Remove Selectable boolean from Selectable trait

Add work-around for ta/td bridge huts since they need actor Bounds to
be targetable by C4/engineer repair.
This commit is contained in:
reaperrr
2015-06-05 16:36:54 +02:00
parent 2afa3cfa3a
commit c23ee1be2e
15 changed files with 73 additions and 51 deletions

View File

@@ -190,13 +190,9 @@ namespace OpenRA.Graphics
public void DrawRollover(Actor unit) public void DrawRollover(Actor unit)
{ {
var selectable = unit.TraitOrDefault<Selectable>(); if (unit.HasTrait<Selectable>())
if (selectable != null)
{
if (selectable.Info.Selectable)
new SelectionBarsRenderable(unit).Render(this); new SelectionBarsRenderable(unit).Render(this);
} }
}
public void DrawRangeCircle(WPos pos, WRange range, Color c) public void DrawRangeCircle(WPos pos, WRange range, Color c)
{ {

View File

@@ -63,8 +63,7 @@ namespace OpenRA.Orders
if (underCursor != null && (mi.Modifiers.HasModifier(Modifiers.Shift) || !world.Selection.Actors.Any())) if (underCursor != null && (mi.Modifiers.HasModifier(Modifiers.Shift) || !world.Selection.Actors.Any()))
{ {
var selectable = underCursor.TraitOrDefault<Selectable>(); if (underCursor.HasTrait<Selectable>())
if (selectable != null && selectable.Info.Selectable)
useSelect = true; useSelect = true;
} }

View File

@@ -15,9 +15,9 @@ using OpenRA.Graphics;
namespace OpenRA.Traits namespace OpenRA.Traits
{ {
[Desc("This actor is selectable. Defines bounds of selectable area and selection priority.")]
public class SelectableInfo : ITraitInfo public class SelectableInfo : ITraitInfo
{ {
public readonly bool Selectable = true;
public readonly int Priority = 10; public readonly int Priority = 10;
[Desc("Bounds for the selectable area.")] [Desc("Bounds for the selectable area.")]
public readonly int[] Bounds = null; public readonly int[] Bounds = null;

View File

@@ -92,7 +92,7 @@ namespace OpenRA.Widgets
{ {
if (!hasBox && World.Selection.Actors.Any() && !multiClick) if (!hasBox && World.Selection.Actors.Any() && !multiClick)
{ {
if (!(World.ScreenMap.ActorsAt(xy).Where(x => x.HasTrait<Selectable>() && x.Trait<Selectable>().Info.Selectable && if (!(World.ScreenMap.ActorsAt(xy).Where(x => x.HasTrait<Selectable>() &&
(x.Owner.IsAlliedWith(World.RenderPlayer) || !World.FogObscures(x))).Any() && !mi.Modifiers.HasModifier(Modifiers.Ctrl) && (x.Owner.IsAlliedWith(World.RenderPlayer) || !World.FogObscures(x))).Any() && !mi.Modifiers.HasModifier(Modifiers.Ctrl) &&
!mi.Modifiers.HasModifier(Modifiers.Alt) && UnitOrderGenerator.InputOverridesSelection(World, xy, mi))) !mi.Modifiers.HasModifier(Modifiers.Alt) && UnitOrderGenerator.InputOverridesSelection(World, xy, mi)))
{ {
@@ -292,7 +292,7 @@ namespace OpenRA.Widgets
var s = a.TraitOrDefault<Selectable>(); var s = a.TraitOrDefault<Selectable>();
// sc == null means that units, that meet all other criteria, get selected // sc == null means that units, that meet all other criteria, get selected
return s != null && s.Info.Selectable && (selectionClasses == null || selectionClasses.Contains(s.Class)); return s != null && (selectionClasses == null || selectionClasses.Contains(s.Class));
}); });
} }
@@ -303,11 +303,7 @@ namespace OpenRA.Widgets
a = b; a = b;
return world.ScreenMap.ActorsInBox(a, b) return world.ScreenMap.ActorsInBox(a, b)
.Where(x => .Where(x => x.HasTrait<Selectable>() && (x.Owner.IsAlliedWith(world.RenderPlayer) || !world.FogObscures(x)))
{
var s = x.TraitOrDefault<Selectable>();
return s != null && s.Info.Selectable && (x.Owner.IsAlliedWith(world.RenderPlayer) || !world.FogObscures(x));
})
.GroupBy(x => x.GetSelectionPriority()) .GroupBy(x => x.GetSelectionPriority())
.OrderByDescending(g => g.Key) .OrderByDescending(g => g.Key)
.Select(g => g.AsEnumerable()) .Select(g => g.AsEnumerable())

View File

@@ -310,6 +310,7 @@
<Compile Include="Traits\Crushable.cs" /> <Compile Include="Traits\Crushable.cs" />
<Compile Include="Traits\CustomBuildTimeValue.cs" /> <Compile Include="Traits\CustomBuildTimeValue.cs" />
<Compile Include="Traits\CustomSellValue.cs" /> <Compile Include="Traits\CustomSellValue.cs" />
<Compile Include="Traits\CustomSelectionSize.cs" />
<Compile Include="Traits\Demolishable.cs" /> <Compile Include="Traits\Demolishable.cs" />
<Compile Include="Traits\DetectCloaked.cs" /> <Compile Include="Traits\DetectCloaked.cs" />
<Compile Include="Traits\EjectOnDeath.cs" /> <Compile Include="Traits\EjectOnDeath.cs" />

View File

@@ -0,0 +1,36 @@
#region Copyright & License Information
/*
* Copyright 2007-2015 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. For more information,
* see COPYING.
*/
#endregion
using System;
using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
[Desc("Special case trait for invisible, unselectable actors like bridge huts.",
"Gives actor targetable area for special cases like C4 and engineer repair.",
"This trait conflicts with AutoSelectionSize so you cannot use both, and doesn't support custom offsets.")]
public class CustomSelectionSizeInfo : ITraitInfo
{
public readonly int[] CustomBounds = null;
public object Create(ActorInitializer init) { return new CustomSelectionSize(this); }
}
public class CustomSelectionSize : IAutoSelectionSize
{
readonly CustomSelectionSizeInfo info;
public CustomSelectionSize(CustomSelectionSizeInfo info) { this.info = info; }
public int2 SelectionSize(Actor self)
{
return new int2(info.CustomBounds[0], info.CustomBounds[1]);
}
}
}

View File

@@ -1175,6 +1175,28 @@ namespace OpenRA.Mods.Common.UtilityCommands
} }
} }
if (engineVersion < 20150604)
{
if (depth == 1 && node.Value.Nodes.Exists(n => n.Key == "Selectable"))
{
var selectable = node.Value.Nodes.FirstOrDefault(n => n.Key == "Selectable");
if (node.Key == "Selectable" && selectable.Value.Value == "false")
node.Key = "SelectableRemoveMe";
// To cover rare cases where the boolean was 'true'
if (node.Key == "Selectable" && selectable.Value.Value == "true")
node.Value.Nodes.Remove(selectable);
}
if (depth == 0 && node.Value.Nodes.Exists(n => n.Key == "SelectableRemoveMe"))
node.Value.Nodes.RemoveAll(n => n.Key == "SelectableRemoveMe");
Console.WriteLine("The 'Selectable' boolean has been removed from the Selectable trait.");
Console.WriteLine("If you just want to disable an inherited Selectable trait, use -Selectable instead.");
Console.WriteLine("For special cases like bridge huts, which need bounds to be targetable by C4 and engineers,");
Console.WriteLine("give them the CustomSelectionSize trait with CustomBounds.");
Console.WriteLine("See RA and C&C bridge huts for reference.");
}
UpgradeActorRules(engineVersion, ref node.Value.Nodes, node, depth + 1); UpgradeActorRules(engineVersion, ref node.Value.Nodes, node, depth + 1);
} }
} }

