Add Support of Types for GivesBuildableArea

This commit is contained in:
Mustafa Alperen Seki
2017-07-13 17:04:09 +02:00
committed by Pavel Penev
parent 4cbc2ee6f3
commit ca1448c7ba
16 changed files with 157 additions and 37 deletions

View File

@@ -286,6 +286,7 @@
<Compile Include="Traits\Buildings\Exit.cs" /> <Compile Include="Traits\Buildings\Exit.cs" />
<Compile Include="Traits\Buildings\FreeActor.cs" /> <Compile Include="Traits\Buildings\FreeActor.cs" />
<Compile Include="Traits\Buildings\Gate.cs" /> <Compile Include="Traits\Buildings\Gate.cs" />
<Compile Include="Traits\Buildings\GivesBuildableArea.cs" />
<Compile Include="Traits\Buildings\LineBuild.cs" /> <Compile Include="Traits\Buildings\LineBuild.cs" />
<Compile Include="Traits\Buildings\LineBuildNode.cs" /> <Compile Include="Traits\Buildings\LineBuildNode.cs" />
<Compile Include="Traits\Buildings\PrimaryBuilding.cs" /> <Compile Include="Traits\Buildings\PrimaryBuilding.cs" />
@@ -293,6 +294,7 @@
<Compile Include="Traits\Buildings\Refinery.cs" /> <Compile Include="Traits\Buildings\Refinery.cs" />
<Compile Include="Traits\Buildings\RepairableBuilding.cs" /> <Compile Include="Traits\Buildings\RepairableBuilding.cs" />
<Compile Include="Traits\Buildings\RepairsUnits.cs" /> <Compile Include="Traits\Buildings\RepairsUnits.cs" />
<Compile Include="Traits\Buildings\RequiresBuildableArea.cs" />
<Compile Include="Traits\Buildings\Reservable.cs" /> <Compile Include="Traits\Buildings\Reservable.cs" />
<Compile Include="Traits\Burns.cs" /> <Compile Include="Traits\Burns.cs" />
<Compile Include="Traits\ChangesTerrain.cs" /> <Compile Include="Traits\ChangesTerrain.cs" />

View File

