diff --git a/OpenRa.Game/Game.cs b/OpenRa.Game/Game.cs index 784d827992..5f51d1f4b4 100644 --- a/OpenRa.Game/Game.cs +++ b/OpenRa.Game/Game.cs @@ -122,14 +122,14 @@ namespace OpenRa.Game viewport.DrawRegions(); } - public static bool IsCellBuildable(int2 a) + public static bool IsCellBuildable(int2 a, UnitMovementType umt) { if (LocalPlayerBuildings[a] != null) return false; a += map.Offset; return map.IsInMap(a.X, a.Y) && - TerrainCosts.Cost(UnitMovementType.Wheel, + TerrainCosts.Cost(umt, terrain.tileSet.GetWalkability(map.MapTiles[a.X, a.Y])) < double.PositiveInfinity; } diff --git a/OpenRa.Game/OpenRa.Game.csproj b/OpenRa.Game/OpenRa.Game.csproj index cb4bef35b9..132ec45043 100644 --- a/OpenRa.Game/OpenRa.Game.csproj +++ b/OpenRa.Game/OpenRa.Game.csproj @@ -96,6 +96,8 @@ + + diff --git a/OpenRa.Game/PlaceBuilding.cs b/OpenRa.Game/PlaceBuilding.cs new file mode 100644 index 0000000000..65ca5511a4 --- /dev/null +++ b/OpenRa.Game/PlaceBuilding.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using OpenRa.Game.GameRules; + +namespace OpenRa.Game +{ + class PlaceBuilding : IOrderGenerator + { + public readonly Player Owner; + public readonly string Name; + + public PlaceBuilding(Player owner, string name) + { + Owner = owner; + Name = name; + } + + public IEnumerable Order(int2 xy) + { + // todo: check that space is free + if (Footprint.Tiles(Name, xy).Any(t => !Game.IsCellBuildable(t, UnitMovementType.Wheel))) + yield break; + + yield return new PlaceBuildingOrder(this, xy); + } + + public void PrepareOverlay(int2 xy) + { + Game.worldRenderer.uiOverlay.SetCurrentOverlay(xy, Name); + } + } +} diff --git a/OpenRa.Game/PlaceBuildingOrder.cs b/OpenRa.Game/PlaceBuildingOrder.cs new file mode 100644 index 0000000000..d45c2c8c7a --- /dev/null +++ b/OpenRa.Game/PlaceBuildingOrder.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace OpenRa.Game +{ + class PlaceBuildingOrder : Order + { + PlaceBuilding building; + int2 xy; + + public PlaceBuildingOrder(PlaceBuilding building, int2 xy) + { + this.building = building; + this.xy = xy; + } + + public override void Apply(bool leftMouseButton) + { + if (leftMouseButton) + { + Game.world.AddFrameEndTask(_ => + { + Log.Write("Player \"{0}\" builds {1}", building.Owner.PlayerName, building.Name); + + //Adjust placement for cursor to be in middle + var footprint = Rules.Footprint.GetFootprint(building.Name); + int maxWidth = 0; + foreach (var row in footprint) + if (row.Length > maxWidth) + maxWidth = row.Length; + + Game.world.Add(new Actor(building.Name, + xy - new int2(maxWidth / 2, footprint.Length / 2), building.Owner)); + + Game.controller.orderGenerator = null; + Game.worldRenderer.uiOverlay.KillOverlay(); + }); + } + else + { + Game.world.AddFrameEndTask(_ => + { + Game.controller.orderGenerator = null; + Game.worldRenderer.uiOverlay.KillOverlay(); + }); + } + } + } +} diff --git a/OpenRa.Game/Sidebar.cs b/OpenRa.Game/Sidebar.cs index d01c83aae5..e984426e82 100644 --- a/OpenRa.Game/Sidebar.cs +++ b/OpenRa.Game/Sidebar.cs @@ -173,70 +173,4 @@ namespace OpenRa.Game } } } - - class PlaceBuilding : IOrderGenerator - { - public readonly Player Owner; - public readonly string Name; - - public PlaceBuilding( Player owner, string name ) - { - Owner = owner; - Name = name; - } - - public IEnumerable Order( int2 xy ) - { - // todo: check that space is free - yield return new PlaceBuildingOrder( this, xy ); - } - - public void PrepareOverlay(int2 xy) - { - Game.worldRenderer.uiOverlay.SetCurrentOverlay(xy, Name); - } - } - - class PlaceBuildingOrder : Order - { - PlaceBuilding building; - int2 xy; - - public PlaceBuildingOrder(PlaceBuilding building, int2 xy) - { - this.building = building; - this.xy = xy; - } - - public override void Apply(bool leftMouseButton) - { - if (leftMouseButton) - { - Game.world.AddFrameEndTask(_ => - { - Log.Write("Player \"{0}\" builds {1}", building.Owner.PlayerName, building.Name); - - //Adjust placement for cursor to be in middle - var footprint = Rules.Footprint.GetFootprint(building.Name); - int maxWidth = 0; - foreach (var row in footprint) - if (row.Length > maxWidth) - maxWidth = row.Length; - - Game.world.Add(new Actor(building.Name, xy - new int2(maxWidth / 2, footprint.Length / 2), building.Owner)); - - Game.controller.orderGenerator = null; - Game.worldRenderer.uiOverlay.KillOverlay(); - }); - } - else - { - Game.world.AddFrameEndTask(_ => - { - Game.controller.orderGenerator = null; - Game.worldRenderer.uiOverlay.KillOverlay(); - }); - } - } - } } diff --git a/OpenRa.Game/TechTree/Item.cs b/OpenRa.Game/TechTree/Item.cs index a76fe37767..ff19fdf5a8 100755 --- a/OpenRa.Game/TechTree/Item.cs +++ b/OpenRa.Game/TechTree/Item.cs @@ -20,7 +20,7 @@ namespace OpenRa.TechTree owner = ParseOwner(unitInfo.Owner, unitInfo.DoubleOwned); techLevel = unitInfo.TechLevel; - Tuple pre = ParsePrerequisites(unitInfo.Prerequisite, tag); + var pre = ParsePrerequisites(unitInfo.Prerequisite, tag); alliedPrerequisites = pre.a; sovietPrerequisites = pre.b; } @@ -41,37 +41,25 @@ namespace OpenRa.TechTree static Tuple ParsePrerequisites(string[] prerequisites, string tag) { - List allied = prerequisites.Select( x => x.ToLowerInvariant() ).ToList(); - List soviet = new List(allied); + var allied = prerequisites.Select( x => x.ToLowerInvariant() ).ToList(); + var soviet = new List(allied); - if (allied.Remove("stek")) - allied.Add("atek"); - - if (soviet.Remove("atek")) - soviet.Add("stek"); - - if (soviet.Remove("tent")) - soviet.Add("barr"); - - if (allied.Remove("barr")) - allied.Add("tent"); + if (allied.Remove("stek")) allied.Add("atek"); + if (soviet.Remove("atek")) soviet.Add("stek"); + if (soviet.Remove("tent")) soviet.Add("barr"); + if (allied.Remove("barr")) allied.Add("tent"); // TODO: rewrite this based on "InfantryTypes" in units.ini if ((tag.Length == 2 && tag[0] == 'e') || tag == "medi" || tag == "thf" || tag == "spy") { - if (!allied.Contains("tent")) - allied.Add("tent"); - if (!soviet.Contains("barr")) - soviet.Add("barr"); + if (!allied.Contains("tent")) allied.Add("tent"); + if (!soviet.Contains("barr")) soviet.Add("barr"); } if (tag == "lst") { - if (!soviet.Contains("spen")) - soviet.Add("spen"); - - if (!allied.Contains("syrd")) - allied.Add("syrd"); + if (!soviet.Contains("spen")) soviet.Add("spen"); + if (!allied.Contains("syrd")) allied.Add("syrd"); } return new Tuple( @@ -91,11 +79,7 @@ namespace OpenRa.TechTree if (racePrerequisites.Length == 0) return true; - List p = new List(racePrerequisites); - foreach (string b in buildings) - p.Remove(b); - - return p.Count == 0; + return racePrerequisites.Except(buildings).Count() == 0; } bool ShouldMakeUnbuildable(IEnumerable buildings, string[] racePrerequisites) @@ -103,20 +87,18 @@ namespace OpenRa.TechTree if (racePrerequisites.Length == 0) return false; - List p = new List(racePrerequisites); - foreach (string b in buildings) - p.Remove(b); - - return p.Count == racePrerequisites.Length; + return racePrerequisites.Except(buildings).Count() == racePrerequisites.Length; } void CheckForBoth(IEnumerable buildings) { - if (canBuild && (ShouldMakeUnbuildable(buildings, alliedPrerequisites) && ShouldMakeUnbuildable(buildings, sovietPrerequisites))) - canBuild = false; + if (CanBuild && (ShouldMakeUnbuildable(buildings, alliedPrerequisites) + && ShouldMakeUnbuildable(buildings, sovietPrerequisites))) + CanBuild = false; - else if (!canBuild && (ShouldMakeBuildable(buildings, alliedPrerequisites) || ShouldMakeBuildable(buildings, sovietPrerequisites))) - canBuild = true; + else if (!CanBuild && (ShouldMakeBuildable(buildings, alliedPrerequisites) + || ShouldMakeBuildable(buildings, sovietPrerequisites))) + CanBuild = true; } public void CheckPrerequisites(IEnumerable buildings, Race currentRace) @@ -127,15 +109,14 @@ namespace OpenRa.TechTree { string[] racePrerequisites = (currentRace == Race.Allies) ? alliedPrerequisites : sovietPrerequisites; - if ((canBuild && ShouldMakeUnbuildable(buildings, racePrerequisites)) || !((owner & currentRace) == currentRace)) - canBuild = false; - else if (!canBuild && ShouldMakeBuildable(buildings, racePrerequisites)) - canBuild = true; + if ((CanBuild && ShouldMakeUnbuildable(buildings, racePrerequisites)) || !((owner & currentRace) == currentRace)) + CanBuild = false; + else if (!CanBuild && ShouldMakeBuildable(buildings, racePrerequisites)) + CanBuild = true; } } - bool canBuild; - public bool CanBuild { get { return canBuild; } } + public bool CanBuild { get; private set; } public string Tooltip { get { return string.Format("{0} ({1})\n{2}", friendlyName, tag, owner); } } } } diff --git a/OpenRa.Game/TechTree/TechTree.cs b/OpenRa.Game/TechTree/TechTree.cs index d83e852650..b4eb5114be 100644 --- a/OpenRa.Game/TechTree/TechTree.cs +++ b/OpenRa.Game/TechTree/TechTree.cs @@ -32,20 +32,6 @@ namespace OpenRa.TechTree CheckAll(); } - IEnumerable> Lines(string filename, bool param) - { - Regex pattern = new Regex(@"^(\w+),([\w ]+),(\w+)$"); - foreach (string s in File.ReadAllLines("../../../../" + filename)) - { - Match m = pattern.Match(s); - if (m == null || !m.Success) - continue; - - yield return new Tuple( - m.Groups[1].Value, m.Groups[2].Value, param); - } - } - void LoadRules() { var allBuildings = Rules.AllRules.GetSection( "BuildingTypes" ).Select( x => x.Key.ToLowerInvariant() ).ToList(); @@ -63,12 +49,9 @@ namespace OpenRa.TechTree built.Add(key); CheckAll(); return true; - } - - public bool Build(string key) - { - return Build(key, false); - } + } + + public bool Build(string key) { return Build(key, false); } public bool Unbuild(string key) { @@ -86,18 +69,9 @@ namespace OpenRa.TechTree unit.CheckPrerequisites(built, currentRace); BuildableItemsChanged(); - } - - public IEnumerable BuildableItems - { - get - { - foreach (Item b in objects.Values) - if (b.CanBuild) - yield return b; - } - } - + } + + public IEnumerable BuildableItems { get { return objects.Values.Where(b => b.CanBuild); } } public event Action BuildableItemsChanged = () => { }; } } diff --git a/OpenRa.Game/UiOverlay.cs b/OpenRa.Game/UiOverlay.cs index 9e4929bbeb..ff626b9124 100644 --- a/OpenRa.Game/UiOverlay.cs +++ b/OpenRa.Game/UiOverlay.cs @@ -36,7 +36,8 @@ namespace OpenRa.Game return; foreach (var t in Footprint.Tiles(name,position)) - spriteRenderer.DrawSprite(Game.IsCellBuildable(t) ? buildOk : buildBlocked, Game.CellSize * t, 0); + spriteRenderer.DrawSprite(Game.IsCellBuildable(t, UnitMovementType.Wheel) + ? buildOk : buildBlocked, Game.CellSize * t, 0); spriteRenderer.Flush(); }