Add Support of Types for GivesBuildableArea
This commit is contained in:
committed by
Pavel Penev
parent
4cbc2ee6f3
commit
ca1448c7ba
@@ -286,6 +286,7 @@
|
||||
<Compile Include="Traits\Buildings\Exit.cs" />
|
||||
<Compile Include="Traits\Buildings\FreeActor.cs" />
|
||||
<Compile Include="Traits\Buildings\Gate.cs" />
|
||||
<Compile Include="Traits\Buildings\GivesBuildableArea.cs" />
|
||||
<Compile Include="Traits\Buildings\LineBuild.cs" />
|
||||
<Compile Include="Traits\Buildings\LineBuildNode.cs" />
|
||||
<Compile Include="Traits\Buildings\PrimaryBuilding.cs" />
|
||||
@@ -293,6 +294,7 @@
|
||||
<Compile Include="Traits\Buildings\Refinery.cs" />
|
||||
<Compile Include="Traits\Buildings\RepairableBuilding.cs" />
|
||||
<Compile Include="Traits\Buildings\RepairsUnits.cs" />
|
||||
<Compile Include="Traits\Buildings\RequiresBuildableArea.cs" />
|
||||
<Compile Include="Traits\Buildings\Reservable.cs" />
|
||||
<Compile Include="Traits\Burns.cs" />
|
||||
<Compile Include="Traits\ChangesTerrain.cs" />
|
||||
|
||||
@@ -19,10 +19,6 @@ using OpenRA.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
|
||||
{
|
||||
Empty = '_',
|
||||
@@ -36,10 +32,6 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Where you are allowed to place the building (Water, Clear, ...)")]
|
||||
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, ",
|
||||
"= means part of the footprint but passable, _ means completely empty.")]
|
||||
[FieldLoader.LoadUsing("LoadFootprint")]
|
||||
@@ -175,19 +167,28 @@ namespace OpenRA.Mods.Common.Traits
|
||||
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)
|
||||
{
|
||||
var requiresBuildableArea = world.Map.Rules.Actors[buildingName].TraitInfoOrDefault<RequiresBuildableAreaInfo>();
|
||||
var mapBuildRadius = world.WorldActor.Trait<MapBuildRadius>();
|
||||
if (Adjacent < 0 || p.PlayerActor.Trait<DeveloperMode>().BuildAnywhere)
|
||||
|
||||
if (requiresBuildableArea == null || p.PlayerActor.Trait<DeveloperMode>().BuildAnywhere)
|
||||
return true;
|
||||
|
||||
if (mapBuildRadius.BuildRadiusEnabled && RequiresBaseProvider && FindBaseProvider(world, p, topLeft) == null)
|
||||
return false;
|
||||
|
||||
var adjacent = requiresBuildableArea.Adjacent;
|
||||
var buildingMaxBounds = Dimensions;
|
||||
|
||||
var scanStart = world.Map.Clamp(topLeft - new CVec(Adjacent, Adjacent));
|
||||
var scanEnd = world.Map.Clamp(topLeft + buildingMaxBounds + 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 nearnessCandidates = new List<CPos>();
|
||||
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
|
||||
&& (a.Owner == p || (allyBuildEnabled && a.Owner.Stances[p] == Stance.Ally))
|
||||
&& a.Info.HasTraitInfo<GivesBuildableAreaInfo>());
|
||||
&& ActorGrantsValidArea(a, requiresBuildableArea));
|
||||
|
||||
if (unitsAtPos.Any())
|
||||
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)))
|
||||
nearnessCandidates.Add(pos);
|
||||
}
|
||||
@@ -219,8 +220,8 @@ namespace OpenRA.Mods.Common.Traits
|
||||
var buildingTiles = Tiles(topLeft).ToList();
|
||||
return nearnessCandidates
|
||||
.Any(a => buildingTiles
|
||||
.Any(b => Math.Abs(a.X - b.X) <= Adjacent
|
||||
&& Math.Abs(a.Y - b.Y) <= Adjacent));
|
||||
.Any(b => Math.Abs(a.X - b.X) <= adjacent
|
||||
&& Math.Abs(a.Y - b.Y) <= adjacent));
|
||||
}
|
||||
|
||||
public IReadOnlyDictionary<CPos, SubCell> OccupiedCells(ActorInfo info, CPos topLeft, SubCell subCell = SubCell.Any)
|
||||
|
||||
36
OpenRA.Mods.Common/Traits/Buildings/GivesBuildableArea.cs
Normal file
36
OpenRA.Mods.Common/Traits/Buildings/GivesBuildableArea.cs
Normal 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; } }
|
||||
}
|
||||
}
|
||||
29
OpenRA.Mods.Common/Traits/Buildings/RequiresBuildableArea.cs
Normal file
29
OpenRA.Mods.Common/Traits/Buildings/RequiresBuildableArea.cs
Normal 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 { }
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user