cleaning techtree & sidebar; building placement is mostly fixed

This commit is contained in:
Chris Forbes
2009-10-20 22:35:05 +13:00
parent b3aa4bf60b
commit 6c0ced3e9a
8 changed files with 121 additions and 144 deletions

View File

@@ -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;
}

View File

@@ -96,6 +96,8 @@
<Compile Include="Graphics\WorldRenderer.cs" />
<Compile Include="BuildingInfluenceMap.cs" />
<Compile Include="IOrderGenerator.cs" />
<Compile Include="PlaceBuilding.cs" />
<Compile Include="PlaceBuildingOrder.cs" />
<Compile Include="TechTree\Item.cs" />
<Compile Include="Network\Packet.cs" />
<Compile Include="Player.cs" />

View File

@@ -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> 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);
}
}
}

View File

@@ -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();
});
}
}
}
}

View File

@@ -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> 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();
});
}
}
}
}

View File

@@ -20,7 +20,7 @@ namespace OpenRa.TechTree
owner = ParseOwner(unitInfo.Owner, unitInfo.DoubleOwned);
techLevel = unitInfo.TechLevel;
Tuple<string[], string[]> 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<string[],string[]> ParsePrerequisites(string[] prerequisites, string tag)
{
List<string> allied = prerequisites.Select( x => x.ToLowerInvariant() ).ToList();
List<string> soviet = new List<string>(allied);
var allied = prerequisites.Select( x => x.ToLowerInvariant() ).ToList();
var soviet = new List<string>(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<string[], string[]>(
@@ -91,11 +79,7 @@ namespace OpenRa.TechTree
if (racePrerequisites.Length == 0)
return true;
List<string> p = new List<string>(racePrerequisites);
foreach (string b in buildings)
p.Remove(b);
return p.Count == 0;
return racePrerequisites.Except(buildings).Count() == 0;
}
bool ShouldMakeUnbuildable(IEnumerable<string> buildings, string[] racePrerequisites)
@@ -103,20 +87,18 @@ namespace OpenRa.TechTree
if (racePrerequisites.Length == 0)
return false;
List<string> p = new List<string>(racePrerequisites);
foreach (string b in buildings)
p.Remove(b);
return p.Count == racePrerequisites.Length;
return racePrerequisites.Except(buildings).Count() == racePrerequisites.Length;
}
void CheckForBoth(IEnumerable<string> 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<string> 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); } }
}
}

View File

@@ -32,20 +32,6 @@ namespace OpenRa.TechTree
CheckAll();
}
IEnumerable<Tuple<string, string, bool>> 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<string, string, bool>(
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<Item> BuildableItems
{
get
{
foreach (Item b in objects.Values)
if (b.CanBuild)
yield return b;
}
}
}
public IEnumerable<Item> BuildableItems { get { return objects.Values.Where(b => b.CanBuild); } }
public event Action BuildableItemsChanged = () => { };
}
}

View File

@@ -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();
}