View File

@@ -545,8 +545,7 @@ Rules:
ShowOwnerRow: false ShowOwnerRow: false
TRAN: TRAN:
RejectsOrders: RejectsOrders:
Selectable: -Selectable:
Selectable: false
RevealsShroud: RevealsShroud:
Range: 5c0 Range: 5c0

View File

@@ -370,10 +370,8 @@ BRIDGEHUT:
Building: Building:
Footprint: __ __ Footprint: __ __
Dimensions: 2,2 Dimensions: 2,2
Selectable: CustomSelectionSize:
Selectable: false CustomBounds: 48,48
Bounds: 48,48
Priority: 2
BridgeHut: BridgeHut:
TargetableBuilding: TargetableBuilding:
TargetTypes: BridgeHut, C4 TargetTypes: BridgeHut, C4

View File

@@ -672,9 +672,4 @@
Image: crate Image: crate
WithCrateBody: WithCrateBody:
XmasImages: xcratea, xcrateb, xcratec, xcrated XmasImages: xcratea, xcrateb, xcratec, xcrated
Selectable:
Selectable: false
Bounds: 15,15,-1,-1
SelectionDecorations:
VisualBounds: 15,15,-1,-1

View File

@@ -109,12 +109,7 @@ crate:
RenderSprites: RenderSprites:
Palette: effect Palette: effect
WithCrateBody: WithCrateBody:
Selectable:
Selectable: false
Bounds: 15,15,-1,-1
Passenger: Passenger:
SelectionDecorations:
VisualBounds: 15,15,-1,-1
mpspawn: mpspawn:
Immobile: Immobile:

View File

@@ -490,10 +490,8 @@ BRIDGEHUT:
Building: Building:
Footprint: __ __ Footprint: __ __
Dimensions: 2,2 Dimensions: 2,2
Selectable: CustomSelectionSize:
Selectable: false CustomBounds: 48,48
Bounds: 48,48
Priority: 2
BridgeHut: BridgeHut:
TargetableBuilding: TargetableBuilding:
TargetTypes: BridgeHut, C4 TargetTypes: BridgeHut, C4
@@ -502,10 +500,8 @@ BRIDGEHUT.small:
Building: Building:
Footprint: _ Footprint: _
Dimensions: 1,1 Dimensions: 1,1
Selectable: CustomSelectionSize:
Selectable: false CustomBounds: 24,24
Bounds: 24,24
Priority: 2
BridgeHut: BridgeHut:
TargetableBuilding: TargetableBuilding:
TargetTypes: BridgeHut, C4 TargetTypes: BridgeHut, C4

View File

@@ -665,9 +665,6 @@
Image: scrate Image: scrate
WithCrateBody: WithCrateBody:
XmasImages: xcratea, xcrateb, xcratec, xcrated XmasImages: xcratea, xcrateb, xcratec, xcrated
Selectable:
Selectable: false
Bounds: 15,15,-1,-1
Parachutable: Parachutable:
KilledOnImpassableTerrain: false KilledOnImpassableTerrain: false
ParachuteSequence: parach ParachuteSequence: parach

View File

@@ -217,9 +217,6 @@ FLARE:
Tooltip: Tooltip:
Name: Flare Name: Flare
ShowOwnerRow: false ShowOwnerRow: false
Selectable:
Selectable: false
Bounds: 25,25
BodyOrientation: BodyOrientation:
MINE: MINE:

View File

@@ -136,11 +136,6 @@
Palette: terrain Palette: terrain
WithCrateBody: WithCrateBody:
Images: crate Images: crate
Selectable:
Selectable: false
Bounds: 25,25,-1,-1
SelectionDecorations:
VisualBounds: 25,25,-1,-1
^Wall: ^Wall:
AppearsOnRadar: AppearsOnRadar: