Moved footprint info onto its building.
This commit is contained in:
@@ -20,14 +20,14 @@ namespace OpenRa.Game
|
||||
|
||||
void AddInfluence(Actor a)
|
||||
{
|
||||
foreach (var t in Footprint.UnpathableTiles(a.unitInfo.Name, a.Location))
|
||||
foreach (var t in Footprint.UnpathableTiles(a.unitInfo, a.Location))
|
||||
if (IsValid(t))
|
||||
influence[t.X, t.Y] = a;
|
||||
}
|
||||
|
||||
void RemoveInfluence(Actor a)
|
||||
{
|
||||
foreach (var t in Footprint.UnpathableTiles(a.unitInfo.Name, a.Location))
|
||||
foreach (var t in Footprint.UnpathableTiles(a.unitInfo, a.Location))
|
||||
if (IsValid(t))
|
||||
influence[t.X, t.Y] = null;
|
||||
}
|
||||
|
||||
@@ -39,10 +39,15 @@ namespace OpenRa.Game.GameRules
|
||||
var parts = x.Split( new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries );
|
||||
|
||||
var ret = Array.CreateInstance( fieldType.GetElementType(), parts.Length );
|
||||
for (int i = 0; i < parts.Length; i++)
|
||||
for( int i = 0 ; i < parts.Length ; i++ )
|
||||
ret.SetValue( GetValue( fieldType.GetElementType(), parts[ i ].Trim() ), i );
|
||||
return ret;
|
||||
}
|
||||
else if( fieldType == typeof( int2 ) )
|
||||
{
|
||||
var parts = x.Split( new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries );
|
||||
return new int2( int.Parse( parts[ 0 ] ), int.Parse( parts[ 1 ] ) );
|
||||
}
|
||||
else
|
||||
throw new InvalidOperationException( "FieldLoader: don't know how to load field of type " + fieldType.ToString() );
|
||||
}
|
||||
|
||||
@@ -7,74 +7,57 @@ using OpenRa.Game.Graphics;
|
||||
|
||||
namespace OpenRa.Game.GameRules
|
||||
{
|
||||
class Footprint
|
||||
static class Footprint
|
||||
{
|
||||
Dictionary<string, string[]> buildingFootprints;
|
||||
|
||||
public string[] GetFootprint(string name)
|
||||
public static IEnumerable<int2> Tiles( UnitInfo unitInfo, int2 position )
|
||||
{
|
||||
string[] val;
|
||||
if (!buildingFootprints.TryGetValue(name, out val))
|
||||
buildingFootprints.TryGetValue("*", out val);
|
||||
return val;
|
||||
}
|
||||
var buildingInfo = unitInfo as UnitInfo.BuildingInfo;
|
||||
var dim = buildingInfo.Dimensions;
|
||||
|
||||
public Footprint(Stream s)
|
||||
{
|
||||
var lines = Util.ReadAllLines(s).Where(a => !a.StartsWith("#"));
|
||||
|
||||
Func<string,string[]> words =
|
||||
b => b.Split( new[] { ' ', '\t' },
|
||||
StringSplitOptions.RemoveEmptyEntries );
|
||||
|
||||
var buildings = lines
|
||||
.Select(a => a.Split(':'))
|
||||
.SelectMany(a => words(a[1])
|
||||
.Select( b => new { Name=b, Pat=words(a[0]) } ));
|
||||
|
||||
buildingFootprints = buildings
|
||||
.ToDictionary(a => a.Name, a => a.Pat);
|
||||
}
|
||||
|
||||
public static IEnumerable<int2> Tiles(string name, int2 position)
|
||||
{
|
||||
var footprint = Rules.Footprint.GetFootprint(name);
|
||||
var j = 0;
|
||||
|
||||
int maxWidth = 0;
|
||||
foreach (var row in footprint)
|
||||
if (row.Length > maxWidth)
|
||||
maxWidth = row.Length;
|
||||
|
||||
foreach (var row in footprint)
|
||||
var footprint = buildingInfo.Footprint.ToCharArray().Where( x => !char.IsWhiteSpace( x ) );
|
||||
if( buildingInfo.Bib )
|
||||
{
|
||||
var i = 0;
|
||||
foreach (var c in row)
|
||||
dim.Y += 1;
|
||||
footprint = footprint.Concat( new char[ dim.X ] );
|
||||
}
|
||||
foreach( var tile in TilesWhere( unitInfo.Name, dim, footprint.ToArray(), a => a != '_' ) )
|
||||
yield return tile + position - AdjustForBuildingSize( buildingInfo );
|
||||
}
|
||||
|
||||
public static IEnumerable<int2> UnpathableTiles( UnitInfo unitInfo, int2 position )
|
||||
{
|
||||
var buildingInfo = unitInfo as UnitInfo.BuildingInfo;
|
||||
|
||||
var footprint = buildingInfo.Footprint.ToCharArray().Where( x => !char.IsWhiteSpace( x ) ).ToArray();
|
||||
foreach( var tile in TilesWhere( unitInfo.Name, buildingInfo.Dimensions, footprint, a => a == 'x' ) )
|
||||
yield return tile + position;
|
||||
}
|
||||
|
||||
static IEnumerable<int2> TilesWhere( string name, int2 dim, char[] footprint, Func<char, bool> cond )
|
||||
{
|
||||
if( footprint.Length != dim.X * dim.Y )
|
||||
throw new InvalidOperationException( "Invalid footprint for " + name );
|
||||
int index = 0;
|
||||
for( int y = 0 ; y < dim.Y ; y++ )
|
||||
{
|
||||
for( int x = 0 ; x < dim.X ; x++ )
|
||||
{
|
||||
if (c != '_')
|
||||
yield return position + new int2(i, j) - new int2(maxWidth / 2, footprint.Length / 2);
|
||||
++i;
|
||||
if( cond( footprint[ index ] ) )
|
||||
yield return new int2( x, y );
|
||||
++index;
|
||||
}
|
||||
++j;
|
||||
}
|
||||
}
|
||||
|
||||
public static IEnumerable<int2> UnpathableTiles( string name, int2 position )
|
||||
public static int2 AdjustForBuildingSize( string name )
|
||||
{
|
||||
var footprint = Rules.Footprint.GetFootprint( name );
|
||||
var j = 0;
|
||||
return AdjustForBuildingSize( Rules.UnitInfo[ name ] as UnitInfo.BuildingInfo );
|
||||
}
|
||||
|
||||
foreach( var row in footprint )
|
||||
{
|
||||
var i = 0;
|
||||
foreach( var c in row )
|
||||
{
|
||||
if( c == 'x' )
|
||||
yield return position + new int2( i, j );
|
||||
++i;
|
||||
}
|
||||
++j;
|
||||
}
|
||||
public static int2 AdjustForBuildingSize( UnitInfo.BuildingInfo unitInfo )
|
||||
{
|
||||
var dim = unitInfo.Dimensions;
|
||||
return new int2( dim.X / 2, ( dim.Y + 1 ) / 2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ namespace OpenRa.Game
|
||||
public static InfoLoader<WeaponInfo> WeaponInfo;
|
||||
public static InfoLoader<WarheadInfo> WarheadInfo;
|
||||
public static InfoLoader<ProjectileInfo> ProjectileInfo;
|
||||
public static Footprint Footprint;
|
||||
|
||||
public static void LoadRules( string mapFileName )
|
||||
{
|
||||
@@ -38,8 +37,6 @@ namespace OpenRa.Game
|
||||
|
||||
ProjectileInfo = new InfoLoader<ProjectileInfo>(
|
||||
Pair.New<string, Func<string, ProjectileInfo>>("ProjectileTypes", _ => new ProjectileInfo()));
|
||||
|
||||
Footprint = new Footprint(FileSystem.Open("footprint.txt"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,7 +58,6 @@ namespace OpenRa.Game.GameRules
|
||||
|
||||
public class InfantryInfo : MobileInfo
|
||||
{
|
||||
|
||||
public readonly bool C4 = false;
|
||||
public readonly bool FraidyCat = false;
|
||||
public readonly bool Infiltrate = false;
|
||||
@@ -78,6 +77,9 @@ namespace OpenRa.Game.GameRules
|
||||
|
||||
public class BuildingInfo : UnitInfo
|
||||
{
|
||||
public readonly int2 Dimensions = new int2( 1, 1 );
|
||||
public readonly string Footprint = "x";
|
||||
|
||||
public readonly bool BaseNormal = true;
|
||||
public readonly int Adjacent = 1;
|
||||
public readonly bool Bib = false;
|
||||
|
||||
@@ -24,13 +24,15 @@ namespace OpenRa.Game.Graphics
|
||||
|
||||
public void Scroll(float2 delta)
|
||||
{
|
||||
scrollPosition = (scrollPosition + delta).Constrain(float2.Zero, mapSize);
|
||||
scrollPosition = ( scrollPosition + delta ).Constrain( float2.Zero, mapSize );
|
||||
}
|
||||
|
||||
public Viewport(float2 size, float2 mapSize, Renderer renderer)
|
||||
{
|
||||
this.size = size;
|
||||
this.mapSize = Game.CellSize * mapSize - size + new float2(128, 0);
|
||||
if( this.mapSize.X < 0 ) this.mapSize.X = 0;
|
||||
if( this.mapSize.Y < 0 ) this.mapSize.Y = 0;
|
||||
this.renderer = renderer;
|
||||
cursorRenderer = new SpriteRenderer(renderer, true);
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace OpenRa.Game
|
||||
public IEnumerable<Order> Order(int2 xy)
|
||||
{
|
||||
// todo: check that space is free
|
||||
if (Footprint.Tiles(Name, xy).Any(t => !Game.IsCellBuildable(t, UnitMovementType.Wheel)))
|
||||
if (Footprint.Tiles(Rules.UnitInfo[Name], xy).Any(t => !Game.IsCellBuildable(t, UnitMovementType.Wheel)))
|
||||
yield break;
|
||||
|
||||
yield return new PlaceBuildingOrder(this, xy);
|
||||
|
||||
@@ -10,41 +10,34 @@ namespace OpenRa.Game
|
||||
PlaceBuilding building;
|
||||
int2 xy;
|
||||
|
||||
public PlaceBuildingOrder(PlaceBuilding building, int2 xy)
|
||||
public PlaceBuildingOrder( PlaceBuilding building, int2 xy )
|
||||
{
|
||||
this.building = building;
|
||||
this.xy = xy;
|
||||
}
|
||||
|
||||
public override void Apply(bool leftMouseButton)
|
||||
public override void Apply( bool leftMouseButton )
|
||||
{
|
||||
if (leftMouseButton)
|
||||
if( leftMouseButton )
|
||||
{
|
||||
Game.world.AddFrameEndTask(_ =>
|
||||
Game.world.AddFrameEndTask( _ =>
|
||||
{
|
||||
Log.Write("Player \"{0}\" builds {1}", building.Owner.PlayerName, building.Name);
|
||||
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.world.Add( new Actor( building.Name, xy - GameRules.Footprint.AdjustForBuildingSize( building.Name ), building.Owner ) );
|
||||
|
||||
Game.controller.orderGenerator = null;
|
||||
Game.worldRenderer.uiOverlay.KillOverlay();
|
||||
});
|
||||
} );
|
||||
}
|
||||
else
|
||||
{
|
||||
Game.world.AddFrameEndTask(_ =>
|
||||
Game.world.AddFrameEndTask( _ =>
|
||||
{
|
||||
Game.controller.orderGenerator = null;
|
||||
Game.worldRenderer.uiOverlay.KillOverlay();
|
||||
});
|
||||
} );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,176 +1,176 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
using OpenRa.FileFormats;
|
||||
using OpenRa.Game.Graphics;
|
||||
using OpenRa.TechTree;
|
||||
using System.Linq;
|
||||
|
||||
namespace OpenRa.Game
|
||||
{
|
||||
using GRegion = OpenRa.Game.Graphics.Region;
|
||||
|
||||
class Sidebar
|
||||
{
|
||||
TechTree.TechTree techTree;
|
||||
|
||||
SpriteRenderer spriteRenderer, clockRenderer;
|
||||
Sprite blank;
|
||||
readonly GRegion region;
|
||||
|
||||
public GRegion Region { get { return region; } }
|
||||
public float Width { get { return spriteWidth * 2; } }
|
||||
|
||||
Dictionary<string, Sprite> sprites = new Dictionary<string,Sprite>();
|
||||
const int spriteWidth = 64, spriteHeight = 48;
|
||||
|
||||
static string[] groups = new string[] { "building", "vehicle", "boat", "infantry", "plane" };
|
||||
|
||||
Dictionary<string, string> itemGroups = new Dictionary<string,string>(); //item->group
|
||||
Dictionary<string, Animation> clockAnimations = new Dictionary<string,Animation>(); //group->clockAnimation
|
||||
Dictionary<string, SidebarItem> selectedItems = new Dictionary<string,SidebarItem>(); //group->selectedItem
|
||||
|
||||
List<SidebarItem> items = new List<SidebarItem>();
|
||||
|
||||
public Sidebar( Renderer renderer )
|
||||
{
|
||||
this.techTree = Game.LocalPlayer.TechTree;
|
||||
this.techTree.BuildableItemsChanged += PopulateItemList;
|
||||
region = GRegion.Create(Game.viewport, DockStyle.Right, 128, Paint, MouseHandler);
|
||||
Game.viewport.AddRegion( region );
|
||||
spriteRenderer = new SpriteRenderer(renderer, false);
|
||||
clockRenderer = new SpriteRenderer(renderer, true);
|
||||
|
||||
LoadSprites( "BuildingTypes", "building" );
|
||||
LoadSprites( "VehicleTypes", "vehicle" );
|
||||
LoadSprites( "InfantryTypes", "infantry" );
|
||||
LoadSprites( "ShipTypes", "boat" );
|
||||
LoadSprites( "PlaneTypes", "plane" );
|
||||
|
||||
foreach (string s in groups)
|
||||
{
|
||||
clockAnimations.Add(s, new Animation("clock"));
|
||||
clockAnimations[s].PlayRepeating("idle");
|
||||
selectedItems.Add(s, null);
|
||||
}
|
||||
|
||||
blank = SheetBuilder.Add(new Size((int)spriteWidth, (int)spriteHeight), 16);
|
||||
}
|
||||
|
||||
public void Build(SidebarItem item)
|
||||
{
|
||||
if (item != null)
|
||||
Game.controller.orderGenerator = new PlaceBuilding(Game.LocalPlayer,
|
||||
item.techTreeItem.tag.ToLowerInvariant());
|
||||
}
|
||||
|
||||
void LoadSprites( string category, string group )
|
||||
{
|
||||
foreach( var u in Rules.AllRules.GetSection( category ) )
|
||||
{
|
||||
var unit = Rules.UnitInfo[ u.Key ];
|
||||
|
||||
if( unit.TechLevel != -1 )
|
||||
sprites.Add( unit.Name, SpriteSheetBuilder.LoadSprite( unit.Name + "icon", ".shp" ) );
|
||||
itemGroups.Add( unit.Name, group );
|
||||
}
|
||||
}
|
||||
|
||||
void DrawSprite(Sprite s, ref float2 p)
|
||||
{
|
||||
spriteRenderer.DrawSprite(s, p, 0);
|
||||
p.Y += spriteHeight;
|
||||
}
|
||||
|
||||
void Fill(float height, float2 p)
|
||||
{
|
||||
while (p.Y < height)
|
||||
DrawSprite(blank, ref p);
|
||||
}
|
||||
|
||||
int buildPos = 0;
|
||||
int unitPos = 0;
|
||||
|
||||
void PopulateItemList()
|
||||
{
|
||||
buildPos = 0; unitPos = 0;
|
||||
|
||||
items.Clear();
|
||||
|
||||
foreach (Item i in techTree.BuildableItems)
|
||||
{
|
||||
Sprite sprite;
|
||||
if (!sprites.TryGetValue(i.tag, out sprite)) continue;
|
||||
|
||||
items.Add(new SidebarItem(sprite, i, i.IsStructure ? buildPos : unitPos));
|
||||
|
||||
if (i.IsStructure)
|
||||
buildPos += spriteHeight;
|
||||
else
|
||||
unitPos += spriteHeight;
|
||||
}
|
||||
|
||||
foreach (string g in groups) selectedItems[g] = null;
|
||||
}
|
||||
|
||||
void Paint()
|
||||
{
|
||||
foreach (SidebarItem i in items)
|
||||
i.Paint(spriteRenderer, region.Location);
|
||||
|
||||
Fill(region.Size.Y + region.Location.Y, new float2(region.Location.X, buildPos + region.Location.Y));
|
||||
Fill(region.Size.Y + region.Location.Y, new float2(region.Location.X + spriteWidth, unitPos + region.Location.Y));
|
||||
|
||||
spriteRenderer.Flush();
|
||||
|
||||
foreach (var kvp in selectedItems)
|
||||
{
|
||||
if (kvp.Value != null)
|
||||
{
|
||||
clockRenderer.DrawSprite(clockAnimations[kvp.Key].Image, region.Location.ToFloat2() + kvp.Value.location, 0);
|
||||
clockAnimations[kvp.Key].Tick(1);
|
||||
}
|
||||
}
|
||||
|
||||
clockRenderer.Flush();
|
||||
}
|
||||
|
||||
public SidebarItem GetItem(float2 point)
|
||||
{
|
||||
foreach (SidebarItem i in items)
|
||||
if (i.Clicked(point))
|
||||
return i;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
void MouseHandler(MouseInput mi)
|
||||
{
|
||||
if (mi.Button == MouseButtons.Left && mi.Event == MouseInputEvent.Down)
|
||||
{
|
||||
var point = mi.Location.ToFloat2();
|
||||
var item = GetItem(point);
|
||||
if (item != null)
|
||||
{
|
||||
string group = itemGroups[item.techTreeItem.tag];
|
||||
if (selectedItems[group] == null)
|
||||
{
|
||||
selectedItems[group] = item;
|
||||
Build(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( mi.Button == MouseButtons.Right && mi.Event == MouseInputEvent.Down )
|
||||
{
|
||||
var point = mi.Location.ToFloat2();
|
||||
var item = GetItem(point);
|
||||
if( item != null )
|
||||
{
|
||||
string group = itemGroups[ item.techTreeItem.tag ];
|
||||
selectedItems[ group ] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
using OpenRa.FileFormats;
|
||||
using OpenRa.Game.Graphics;
|
||||
using OpenRa.TechTree;
|
||||
using System.Linq;
|
||||
|
||||
namespace OpenRa.Game
|
||||
{
|
||||
using GRegion = OpenRa.Game.Graphics.Region;
|
||||
|
||||
class Sidebar
|
||||
{
|
||||
TechTree.TechTree techTree;
|
||||
|
||||
SpriteRenderer spriteRenderer, clockRenderer;
|
||||
Sprite blank;
|
||||
readonly GRegion region;
|
||||
|
||||
public GRegion Region { get { return region; } }
|
||||
public float Width { get { return spriteWidth * 2; } }
|
||||
|
||||
Dictionary<string, Sprite> sprites = new Dictionary<string,Sprite>();
|
||||
const int spriteWidth = 64, spriteHeight = 48;
|
||||
|
||||
static string[] groups = new string[] { "building", "vehicle", "boat", "infantry", "plane" };
|
||||
|
||||
Dictionary<string, string> itemGroups = new Dictionary<string,string>(); //item->group
|
||||
Dictionary<string, Animation> clockAnimations = new Dictionary<string,Animation>(); //group->clockAnimation
|
||||
Dictionary<string, SidebarItem> selectedItems = new Dictionary<string,SidebarItem>(); //group->selectedItem
|
||||
|
||||
List<SidebarItem> items = new List<SidebarItem>();
|
||||
|
||||
public Sidebar( Renderer renderer )
|
||||
{
|
||||
this.techTree = Game.LocalPlayer.TechTree;
|
||||
this.techTree.BuildableItemsChanged += PopulateItemList;
|
||||
region = GRegion.Create(Game.viewport, DockStyle.Right, 128, Paint, MouseHandler);
|
||||
Game.viewport.AddRegion( region );
|
||||
spriteRenderer = new SpriteRenderer(renderer, false);
|
||||
clockRenderer = new SpriteRenderer(renderer, true);
|
||||
|
||||
LoadSprites( "BuildingTypes", "building" );
|
||||
LoadSprites( "VehicleTypes", "vehicle" );
|
||||
LoadSprites( "InfantryTypes", "infantry" );
|
||||
LoadSprites( "ShipTypes", "boat" );
|
||||
LoadSprites( "PlaneTypes", "plane" );
|
||||
|
||||
foreach (string s in groups)
|
||||
{
|
||||
clockAnimations.Add(s, new Animation("clock"));
|
||||
clockAnimations[s].PlayRepeating("idle");
|
||||
selectedItems.Add(s, null);
|
||||
}
|
||||
|
||||
blank = SheetBuilder.Add(new Size((int)spriteWidth, (int)spriteHeight), 16);
|
||||
}
|
||||
|
||||
public void Build(SidebarItem item)
|
||||
{
|
||||
if (item != null)
|
||||
Game.controller.orderGenerator = new PlaceBuilding(Game.LocalPlayer,
|
||||
item.techTreeItem.tag.ToLowerInvariant());
|
||||
}
|
||||
|
||||
void LoadSprites( string category, string group )
|
||||
{
|
||||
foreach( var u in Rules.AllRules.GetSection( category ) )
|
||||
{
|
||||
var unit = Rules.UnitInfo[ u.Key ];
|
||||
|
||||
if( unit.TechLevel != -1 )
|
||||
sprites.Add( unit.Name, SpriteSheetBuilder.LoadSprite( unit.Name + "icon", ".shp" ) );
|
||||
itemGroups.Add( unit.Name, group );
|
||||
}
|
||||
}
|
||||
|
||||
void DrawSprite(Sprite s, ref float2 p)
|
||||
{
|
||||
spriteRenderer.DrawSprite(s, p, 0);
|
||||
p.Y += spriteHeight;
|
||||
}
|
||||
|
||||
void Fill(float height, float2 p)
|
||||
{
|
||||
while (p.Y < height)
|
||||
DrawSprite(blank, ref p);
|
||||
}
|
||||
|
||||
int buildPos = 0;
|
||||
int unitPos = 0;
|
||||
|
||||
void PopulateItemList()
|
||||
{
|
||||
buildPos = 0; unitPos = 0;
|
||||
|
||||
items.Clear();
|
||||
|
||||
foreach (Item i in techTree.BuildableItems)
|
||||
{
|
||||
Sprite sprite;
|
||||
if (!sprites.TryGetValue(i.tag, out sprite)) continue;
|
||||
|
||||
items.Add(new SidebarItem(sprite, i, i.IsStructure ? buildPos : unitPos));
|
||||
|
||||
if (i.IsStructure)
|
||||
buildPos += spriteHeight;
|
||||
else
|
||||
unitPos += spriteHeight;
|
||||
}
|
||||
|
||||
foreach (string g in groups) selectedItems[g] = null;
|
||||
}
|
||||
|
||||
void Paint()
|
||||
{
|
||||
foreach (SidebarItem i in items)
|
||||
i.Paint(spriteRenderer, region.Location);
|
||||
|
||||
Fill(region.Size.Y + region.Location.Y, new float2(region.Location.X, buildPos + region.Location.Y));
|
||||
Fill(region.Size.Y + region.Location.Y, new float2(region.Location.X + spriteWidth, unitPos + region.Location.Y));
|
||||
|
||||
spriteRenderer.Flush();
|
||||
|
||||
foreach (var kvp in selectedItems)
|
||||
{
|
||||
if (kvp.Value != null)
|
||||
{
|
||||
clockRenderer.DrawSprite(clockAnimations[kvp.Key].Image, region.Location.ToFloat2() + kvp.Value.location, 0);
|
||||
clockAnimations[kvp.Key].Tick(1);
|
||||
}
|
||||
}
|
||||
|
||||
clockRenderer.Flush();
|
||||
}
|
||||
|
||||
public SidebarItem GetItem(float2 point)
|
||||
{
|
||||
foreach (SidebarItem i in items)
|
||||
if (i.Clicked(point))
|
||||
return i;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
void MouseHandler(MouseInput mi)
|
||||
{
|
||||
if (mi.Button == MouseButtons.Left && mi.Event == MouseInputEvent.Down)
|
||||
{
|
||||
var point = mi.Location.ToFloat2();
|
||||
var item = GetItem(point);
|
||||
if (item != null)
|
||||
{
|
||||
string group = itemGroups[item.techTreeItem.tag];
|
||||
if (selectedItems[group] == null)
|
||||
{
|
||||
selectedItems[group] = item;
|
||||
Build(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( mi.Button == MouseButtons.Right && mi.Event == MouseInputEvent.Down )
|
||||
{
|
||||
var point = mi.Location.ToFloat2();
|
||||
var item = GetItem(point);
|
||||
if( item != null )
|
||||
{
|
||||
string group = itemGroups[ item.techTreeItem.tag ];
|
||||
selectedItems[ group ] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,14 +21,13 @@ namespace OpenRa.Game.Traits
|
||||
anim.PlayThen("make", () => anim.PlayRepeating("idle"));
|
||||
|
||||
// at this point, we already know where we are, so we can safely place the bib in the smudge
|
||||
if (((UnitInfo.BuildingInfo)self.unitInfo).Bib)
|
||||
var buildingInfo = (UnitInfo.BuildingInfo)self.unitInfo;
|
||||
if (buildingInfo.Bib)
|
||||
{
|
||||
var fp = Rules.Footprint.GetFootprint(self.unitInfo.Name);
|
||||
var bibOffset = fp.Length - 2;
|
||||
var size = fp.First().Length;
|
||||
var size = buildingInfo.Dimensions.X;
|
||||
var bibOffset = buildingInfo.Dimensions.Y - 1;
|
||||
var startIndex = (size == 2) ? SmallBibStart : LargeBibStart;
|
||||
|
||||
|
||||
for (int i = 0; i < 2 * size; i++)
|
||||
{
|
||||
var p = self.Location + Game.map.Offset + new int2(i % size, i / size + bibOffset);
|
||||
|
||||
@@ -1,61 +1,61 @@
|
||||
using System.Drawing;
|
||||
using OpenRa.Game.Graphics;
|
||||
using System;
|
||||
using OpenRa.Game.GameRules;
|
||||
|
||||
namespace OpenRa.Game
|
||||
{
|
||||
class UiOverlay
|
||||
{
|
||||
SpriteRenderer spriteRenderer;
|
||||
Sprite buildOk;
|
||||
Sprite buildBlocked;
|
||||
|
||||
public UiOverlay(SpriteRenderer spriteRenderer)
|
||||
{
|
||||
this.spriteRenderer = spriteRenderer;
|
||||
|
||||
buildOk = SynthesizeTile(0x80);
|
||||
buildBlocked = SynthesizeTile(0xe6);
|
||||
}
|
||||
|
||||
static Sprite SynthesizeTile(byte paletteIndex)
|
||||
{
|
||||
byte[] data = new byte[Game.CellSize * Game.CellSize];
|
||||
|
||||
for (int i = 0; i < Game.CellSize; i++)
|
||||
for (int j = 0; j < Game.CellSize; j++)
|
||||
data[i * Game.CellSize + j] = ((i + j) % 4 < 2) ? (byte)0 : paletteIndex;
|
||||
|
||||
return SheetBuilder.Add( data, new Size(Game.CellSize,Game.CellSize) );
|
||||
}
|
||||
|
||||
public void Draw()
|
||||
{
|
||||
if (!hasOverlay)
|
||||
using System.Drawing;
|
||||
using OpenRa.Game.Graphics;
|
||||
using System;
|
||||
using OpenRa.Game.GameRules;
|
||||
|
||||
namespace OpenRa.Game
|
||||
{
|
||||
class UiOverlay
|
||||
{
|
||||
SpriteRenderer spriteRenderer;
|
||||
Sprite buildOk;
|
||||
Sprite buildBlocked;
|
||||
|
||||
public UiOverlay(SpriteRenderer spriteRenderer)
|
||||
{
|
||||
this.spriteRenderer = spriteRenderer;
|
||||
|
||||
buildOk = SynthesizeTile(0x80);
|
||||
buildBlocked = SynthesizeTile(0xe6);
|
||||
}
|
||||
|
||||
static Sprite SynthesizeTile(byte paletteIndex)
|
||||
{
|
||||
byte[] data = new byte[Game.CellSize * Game.CellSize];
|
||||
|
||||
for (int i = 0; i < Game.CellSize; i++)
|
||||
for (int j = 0; j < Game.CellSize; j++)
|
||||
data[i * Game.CellSize + j] = ((i + j) % 4 < 2) ? (byte)0 : paletteIndex;
|
||||
|
||||
return SheetBuilder.Add( data, new Size(Game.CellSize,Game.CellSize) );
|
||||
}
|
||||
|
||||
public void Draw()
|
||||
{
|
||||
if (!hasOverlay)
|
||||
return;
|
||||
|
||||
foreach (var t in Footprint.Tiles(name,position))
|
||||
spriteRenderer.DrawSprite(Game.IsCellBuildable(t, UnitMovementType.Wheel)
|
||||
? buildOk : buildBlocked, Game.CellSize * t, 0);
|
||||
|
||||
spriteRenderer.Flush();
|
||||
}
|
||||
|
||||
bool hasOverlay;
|
||||
int2 position;
|
||||
string name;
|
||||
|
||||
public void KillOverlay()
|
||||
{
|
||||
hasOverlay = false;
|
||||
}
|
||||
|
||||
public void SetCurrentOverlay(int2 cell, string name)
|
||||
{
|
||||
hasOverlay = true;
|
||||
position = cell;
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach( var t in Footprint.Tiles( Rules.UnitInfo[ name ], position ) )
|
||||
spriteRenderer.DrawSprite( Game.IsCellBuildable( t, UnitMovementType.Wheel )
|
||||
? buildOk : buildBlocked, Game.CellSize * t, 0 );
|
||||
|
||||
spriteRenderer.Flush();
|
||||
}
|
||||
|
||||
bool hasOverlay;
|
||||
int2 position;
|
||||
string name;
|
||||
|
||||
public void KillOverlay()
|
||||
{
|
||||
hasOverlay = false;
|
||||
}
|
||||
|
||||
public void SetCurrentOverlay(int2 cell, string name)
|
||||
{
|
||||
hasOverlay = true;
|
||||
position = cell;
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user