@@ -19,10 +19,6 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits namespace OpenRA.Mods.Common.Traits
{ {
[Desc("Remove this trait to limit base-walking by cheap or defensive buildings.")]
public class GivesBuildableAreaInfo : TraitInfo<GivesBuildableArea> { }
public class GivesBuildableArea { }
public enum FootprintCellType public enum FootprintCellType
{ {
Empty = '_', Empty = '_',
@@ -36,10 +32,6 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Where you are allowed to place the building (Water, Clear, ...)")] [Desc("Where you are allowed to place the building (Water, Clear, ...)")]
public readonly HashSet<string> TerrainTypes = new HashSet<string>(); public readonly HashSet<string> TerrainTypes = new HashSet<string>();
[Desc("The range to the next building it can be constructed. Set it higher for walls.",
"Set to '-1' to disable adjacency checks.")]
public readonly int Adjacent = 2;
[Desc("x means cell is blocked, capital X means blocked but not counting as targetable, ", [Desc("x means cell is blocked, capital X means blocked but not counting as targetable, ",
"= means part of the footprint but passable, _ means completely empty.")] "= means part of the footprint but passable, _ means completely empty.")]
[FieldLoader.LoadUsing("LoadFootprint")] [FieldLoader.LoadUsing("LoadFootprint")]
@@ -175,19 +167,28 @@ namespace OpenRA.Mods.Common.Traits
return null; return null;
} }
bool ActorGrantsValidArea(Actor a, RequiresBuildableAreaInfo rba)
{
return rba.AreaTypes.Overlaps(a.TraitsImplementing<GivesBuildableArea>()
.SelectMany(gba => gba.AreaTypes));
}
public virtual bool IsCloseEnoughToBase(World world, Player p, string buildingName, CPos topLeft) public virtual bool IsCloseEnoughToBase(World world, Player p, string buildingName, CPos topLeft)
{ {
var requiresBuildableArea = world.Map.Rules.Actors[buildingName].TraitInfoOrDefault<RequiresBuildableAreaInfo>();
var mapBuildRadius = world.WorldActor.Trait<MapBuildRadius>(); var mapBuildRadius = world.WorldActor.Trait<MapBuildRadius>();
if (Adjacent < 0 || p.PlayerActor.Trait<DeveloperMode>().BuildAnywhere)
if (requiresBuildableArea == null || p.PlayerActor.Trait<DeveloperMode>().BuildAnywhere)
return true; return true;
if (mapBuildRadius.BuildRadiusEnabled && RequiresBaseProvider && FindBaseProvider(world, p, topLeft) == null) if (mapBuildRadius.BuildRadiusEnabled && RequiresBaseProvider && FindBaseProvider(world, p, topLeft) == null)
return false; return false;
var adjacent = requiresBuildableArea.Adjacent;
var buildingMaxBounds = Dimensions; var buildingMaxBounds = Dimensions;
var scanStart = world.Map.Clamp(topLeft - new CVec(Adjacent, Adjacent)); var scanStart = world.Map.Clamp(topLeft - new CVec(adjacent, adjacent));
var scanEnd = world.Map.Clamp(topLeft + buildingMaxBounds + new CVec(Adjacent, Adjacent)); var scanEnd = world.Map.Clamp(topLeft + buildingMaxBounds + new CVec(adjacent, adjacent));
var nearnessCandidates = new List<CPos>(); var nearnessCandidates = new List<CPos>();
var bi = world.WorldActor.Trait<BuildingInfluence>(); var bi = world.WorldActor.Trait<BuildingInfluence>();
@@ -205,12 +206,12 @@ namespace OpenRA.Mods.Common.Traits
{ {
var unitsAtPos = world.ActorMap.GetActorsAt(pos).Where(a => a.IsInWorld var unitsAtPos = world.ActorMap.GetActorsAt(pos).Where(a => a.IsInWorld
&& (a.Owner == p || (allyBuildEnabled && a.Owner.Stances[p] == Stance.Ally)) && (a.Owner == p || (allyBuildEnabled && a.Owner.Stances[p] == Stance.Ally))
&& a.Info.HasTraitInfo<GivesBuildableAreaInfo>()); && ActorGrantsValidArea(a, requiresBuildableArea));
if (unitsAtPos.Any()) if (unitsAtPos.Any())
nearnessCandidates.Add(pos); nearnessCandidates.Add(pos);
} }
else if (buildingAtPos.IsInWorld && buildingAtPos.Info.HasTraitInfo<GivesBuildableAreaInfo>() else if (buildingAtPos.IsInWorld && ActorGrantsValidArea(buildingAtPos, requiresBuildableArea)
&& (buildingAtPos.Owner == p || (allyBuildEnabled && buildingAtPos.Owner.Stances[p] == Stance.Ally))) && (buildingAtPos.Owner == p || (allyBuildEnabled && buildingAtPos.Owner.Stances[p] == Stance.Ally)))
nearnessCandidates.Add(pos); nearnessCandidates.Add(pos);
} }
@@ -219,8 +220,8 @@ namespace OpenRA.Mods.Common.Traits
var buildingTiles = Tiles(topLeft).ToList(); var buildingTiles = Tiles(topLeft).ToList();
return nearnessCandidates return nearnessCandidates
.Any(a => buildingTiles .Any(a => buildingTiles
.Any(b => Math.Abs(a.X - b.X) <= Adjacent .Any(b => Math.Abs(a.X - b.X) <= adjacent
&& Math.Abs(a.Y - b.Y) <= Adjacent)); && Math.Abs(a.Y - b.Y) <= adjacent));
} }
public IReadOnlyDictionary<CPos, SubCell> OccupiedCells(ActorInfo info, CPos topLeft, SubCell subCell = SubCell.Any) public IReadOnlyDictionary<CPos, SubCell> OccupiedCells(ActorInfo info, CPos topLeft, SubCell subCell = SubCell.Any)

View File

@@ -0,0 +1,36 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 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.Collections.Generic;
using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
[Desc("This actor allows placement of other actors with 'RequiresBuildableArea' trait around it.")]
public class GivesBuildableAreaInfo : ConditionalTraitInfo
{
[FieldLoader.Require]
[Desc("Types of buildable area this actor gives.")]
public readonly HashSet<string> AreaTypes = new HashSet<string>();
public override object Create(ActorInitializer init) { return new GivesBuildableArea(this); }
}
public class GivesBuildableArea : ConditionalTrait<GivesBuildableAreaInfo>
{
public GivesBuildableArea(GivesBuildableAreaInfo info)
: base(info) { }
readonly HashSet<string> noAreaTypes = new HashSet<string>();
public HashSet<string> AreaTypes { get { return !IsTraitDisabled ? Info.AreaTypes : noAreaTypes; } }
}
}

View File

@@ -0,0 +1,29 @@
#region Copyright & License Information
/*
* Copyright 2007-2017 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.Collections.Generic;
using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
[Desc("This actor requires another actor with 'GivesBuildableArea' trait around to be placed.")]
public class RequiresBuildableAreaInfo : TraitInfo<RequiresBuildableArea>, Requires<BuildingInfo>
{
[FieldLoader.Require]
[Desc("Types of buildable are this actor requires.")]
public readonly HashSet<string> AreaTypes = new HashSet<string>();
[Desc("Maximum range from the actor with 'GivesBuildableArea' this can be placed at.")]
public readonly int Adjacent = 2;
}
public class RequiresBuildableArea { }
}

View File

@@ -1210,6 +1210,30 @@ namespace OpenRA.Mods.Common.UtilityCommands
} }
} }
if (engineVersion < 20171120)
{
// AreaTypes support is added to GivesBuildableArea and it is required.
var givesBuildableArea = node.Value.Nodes.FirstOrDefault(n => n.Key == "GivesBuildableArea");
if (givesBuildableArea != null)
givesBuildableArea.Value.Nodes.Add(new MiniYamlNode("AreaTypes", "building"));
// RequiresBuildableArea trait is added and Building.Adjacent is moved there.
var building = node.Value.Nodes.FirstOrDefault(n => n.Key == "Building");
if (building != null)
{
var adjacent = building.Value.Nodes.FirstOrDefault(n => n.Key == "Adjacent");
var areaTypes = new MiniYamlNode("AreaTypes", "building");
var requiresBuildableArea = new MiniYamlNode("RequiresBuildableArea", "");
requiresBuildableArea.Value.Nodes.Add(areaTypes);
if (adjacent != null)
requiresBuildableArea.Value.Nodes.Add(adjacent);
node.Value.Nodes.Add(requiresBuildableArea);
building.Value.Nodes.Remove(adjacent);
}
}
UpgradeActorRules(modData, engineVersion, ref node.Value.Nodes, node, depth + 1); UpgradeActorRules(modData, engineVersion, ref node.Value.Nodes, node, depth + 1);
} }

View File

@@ -691,10 +691,12 @@
^BaseBuilding: ^BaseBuilding:
Inherits: ^Building Inherits: ^Building
Building: Building:
Adjacent: 4
RequiresBaseProvider: true RequiresBaseProvider: true
BuildSounds: constru2.aud, hvydoor1.aud BuildSounds: constru2.aud, hvydoor1.aud
TerrainTypes: Clear,Road TerrainTypes: Clear,Road
RequiresBuildableArea:
AreaTypes: building
Adjacent: 4
MustBeDestroyed: MustBeDestroyed:
RequiredForShortGame: true RequiredForShortGame: true
RepairableBuilding: RepairableBuilding:
@@ -705,6 +707,7 @@
DeathSequence: dead DeathSequence: dead
UseDeathTypeSuffix: false UseDeathTypeSuffix: false
GivesBuildableArea: GivesBuildableArea:
AreaTypes: building
EmitInfantryOnSell: EmitInfantryOnSell:
ActorTypes: e6,e1,e1,e1 ActorTypes: e6,e1,e1,e1
EngineerRepairable: EngineerRepairable:
@@ -796,8 +799,10 @@
Dimensions: 1,1 Dimensions: 1,1
Footprint: x Footprint: x
BuildSounds: hvydoor1.aud BuildSounds: hvydoor1.aud
Adjacent: 7
TerrainTypes: Clear,Road TerrainTypes: Clear,Road
RequiresBuildableArea:
AreaTypes: building
Adjacent: 4
Targetable: Targetable:
TargetTypes: Ground, Wall TargetTypes: Ground, Wall
Crushable: Crushable:

View File

@@ -395,8 +395,11 @@
Footprint: x Footprint: x
TerrainTypes: Rock, Concrete TerrainTypes: Rock, Concrete
BuildSounds: BUILD1.WAV BuildSounds: BUILD1.WAV
RequiresBuildableArea:
AreaTypes: building
Adjacent: 3 Adjacent: 3
GivesBuildableArea: GivesBuildableArea:
AreaTypes: building
Capturable: Capturable:
CaptureThreshold: 100 CaptureThreshold: 100
SoundOnDamageTransition: SoundOnDamageTransition:

View File

@@ -1,10 +1,12 @@
^concrete: ^concrete:
AlwaysVisible: AlwaysVisible:
Building: Building:
Adjacent: 4
TerrainTypes: Rock TerrainTypes: Rock
BuildSounds: CHUNG.WAV BuildSounds: CHUNG.WAV
AllowInvalidPlacement: true AllowInvalidPlacement: true
RequiresBuildableArea:
AreaTypes: building
Adjacent: 4
LaysTerrain: LaysTerrain:
Template: 88 Template: 88
TerrainTypes: Rock TerrainTypes: Rock
@@ -55,7 +57,6 @@ construction_yard:
Building: Building:
Footprint: xxx xxx === Footprint: xxx xxx ===
Dimensions: 3,3 Dimensions: 3,3
Adjacent: 4
LocalCenterOffset: 0,-512,0 LocalCenterOffset: 0,-512,0
LaysTerrain: LaysTerrain:
TerrainTypes: Rock TerrainTypes: Rock
@@ -324,7 +325,7 @@ silo:
Cost: 120 Cost: 120
Tooltip: Tooltip:
Name: Silo Name: Silo
Building: RequiresBuildableArea:
Adjacent: 4 Adjacent: 4
-GivesBuildableArea: -GivesBuildableArea:
Health: Health:
@@ -677,8 +678,10 @@ wall:
AppearsOnRadar: AppearsOnRadar:
Building: Building:
BuildSounds: CHUNG.WAV BuildSounds: CHUNG.WAV
Adjacent: 7
TerrainTypes: Rock, Concrete TerrainTypes: Rock, Concrete
RequiresBuildableArea:
AreaTypes: building
Adjacent: 7
Health: Health:
HP: 2000 HP: 2000
Armor: Armor:
@@ -729,8 +732,9 @@ medium_gun_turret:
Tooltip: Tooltip:
Name: Gun Turret Name: Gun Turret
Building: Building:
Adjacent: 4
BuildSounds: CHUNG.WAV BuildSounds: CHUNG.WAV
RequiresBuildableArea:
Adjacent: 4
Sellable: Sellable:
SellSounds: CHUNG.WAV SellSounds: CHUNG.WAV
Selectable: Selectable:
@@ -775,8 +779,9 @@ large_gun_turret:
Tooltip: Tooltip:
Name: Rocket Turret Name: Rocket Turret
Building: Building:
Adjacent: 4
BuildSounds: CHUNG.WAV BuildSounds: CHUNG.WAV
RequiresBuildableArea:
Adjacent: 4
Sellable: Sellable:
SellSounds: CHUNG.WAV SellSounds: CHUNG.WAV
Selectable: Selectable:

View File

@@ -141,7 +141,6 @@ MINVV:
HiddenUnderFog: HiddenUnderFog:
Building: Building:
TerrainTypes: Clear,Road TerrainTypes: Clear,Road
Adjacent: -1
Buildable: Buildable:
Queue: Building Queue: Building
BuildPaletteOrder: 10 BuildPaletteOrder: 10

View File

@@ -175,6 +175,7 @@ FTUR:
Power: Power:
Amount: 0 Amount: 0
GivesBuildableArea: GivesBuildableArea:
AreaTypes: building
PBOX: PBOX:
Buildable: Buildable:
@@ -188,6 +189,7 @@ PBOX:
Power: Power:
Amount: 0 Amount: 0
GivesBuildableArea: GivesBuildableArea:
AreaTypes: building
DOG: DOG:
Buildable: Buildable:

View File

@@ -85,6 +85,7 @@ FCOM:
CaptureCompleteTime: 30 CaptureCompleteTime: 30
ExternalCapturableBar: ExternalCapturableBar:
GivesBuildableArea: GivesBuildableArea:
AreaTypes: building
BaseProvider: BaseProvider:
Range: 8c0 Range: 8c0
EngineerRepairable: EngineerRepairable:

View File

@@ -587,6 +587,8 @@
Footprint: x Footprint: x
TerrainTypes: Clear,Road TerrainTypes: Clear,Road
RequiresBaseProvider: True RequiresBaseProvider: True
RequiresBuildableArea:
AreaTypes: building
SoundOnDamageTransition: SoundOnDamageTransition:
DamagedSounds: kaboom1.aud DamagedSounds: kaboom1.aud
DestroyedSounds: kaboom22.aud DestroyedSounds: kaboom22.aud
@@ -616,6 +618,7 @@
Huntable: Huntable:
UpdatesPlayerStatistics: UpdatesPlayerStatistics:
GivesBuildableArea: GivesBuildableArea:
AreaTypes: building
RepairableBuilding: RepairableBuilding:
PlayerExperience: 25 PlayerExperience: 25
EngineerRepairable: EngineerRepairable:
@@ -662,8 +665,10 @@
Dimensions: 1,1 Dimensions: 1,1
Footprint: x Footprint: x
BuildSounds: placbldg.aud BuildSounds: placbldg.aud
Adjacent: 7
TerrainTypes: Clear,Road TerrainTypes: Clear,Road
RequiresBuildableArea:
AreaTypes: building
Adjacent: 7
SoundOnDamageTransition: SoundOnDamageTransition:
DamagedSounds: sandbag2.aud DamagedSounds: sandbag2.aud
DestroyedSounds: sandbag2.aud DestroyedSounds: sandbag2.aud
@@ -706,12 +711,14 @@
Tooltip: Tooltip:
Name: Gate Name: Gate
Gate: Gate:
Adjacent: 4
BlocksProjectilesHeight: 0 BlocksProjectilesHeight: 0
BuildSounds: place2.aud BuildSounds: place2.aud
OpeningSound: cashturn.aud OpeningSound: cashturn.aud
ClosingSound: cashturn.aud ClosingSound: cashturn.aud
TerrainTypes: Clear, Road TerrainTypes: Clear, Road
RequiresBuildableArea:
AreaTypes: building
Adjacent: 4
EditorTilesetFilter: EditorTilesetFilter:
Categories: Wall Categories: Wall

View File

@@ -49,8 +49,9 @@ SYRF:
Building: Building:
Footprint: XXX xxx XXX Footprint: XXX xxx XXX
Dimensions: 3,3 Dimensions: 3,3
Adjacent: 8
TerrainTypes: Water TerrainTypes: Water
RequiresBuildableArea:
Adjacent: 8
RenderSprites: RenderSprites:
Image: SYRD Image: SYRD
Valued: Valued:
@@ -91,8 +92,9 @@ SPEF:
Building: Building:
Footprint: XXX xxx XXX Footprint: XXX xxx XXX
Dimensions: 3,3 Dimensions: 3,3
Adjacent: 8
TerrainTypes: Water TerrainTypes: Water
RequiresBuildableArea:
Adjacent: 8
RenderSprites: RenderSprites:
Image: SPEN Image: SPEN
Valued: Valued:

View File

@@ -125,8 +125,10 @@ SPEN:
Building: Building:
Footprint: XXX xxx XXX Footprint: XXX xxx XXX
Dimensions: 3,3 Dimensions: 3,3
Adjacent: 8
TerrainTypes: Water TerrainTypes: Water
RequiresBuildableArea:
AreaTypes: building
Adjacent: 8
-GivesBuildableArea: -GivesBuildableArea:
Health: Health:
HP: 1000 HP: 1000
@@ -227,8 +229,9 @@ SYRD:
Building: Building:
Footprint: XXX xxx XXX Footprint: XXX xxx XXX
Dimensions: 3,3 Dimensions: 3,3
Adjacent: 8
TerrainTypes: Water TerrainTypes: Water
RequiresBuildableArea:
Adjacent: 8
-GivesBuildableArea: -GivesBuildableArea:
Health: Health:
HP: 1000 HP: 1000
@@ -1154,8 +1157,6 @@ SILO:
Cost: 150 Cost: 150
Tooltip: Tooltip:
Name: Silo Name: Silo
Building:
Adjacent: 2
-GivesBuildableArea: -GivesBuildableArea:
Health: Health:
HP: 300 HP: 300
@@ -1603,8 +1604,6 @@ KENN:
Cost: 100 Cost: 100
Tooltip: Tooltip:
Name: Kennel Name: Kennel
Building:
Adjacent: 2
-GivesBuildableArea: -GivesBuildableArea:
Health: Health:
HP: 300 HP: 300

View File

@@ -309,6 +309,8 @@
Footprint: x Footprint: x
BuildSounds: place2.aud BuildSounds: place2.aud
TerrainTypes: Clear, Road, DirtRoad, Rough TerrainTypes: Clear, Road, DirtRoad, Rough
RequiresBuildableArea:
AreaTypes: building
Adjacent: 4 Adjacent: 4
FrozenUnderFog: FrozenUnderFog:
SoundOnDamageTransition: SoundOnDamageTransition:
@@ -340,6 +342,7 @@
Inherits@1: ^BasicBuilding Inherits@1: ^BasicBuilding
Inherits@2: ^EmpDisable Inherits@2: ^EmpDisable
GivesBuildableArea: GivesBuildableArea:
AreaTypes: building
Capturable: Capturable:
RepairableBuilding: RepairableBuilding:
IndicatorPalette: mouse IndicatorPalette: mouse
@@ -439,8 +442,10 @@
Dimensions: 1,1 Dimensions: 1,1
Footprint: x Footprint: x
BuildSounds: place2.aud BuildSounds: place2.aud
Adjacent: 7
TerrainTypes: Clear, Rough, Road, DirtRoad, Green, Sand, Pavement TerrainTypes: Clear, Rough, Road, DirtRoad, Green, Sand, Pavement
RequiresBuildableArea:
AreaTypes: building
Adjacent: 7
SoundOnDamageTransition: SoundOnDamageTransition:
DamagedSounds: expnew01.aud DamagedSounds: expnew01.aud
DestroyedSounds: crmble2.aud DestroyedSounds: crmble2.aud
@@ -1134,7 +1139,6 @@
OpenSequence: open OpenSequence: open
Tooltip: Tooltip:
Gate: Gate:
Adjacent: 4
BuildSounds: place2.aud BuildSounds: place2.aud
OpeningSound: gateup1.aud OpeningSound: gateup1.aud
ClosingSound: gatedwn1.aud ClosingSound: gatedwn1.aud

View File

@@ -348,9 +348,10 @@ NATMPL:
Tooltip: Tooltip:
Name: Temple of Nod Name: Temple of Nod
Building: Building:
Adjacent: 3
Footprint: xxxx xxxx xxxX Footprint: xxxx xxxx xxxX
Dimensions: 4,3 Dimensions: 4,3
RequiresBuildableArea:
Adjacent: 3
Selectable: Selectable:
Bounds: 134, 120, 12, -12 Bounds: 134, 120, 12, -12
Health: Health: