Merge commit 'pchote/NewUI'

This commit is contained in:
Chris Forbes
2010-01-10 22:36:52 +13:00
20 changed files with 548 additions and 248 deletions

View File

@@ -15,20 +15,19 @@ namespace OpenRa.Game
{ {
readonly Renderer renderer; readonly Renderer renderer;
readonly LineRenderer lineRenderer; readonly LineRenderer lineRenderer;
readonly Sheet chromeTexture;
readonly SpriteRenderer rgbaRenderer; readonly SpriteRenderer rgbaRenderer;
readonly Sprite[] specialBinSprites; readonly SpriteRenderer shpRenderer;
readonly Sprite moneyBinSprite;
readonly Sprite tooltipSprite;
readonly Sprite powerIndicatorSprite;
readonly Sprite powerLevelTopSprite;
readonly Sprite powerLevelBottomSprite;
readonly Animation repairButton; string chromeCollection;
readonly Animation sellButton; string radarCollection;
readonly Animation pwrdownButton; string paletteCollection;
readonly Animation optionsButton; string digitCollection;
// Special power bin
readonly Dictionary<string, Sprite> spsprites;
// Options menu (to be refactored)
bool optionsPressed = false;
readonly Sprite optionsTop; readonly Sprite optionsTop;
readonly Sprite optionsBottom; readonly Sprite optionsBottom;
readonly Sprite optionsLeft; readonly Sprite optionsLeft;
@@ -38,65 +37,57 @@ namespace OpenRa.Game
readonly Sprite optionsBottomLeft; readonly Sprite optionsBottomLeft;
readonly Sprite optionsBottomRight; readonly Sprite optionsBottomRight;
readonly Sprite optionsBackground; readonly Sprite optionsBackground;
readonly SpriteRenderer shpRenderer; // Buttons
readonly Animation repairButton;
readonly Animation sellButton;
readonly Animation pwrdownButton;
readonly Animation optionsButton;
// Build Palette tabs
string currentTab = "Building";
bool paletteOpen = false;
static string[] groups = new string[] { "Building", "Defense", "Infantry", "Vehicle", "Plane", "Ship" };
readonly Dictionary<string, string[]> tabImageNames;
readonly Dictionary<string, Sprite> tabSprites;
// Build Palette
const int paletteColumns = 3;
const int paletteRows = 5;
static float2 paletteOpenOrigin = new float2(Game.viewport.Width - 215, 280);
static float2 paletteClosedOrigin = new float2(Game.viewport.Width - 16, 280);
static float2 paletteOrigin = paletteClosedOrigin;
const int paletteAnimationLength = 7;
int paletteAnimationFrame = 0;
bool paletteAnimating = false;
readonly List<Pair<RectangleF, Action<bool>>> buttons = new List<Pair<RectangleF, Action<bool>>>();
readonly Animation cantBuild; readonly Animation cantBuild;
readonly Animation ready; readonly Animation ready;
readonly Animation clock; readonly Animation clock;
readonly List<Pair<Rectangle, Action<bool>>> buttons = new List<Pair<Rectangle, Action<bool>>>();
readonly List<Sprite> digitSprites;
readonly Dictionary<string, Sprite[]> tabSprites;
readonly Dictionary<string, Sprite> spsprites;
readonly Sprite[] shimSprites;
readonly Sprite blank;
readonly int paletteColumns;
readonly int2 paletteOrigin;
bool hadRadar = false;
bool optionsPressed = false;
const int MinRows = 4;
string currentTab = "Building";
static string[] groups = new string[] { "Building", "Defense", "Infantry", "Vehicle", "Plane", "Ship" };
readonly Dictionary<string, Sprite> sprites;
const int NumClockFrames = 54; const int NumClockFrames = 54;
// Radar
static float2 radarOpenOrigin = new float2(Game.viewport.Width - 215, 29);
static float2 radarClosedOrigin = new float2(Game.viewport.Width - 215, -166);
static float2 radarOrigin = radarClosedOrigin;
float radarMinimapHeight;
const int radarSlideAnimationLength = 15;
const int radarActivateAnimationLength = 5;
int radarAnimationFrame = 0;
bool radarAnimating = false;
bool hasRadar = false;
// Power bar
static float2 powerOrigin = new float2(42, 205); // Relative to radarOrigin
static Size powerSize = new Size(138,5);
public Chrome(Renderer r) public Chrome(Renderer r)
{ {
// Positioning of chrome elements
// Build palette
paletteColumns = 4;
paletteOrigin = new int2(Game.viewport.Width - paletteColumns * 64 - 9 - 20, 282);
this.renderer = r; this.renderer = r;
chromeTexture = new Sheet(renderer, "specialbin.png");
rgbaRenderer = new SpriteRenderer(renderer, true, renderer.RgbaSpriteShader); rgbaRenderer = new SpriteRenderer(renderer, true, renderer.RgbaSpriteShader);
lineRenderer = new LineRenderer(renderer); lineRenderer = new LineRenderer(renderer);
shpRenderer = new SpriteRenderer(renderer, true); shpRenderer = new SpriteRenderer(renderer, true);
specialBinSprites = new []
{
new Sprite(chromeTexture, new Rectangle(0, 0, 32, 51), TextureChannel.Alpha),
new Sprite(chromeTexture, new Rectangle(0, 51, 32, 51 /*144*/), TextureChannel.Alpha),
new Sprite(chromeTexture, new Rectangle(0, 192-39, 32, 39 ), TextureChannel.Alpha),
};
moneyBinSprite = new Sprite(chromeTexture, new Rectangle(512 - 320, 0, 320, 32), TextureChannel.Alpha);
tooltipSprite = new Sprite(chromeTexture, new Rectangle(0, 288, 272, 136), TextureChannel.Alpha);
var powerIndicator = new Animation("power");
powerIndicator.PlayRepeating("power-level-indicator");
powerIndicatorSprite = powerIndicator.Image;
var powerTop = new Animation("powerbar");
powerTop.PlayRepeating("powerbar-top");
powerLevelTopSprite = powerTop.Image;
var powerBottom = new Animation("powerbar");
powerBottom.PlayRepeating("powerbar-bottom");
powerLevelBottomSprite = powerBottom.Image;
repairButton = new Animation("repair"); repairButton = new Animation("repair");
repairButton.PlayRepeating("normal"); repairButton.PlayRepeating("normal");
@@ -119,9 +110,7 @@ namespace OpenRa.Game
optionsBottomRight = SpriteSheetBuilder.LoadAllSprites("dd-crnr")[3]; optionsBottomRight = SpriteSheetBuilder.LoadAllSprites("dd-crnr")[3];
optionsBackground = SpriteSheetBuilder.LoadAllSprites("dd-bkgnd")[Game.CosmeticRandom.Next(4)]; optionsBackground = SpriteSheetBuilder.LoadAllSprites("dd-bkgnd")[Game.CosmeticRandom.Next(4)];
blank = SheetBuilder.Add(new Size(64, 48), 16); tabSprites = groups
sprites = groups
.SelectMany(g => Rules.Categories[g]) .SelectMany(g => Rules.Categories[g])
.Where(u => Rules.UnitInfo[u].TechLevel != -1) .Where(u => Rules.UnitInfo[u].TechLevel != -1)
.ToDictionary( .ToDictionary(
@@ -132,59 +121,52 @@ namespace OpenRa.Game
.ToDictionary( .ToDictionary(
u => u.Key, u => u.Key,
u => SpriteSheetBuilder.LoadAllSprites(u.Value.Image)[0]); u => SpriteSheetBuilder.LoadAllSprites(u.Value.Image)[0]);
tabSprites = groups.Select( tabImageNames = groups.Select(
(g, i) => Pair.New(g, (g, i) => Pair.New(g,
OpenRa.Game.Graphics.Util.MakeArray(3, OpenRa.Game.Graphics.Util.MakeArray(3,
n => new Sprite(chromeTexture, n => i.ToString())))
new Rectangle(512 - (n + 1) * 27, 64 + i * 40, 27, 40),
TextureChannel.Alpha))))
.ToDictionary(a => a.First, a => a.Second); .ToDictionary(a => a.First, a => a.Second);
cantBuild = new Animation("clock"); cantBuild = new Animation("clock");
cantBuild.PlayFetchIndex("idle", () => 0); cantBuild.PlayFetchIndex("idle", () => 0);
digitSprites = Graphics.Util.MakeArray(10, a => a)
.Select(n => new Sprite(chromeTexture, new Rectangle(32 + 13 * n, 0, 13, 17), TextureChannel.Alpha)).ToList();
shimSprites = new[]
{
new Sprite( chromeTexture, new Rectangle( 0, 192, 9, 10 ), TextureChannel.Alpha ),
new Sprite( chromeTexture, new Rectangle( 0, 202, 9, 10 ), TextureChannel.Alpha ),
new Sprite( chromeTexture, new Rectangle( 0, 216, 9, 48 ), TextureChannel.Alpha ),
new Sprite( chromeTexture, new Rectangle( 11, 192, 64, 10 ), TextureChannel.Alpha ),
new Sprite( chromeTexture, new Rectangle( 11, 202, 64, 10 ), TextureChannel.Alpha ),
};
ready = new Animation("pips"); ready = new Animation("pips");
ready.PlayRepeating("ready"); ready.PlayRepeating("ready");
clock = new Animation("clock"); clock = new Animation("clock");
} }
public void Tick()
{
TickPaletteAnimation();
TickRadarAnimation();
}
public void Draw() public void Draw()
{ {
chromeCollection = (Game.LocalPlayer.Race == Race.Allies) ? "chrome-allies" : "chrome-soviet";
radarCollection = (Game.LocalPlayer.Race == Race.Allies) ? "radar-allies" : "radar-soviet";
paletteCollection = (Game.LocalPlayer.Race == Race.Allies) ? "palette-allies" : "palette-soviet";
digitCollection = (Game.LocalPlayer.Race == Race.Allies) ? "digits-allies" : "digits-soviet";
buttons.Clear(); buttons.Clear();
renderer.Device.DisableScissor(); renderer.Device.DisableScissor();
renderer.DrawText("RenderFrame {0} ({2:F1} ms)\nTick {1} ({3:F1} ms)\nPower {4}/{5}\nReady: {6} (F8 to toggle)".F( renderer.DrawText("RenderFrame {0} ({2:F1} ms)\nTick {1} ({3:F1} ms)\nReady: {4} (F8 to toggle)".F(
Game.RenderFrame, Game.RenderFrame,
Game.orderManager.FrameNumber, Game.orderManager.FrameNumber,
PerfHistory.items["render"].LastValue, PerfHistory.items["render"].LastValue,
PerfHistory.items["tick_time"].LastValue, PerfHistory.items["tick_time"].LastValue,
Game.LocalPlayer.PowerDrained,
Game.LocalPlayer.PowerProvided,
Game.LocalPlayer.IsReady ? "Yes" : "No" Game.LocalPlayer.IsReady ? "Yes" : "No"
), new int2(140, 15), Color.White); ), new int2(140, 15), Color.White);
if (Game.Settings.PerfGraph) if (Game.Settings.PerfGraph)
PerfHistory.Render(renderer, Game.worldRenderer.lineRenderer); PerfHistory.Render(renderer, Game.worldRenderer.lineRenderer);
DrawMinimap(); DrawRadar();
rgbaRenderer.DrawSprite(moneyBinSprite, new float2(Game.viewport.Width - 320, 0), PaletteType.Chrome);
DrawMoney();
DrawPower(); DrawPower();
rgbaRenderer.DrawSprite(SequenceProvider.GetImageFromCollection(renderer, chromeCollection, "moneybin"), new float2(Game.viewport.Width - 320, 0), PaletteType.Chrome);
DrawMoney();
rgbaRenderer.Flush(); rgbaRenderer.Flush();
DrawButtons(); DrawButtons();
@@ -195,22 +177,73 @@ namespace OpenRa.Game
DrawOptionsMenu(); DrawOptionsMenu();
} }
void DrawMinimap() public void TickRadarAnimation()
{ {
var hasRadar = Game.world.Actors.Any(a => a.Owner == Game.LocalPlayer if (!radarAnimating)
return;
// Increment frame
if (hasRadar)
radarAnimationFrame++;
else
radarAnimationFrame--;
// Calculate radar bin position
if (radarAnimationFrame <= radarSlideAnimationLength)
radarOrigin = float2.Lerp(radarClosedOrigin, radarOpenOrigin, radarAnimationFrame * 1.0f / radarSlideAnimationLength);
// Play radar-on sound at the start of the activate anim (open)
if (radarAnimationFrame == radarSlideAnimationLength && hasRadar)
Sound.Play("radaron2.aud");
// Play radar-on sound at the start of the activate anim (close)
if (radarAnimationFrame == radarSlideAnimationLength + radarActivateAnimationLength - 1 && !hasRadar)
Sound.Play("radardn1.aud");
// Minimap height
if (radarAnimationFrame >= radarSlideAnimationLength)
radarMinimapHeight = float2.Lerp(0, 192, (radarAnimationFrame - radarSlideAnimationLength) * 1.0f / radarActivateAnimationLength);
// Animation is complete
if ((radarAnimationFrame == 0 && !hasRadar)
|| (radarAnimationFrame == radarSlideAnimationLength + radarActivateAnimationLength && hasRadar))
{
radarAnimating = false;
}
}
void DrawRadar()
{
var hasNewRadar = Game.world.Actors.Any(a => a.Owner == Game.LocalPlayer
&& a.traits.Contains<ProvidesRadar>() && a.traits.Contains<ProvidesRadar>()
&& a.traits.Get<ProvidesRadar>().IsActive()); && a.traits.Get<ProvidesRadar>().IsActive());
if (hasRadar != hadRadar) if (hasNewRadar != hasRadar)
Sound.Play((hasRadar) ? "radaron2.aud" : "radardn1.aud"); {
hadRadar = hasRadar; radarAnimating = true;
}
hasRadar = hasNewRadar;
var isJammed = false; // todo: MRJ can do this var isJammed = false; // todo: MRJ can do this
rgbaRenderer.DrawSprite(SequenceProvider.GetImageFromCollection(renderer, radarCollection, "left"), radarOrigin, PaletteType.Chrome);
rgbaRenderer.DrawSprite(SequenceProvider.GetImageFromCollection(renderer, radarCollection, "right"), radarOrigin + new float2(201, 0), PaletteType.Chrome);
rgbaRenderer.DrawSprite(SequenceProvider.GetImageFromCollection(renderer, radarCollection, "bottom"), radarOrigin + new float2(0, 192), PaletteType.Chrome);
if (radarAnimating)
rgbaRenderer.DrawSprite(SequenceProvider.GetImageFromCollection(renderer, radarCollection, "bg"), radarOrigin + new float2(9, 0), PaletteType.Chrome);
Game.minimap.Draw(new float2(Game.viewport.Width - 247, 10), hasRadar, isJammed); rgbaRenderer.Flush();
if (radarAnimationFrame >= radarSlideAnimationLength)
{
RectangleF mapRect = new RectangleF(radarOrigin.X + 9, radarOrigin.Y+(192-radarMinimapHeight)/2, 192, radarMinimapHeight);
Game.minimap.Draw(mapRect, hasRadar, isJammed);
}
} }
void AddButton(Rectangle r, Action<bool> b) { buttons.Add(Pair.New(r, b)); } void AddButton(RectangleF r, Action<bool> b) { buttons.Add(Pair.New(r, b)); }
void DrawBuildTabs(int paletteHeight) void DrawBuildTabs(int paletteHeight)
{ {
@@ -224,7 +257,7 @@ namespace OpenRa.Game
var queue = Game.LocalPlayer.PlayerActor.traits.Get<Traits.ProductionQueue>(); var queue = Game.LocalPlayer.PlayerActor.traits.Get<Traits.ProductionQueue>();
foreach (var q in tabSprites) foreach (var q in tabImageNames)
{ {
var groupName = q.Key; var groupName = q.Key;
if (!Rules.TechTree.BuildableItems(Game.LocalPlayer, groupName).Any()) if (!Rules.TechTree.BuildableItems(Game.LocalPlayer, groupName).Any())
@@ -232,29 +265,30 @@ namespace OpenRa.Game
CheckDeadTab(groupName); CheckDeadTab(groupName);
continue; continue;
} }
string[] tabKeys = { "normal", "ready", "selected" };
var producing = queue.CurrentItem(groupName); var producing = queue.CurrentItem(groupName);
var index = q.Key == currentTab ? 2 : (producing != null && producing.Done) ? 1 : 0; var index = q.Key == currentTab ? 2 : (producing != null && producing.Done) ? 1 : 0;
var race = (Game.LocalPlayer.Race == Race.Allies) ? "allies" : "soviet";
rgbaRenderer.DrawSprite(SequenceProvider.GetImageFromCollection(renderer,"tabs-"+tabKeys[index], race+"-"+q.Key), new float2(x, y), PaletteType.Chrome);
// Don't let tabs overlap the bevel
if (y > paletteOrigin.Y + paletteHeight - tabHeight - 9 && y < paletteOrigin.Y + paletteHeight)
y += tabHeight;
// Stick tabs to the edge of the screen
if (y > paletteOrigin.Y + paletteHeight)
x = Game.viewport.Width - tabWidth;
rgbaRenderer.DrawSprite(q.Value[index], new float2(x, y), PaletteType.Chrome); buttons.Add(Pair.New(new RectangleF(x, y, tabWidth, tabHeight),
(Action<bool>)(isLmb => HandleTabClick(groupName))));
buttons.Add(Pair.New(new Rectangle(x, y, tabWidth, tabHeight),
(Action<bool>)(isLmb => currentTab = groupName)));
y += tabHeight; y += tabHeight;
} }
rgbaRenderer.Flush(); rgbaRenderer.Flush();
} }
void HandleTabClick(string button)
{
Sound.Play("ramenu1.aud");
var wasOpen = paletteOpen;
paletteOpen = (currentTab == button && wasOpen) ? false : true;
currentTab = button;
if (wasOpen != paletteOpen)
paletteAnimating = true;
}
void CheckDeadTab( string groupName ) void CheckDeadTab( string groupName )
{ {
var queue = Game.LocalPlayer.PlayerActor.traits.Get<Traits.ProductionQueue>(); var queue = Game.LocalPlayer.PlayerActor.traits.Get<Traits.ProductionQueue>();
@@ -264,17 +298,17 @@ namespace OpenRa.Game
void ChooseAvailableTab() void ChooseAvailableTab()
{ {
currentTab = tabSprites.Select(q => q.Key).FirstOrDefault( currentTab = tabImageNames.Select(q => q.Key).FirstOrDefault(
t => Rules.TechTree.BuildableItems(Game.LocalPlayer, t).Any()); t => Rules.TechTree.BuildableItems(Game.LocalPlayer, t).Any());
} }
void DrawMoney() void DrawMoney()
{ {
var moneyDigits = Game.LocalPlayer.DisplayCash.ToString(); var moneyDigits = Game.LocalPlayer.DisplayCash.ToString();
var x = Game.viewport.Width - 155; var x = Game.viewport.Width - 65;
foreach (var d in moneyDigits.Reverse()) foreach (var d in moneyDigits.Reverse())
{ {
rgbaRenderer.DrawSprite(digitSprites[d - '0'], new float2(x, 6), PaletteType.Chrome); rgbaRenderer.DrawSprite(SequenceProvider.GetImageFromCollection(renderer, digitCollection, (d - '0').ToString()), new float2(x, 6), PaletteType.Chrome);
x -= 14; x -= 14;
} }
} }
@@ -284,51 +318,60 @@ namespace OpenRa.Game
void DrawPower() void DrawPower()
{ {
//draw background // Nothing to draw
float2 powerOrigin = Game.viewport.Location + new float2(Game.viewport.Width - 20, paletteOrigin.Y); if (Game.LocalPlayer.PowerProvided == 0 && Game.LocalPlayer.PowerDrained == 0)
return;
shpRenderer.DrawSprite(powerLevelTopSprite, powerOrigin, PaletteType.Chrome);
shpRenderer.DrawSprite(powerLevelBottomSprite, powerOrigin + new float2(0, powerLevelTopSprite.size.Y), PaletteType.Chrome);
shpRenderer.Flush();
float2 top = powerOrigin + new float2(0, 15);
float2 bottom = powerOrigin + new float2(0, powerLevelTopSprite.size.Y + powerLevelBottomSprite.size.Y) - new float2(0, 50);
var scale = 100; // Draw bar horizontally
while(Math.Max(Game.LocalPlayer.PowerProvided, Game.LocalPlayer.PowerDrained) >= scale) scale *= 2; var barStart = powerOrigin + Game.viewport.Location + radarOrigin;
//draw bar var barEnd = barStart + new float2(powerSize.Width, 0);
var powerTopY = bottom.Y + (top.Y - bottom.Y) * (Game.LocalPlayer.PowerProvided / (float)scale) - Game.viewport.Location.Y; float powerScaleBy = 100;
lastPowerProvidedPos = float2.Lerp(lastPowerProvidedPos.GetValueOrDefault(powerTopY), powerTopY, .3f); var maxPower = Math.Max(Game.LocalPlayer.PowerProvided, Game.LocalPlayer.PowerDrained);
float2 powerTop = new float2(bottom.X, lastPowerProvidedPos.Value + Game.viewport.Location.Y); while (maxPower >= powerScaleBy) powerScaleBy *= 2;
// Current power supply
var powerLevelTemp = barStart.X + (barEnd.X - barStart.X) * (Game.LocalPlayer.PowerProvided / powerScaleBy) - Game.viewport.Location.X;
lastPowerProvidedPos = float2.Lerp(lastPowerProvidedPos.GetValueOrDefault(powerLevelTemp), powerLevelTemp, .3f);
float2 powerLevel = new float2(lastPowerProvidedPos.Value + Game.viewport.Location.X, barStart.Y);
var color = Color.LimeGreen; var color = Color.LimeGreen;
if (Game.LocalPlayer.GetPowerState() == PowerState.Low) if (Game.LocalPlayer.GetPowerState() == PowerState.Low)
color = Color.Orange; color = Color.Orange;
if (Game.LocalPlayer.GetPowerState() == PowerState.Critical) if (Game.LocalPlayer.GetPowerState() == PowerState.Critical)
color = Color.Red; color = Color.Red;
var color2 = Graphics.Util.Lerp(0.25f, color, Color.Black); var colorDark = Graphics.Util.Lerp(0.25f, color, Color.Black);
for (int i = 0; i < powerSize.Height; i++)
for(int i = 11; i < 13; i++) {
lineRenderer.DrawLine(bottom + new float2(i, 0), powerTop + new float2(i, 0), color, color); color = (i-1 < powerSize.Height/2) ? color : colorDark;
for (int i = 13; i < 15; i++) float2 leftOffset = new float2(0,i);
lineRenderer.DrawLine(bottom + new float2(i, 0), powerTop + new float2(i, 0), color2, color2); float2 rightOffset = new float2(0,i);
// Indent corners
if ((i == 0 || i == powerSize.Height - 1) && powerLevel.X - barStart.X > 1)
{
leftOffset.X += 1;
rightOffset.X -= 1;
}
lineRenderer.DrawLine(barStart + leftOffset, powerLevel + rightOffset, color, color);
}
lineRenderer.Flush(); lineRenderer.Flush();
var drainedPositionY = bottom.Y + (top.Y - bottom.Y)*(Game.LocalPlayer.PowerDrained/(float) scale) - powerIndicatorSprite.size.Y /2 - Game.viewport.Location.Y; // Power usage indicator
lastPowerDrainedPos = float2.Lerp(lastPowerDrainedPos.GetValueOrDefault(drainedPositionY), drainedPositionY, .3f); var indicator = SequenceProvider.GetImageFromCollection(renderer, radarCollection, "power-indicator");
//draw indicator var powerDrainedTemp = barStart.X + (barEnd.X - barStart.X) * (Game.LocalPlayer.PowerDrained / powerScaleBy) - Game.viewport.Location.X;
float2 drainedPosition = new float2(bottom.X + 2, lastPowerDrainedPos.Value + Game.viewport.Location.Y); lastPowerDrainedPos = float2.Lerp(lastPowerDrainedPos.GetValueOrDefault(powerDrainedTemp), powerDrainedTemp, .3f);
float2 powerDrainLevel = new float2(lastPowerDrainedPos.Value-indicator.size.X/2, barStart.Y - Game.viewport.Location.Y-1);
shpRenderer.DrawSprite(powerIndicatorSprite, drainedPosition, PaletteType.Chrome);
shpRenderer.Flush(); rgbaRenderer.DrawSprite(indicator, powerDrainLevel, PaletteType.Chrome);
rgbaRenderer.Flush();
} }
void DrawButtons() void DrawButtons()
{ {
int2 buttonOrigin = new int2(Game.viewport.Width - 320, 2);
// Repair // Repair
Rectangle repairRect = new Rectangle(Game.viewport.Width - 120, 5, repairButton.Image.bounds.Width, repairButton.Image.bounds.Height); Rectangle repairRect = new Rectangle(buttonOrigin.X, buttonOrigin.Y, repairButton.Image.bounds.Width, repairButton.Image.bounds.Height);
var repairDrawPos = Game.viewport.Location + new float2(repairRect.Location); var repairDrawPos = Game.viewport.Location + new float2(repairRect.Location);
var hasFact = Game.world.Actors.Any(a => a.Owner == Game.LocalPlayer && a.traits.Contains<ConstructionYard>()); var hasFact = Game.world.Actors.Any(a => a.Owner == Game.LocalPlayer && a.traits.Contains<ConstructionYard>());
@@ -343,7 +386,7 @@ namespace OpenRa.Game
shpRenderer.DrawSprite(repairButton.Image, repairDrawPos, PaletteType.Chrome); shpRenderer.DrawSprite(repairButton.Image, repairDrawPos, PaletteType.Chrome);
// Sell // Sell
Rectangle sellRect = new Rectangle(Game.viewport.Width - 80, 5, Rectangle sellRect = new Rectangle(buttonOrigin.X+40, buttonOrigin.Y,
sellButton.Image.bounds.Width, sellButton.Image.bounds.Height); sellButton.Image.bounds.Width, sellButton.Image.bounds.Height);
var sellDrawPos = Game.viewport.Location + new float2(sellRect.Location); var sellDrawPos = Game.viewport.Location + new float2(sellRect.Location);
@@ -357,7 +400,7 @@ namespace OpenRa.Game
if (Game.Settings.PowerDownBuildings) if (Game.Settings.PowerDownBuildings)
{ {
// Power Down // Power Down
Rectangle pwrdownRect = new Rectangle(Game.viewport.Width - 40, 5, Rectangle pwrdownRect = new Rectangle(buttonOrigin.X+80, buttonOrigin.Y,
pwrdownButton.Image.bounds.Width, pwrdownButton.Image.bounds.Height); pwrdownButton.Image.bounds.Width, pwrdownButton.Image.bounds.Height);
var pwrdownDrawPos = Game.viewport.Location + new float2(pwrdownRect.Location); var pwrdownDrawPos = Game.viewport.Location + new float2(pwrdownRect.Location);
@@ -437,12 +480,48 @@ namespace OpenRa.Game
renderer.DrawText(line.c, p + new int2(size.X + 10, 0), Color.White); renderer.DrawText(line.c, p + new int2(size.X + 10, 0), Color.White);
} }
void TickPaletteAnimation()
{
Log.Write("{0} {1} {2} {3}", paletteAnimationFrame, paletteOrigin.X, paletteAnimating, paletteOpen);
if (!paletteAnimating)
return;
// Increment frame
if (paletteOpen)
paletteAnimationFrame++;
else
paletteAnimationFrame--;
Log.Write("{0}",paletteAnimationFrame);
// Calculate palette position
if (paletteAnimationFrame <= paletteAnimationLength)
paletteOrigin = float2.Lerp(paletteClosedOrigin, paletteOpenOrigin, paletteAnimationFrame * 1.0f / paletteAnimationLength);
// Play radar-on sound at the start of the activate anim (open)
if (paletteAnimationFrame == 1 && paletteOpen)
Sound.Play("bleep13.aud");
// Play radar-on sound at the start of the activate anim (close)
if (paletteAnimationFrame == paletteAnimationLength + -1 && !paletteOpen)
Sound.Play("bleep13.aud");
// Animation is complete
if ((paletteAnimationFrame == 0 && !paletteOpen)
|| (paletteAnimationFrame == paletteAnimationLength && paletteOpen))
{
paletteAnimating = false;
}
}
// Return an int telling us the y coordinate at the bottom of the palette // Return an int telling us the y coordinate at the bottom of the palette
int DrawBuildPalette(string queueName) int DrawBuildPalette(string queueName)
{ {
// Hack // Hack
int columns = paletteColumns; int columns = paletteColumns;
int2 origin = new int2(paletteOrigin.X + 9, paletteOrigin.Y + 9); float2 origin = new float2(paletteOrigin.X + 9, paletteOrigin.Y + 9);
if (queueName == null) return 0; if (queueName == null) return 0;
@@ -461,13 +540,26 @@ namespace OpenRa.Game
string tooltipItem = null; string tooltipItem = null;
// Draw the top border
rgbaRenderer.DrawSprite(SequenceProvider.GetImageFromCollection(renderer, paletteCollection, "top"), new float2(origin.X - 9, origin.Y - 9), PaletteType.Chrome);
// Draw the icons
int lasty = -1;
foreach (var item in allItems) foreach (var item in allItems)
{ {
var rect = new Rectangle(origin.X + x * 64, origin.Y + 48 * y, 64, 48); // Draw the background for this row
if (y != lasty)
{
rgbaRenderer.DrawSprite(SequenceProvider.GetImageFromCollection(renderer, paletteCollection, "bg-" + (y % 4).ToString()), new float2(origin.X - 9, origin.Y + 48 * y), PaletteType.Chrome);
rgbaRenderer.Flush();
lasty = y;
}
var rect = new RectangleF(origin.X + x * 64, origin.Y + 48 * y, 64, 48);
var drawPos = Game.viewport.Location + new float2(rect.Location); var drawPos = Game.viewport.Location + new float2(rect.Location);
var isBuildingSomething = queue.CurrentItem(queueName) != null; var isBuildingSomething = queue.CurrentItem(queueName) != null;
shpRenderer.DrawSprite(sprites[item], drawPos, PaletteType.Chrome); shpRenderer.DrawSprite(tabSprites[item], drawPos, PaletteType.Chrome);
var firstOfThis = queue.AllItems(queueName).FirstOrDefault(a => a.Item == item); var firstOfThis = queue.AllItems(queueName).FirstOrDefault(a => a.Item == item);
@@ -516,38 +608,35 @@ namespace OpenRa.Game
var closureItem = item; var closureItem = item;
AddButton(rect, isLmb => HandleBuildPalette(closureItem, isLmb)); AddButton(rect, isLmb => HandleBuildPalette(closureItem, isLmb));
if (++x == columns) { x = 0; y++; } if (++x == columns) { x = 0; y++; }
} }
if (x != 0) y++;
while (x != 0 || y < MinRows)
while (y < paletteRows)
{ {
var rect = new Rectangle(origin.X + x * 64, origin.Y + 48 * y, 64, 48); rgbaRenderer.DrawSprite(SequenceProvider.GetImageFromCollection(renderer, paletteCollection, "bg-" + (y % 4).ToString()), new float2(origin.X - 9, origin.Y + 48 * y), PaletteType.Chrome);
var drawPos = Game.viewport.Location + new float2(rect.Location); y++;
shpRenderer.DrawSprite(blank, drawPos, PaletteType.Chrome);
AddButton(rect, _ => { });
if (++x == columns) { x = 0; y++; }
} }
foreach (var ob in overlayBits) foreach (var ob in overlayBits)
shpRenderer.DrawSprite(ob.First, ob.Second, PaletteType.Chrome); shpRenderer.DrawSprite(ob.First, ob.Second, PaletteType.Chrome);
shpRenderer.Flush(); shpRenderer.Flush();
rgbaRenderer.DrawSprite(SequenceProvider.GetImageFromCollection(renderer, paletteCollection, "bottom"), new float2(origin.X - 9, origin.Y - 1 + 48 * y), PaletteType.Chrome);
for (var j = 0; j < y; j++) // Draw dock
rgbaRenderer.DrawSprite(shimSprites[2], new float2(origin.X - 9, origin.Y + 48 * j), PaletteType.Chrome); rgbaRenderer.DrawSprite(SequenceProvider.GetImageFromCollection(renderer, paletteCollection, "dock-top"), new float2(Game.viewport.Width - 14, origin.Y - 23), PaletteType.Chrome);
for (int i = 0; i < y; i++)
rgbaRenderer.DrawSprite(shimSprites[0], new float2(origin.X - 9, origin.Y - 9), PaletteType.Chrome);
rgbaRenderer.DrawSprite(shimSprites[1], new float2(origin.X - 9, origin.Y - 1 + 48 * y), PaletteType.Chrome);
for (var i = 0; i < columns; i++)
{ {
rgbaRenderer.DrawSprite(shimSprites[3], new float2(origin.X + 64 * i, origin.Y - 9), PaletteType.Chrome); rgbaRenderer.DrawSprite(SequenceProvider.GetImageFromCollection(renderer, paletteCollection, "dock-" + (y % 4).ToString()), new float2(Game.viewport.Width - 14, origin.Y + 48 * i), PaletteType.Chrome);
rgbaRenderer.DrawSprite(shimSprites[4], new float2(origin.X + 64 * i, origin.Y - 1 + 48 * y), PaletteType.Chrome);
} }
rgbaRenderer.DrawSprite(SequenceProvider.GetImageFromCollection(renderer, paletteCollection, "dock-bottom"), new float2(Game.viewport.Width - 14, origin.Y - 1 + 48 * y), PaletteType.Chrome);
rgbaRenderer.Flush(); rgbaRenderer.Flush();
if (tooltipItem != null) if (tooltipItem != null)
DrawProductionTooltip(tooltipItem, new int2(Game.viewport.Width, origin.Y + y * 48 + 9)/*tooltipPos*/); DrawProductionTooltip(tooltipItem, new float2(Game.viewport.Width, origin.Y + y * 48 + 9).ToInt2()/*tooltipPos*/);
return y*48+9; return y*48+9;
} }
@@ -637,6 +726,7 @@ namespace OpenRa.Game
void DrawProductionTooltip(string unit, int2 pos) void DrawProductionTooltip(string unit, int2 pos)
{ {
var tooltipSprite = SequenceProvider.GetImageFromCollection(renderer, chromeCollection, "tooltip-bg");
var p = pos.ToFloat2() - new float2(tooltipSprite.size.X, 0); var p = pos.ToFloat2() - new float2(tooltipSprite.size.X, 0);
rgbaRenderer.DrawSprite(tooltipSprite, p, PaletteType.Chrome); rgbaRenderer.DrawSprite(tooltipSprite, p, PaletteType.Chrome);
rgbaRenderer.Flush(); rgbaRenderer.Flush();
@@ -681,10 +771,10 @@ namespace OpenRa.Game
if (numPowers == 0) return; if (numPowers == 0) return;
rgbaRenderer.DrawSprite(specialBinSprites[0], new float2(0,14), PaletteType.Chrome); rgbaRenderer.DrawSprite(SequenceProvider.GetImageFromCollection(renderer, chromeCollection, "specialbin-top"), new float2(0, 14), PaletteType.Chrome);
for (var i = 1; i < numPowers; i++) for (var i = 1; i < numPowers; i++)
rgbaRenderer.DrawSprite(specialBinSprites[1], new float2(0, 14 + i * 51), PaletteType.Chrome); rgbaRenderer.DrawSprite(SequenceProvider.GetImageFromCollection(renderer, chromeCollection, "specialbin-middle"), new float2(0, 14 + i * 51), PaletteType.Chrome);
rgbaRenderer.DrawSprite(specialBinSprites[2], new float2(0, 14 + numPowers * 51), PaletteType.Chrome); rgbaRenderer.DrawSprite(SequenceProvider.GetImageFromCollection(renderer, chromeCollection, "specialbin-bottom"), new float2(0, 14 + numPowers * 51), PaletteType.Chrome);
rgbaRenderer.Flush(); rgbaRenderer.Flush();
@@ -750,6 +840,7 @@ namespace OpenRa.Game
void DrawSupportPowerTooltip(string sp, int2 pos) void DrawSupportPowerTooltip(string sp, int2 pos)
{ {
var tooltipSprite = SequenceProvider.GetImageFromCollection(renderer, chromeCollection, "tooltip-bg");
rgbaRenderer.DrawSprite(tooltipSprite, pos, PaletteType.Chrome); rgbaRenderer.DrawSprite(tooltipSprite, pos, PaletteType.Chrome);
rgbaRenderer.Flush(); rgbaRenderer.Flush();

View File

@@ -178,6 +178,7 @@ namespace OpenRa.Game
UpdatePalette(world.Actors.SelectMany( UpdatePalette(world.Actors.SelectMany(
a => a.traits.WithInterface<IPaletteModifier>())); a => a.traits.WithInterface<IPaletteModifier>()));
minimap.Update(); minimap.Update();
chrome.Tick();
orderManager.TickImmediate(); orderManager.TickImmediate();

View File

@@ -0,0 +1,31 @@
using System.Xml;
using System.Drawing;
using Ijw.DirectX;
using System.IO;
namespace OpenRa.Game.Graphics
{
class MappedImage
{
readonly Rectangle rect;
public readonly string Src;
public readonly string Name;
public MappedImage(string defaultSrc, XmlElement e)
{
Src = (e.HasAttribute("src")) ? e.GetAttribute("src") : defaultSrc;
Name = e.GetAttribute("name");
if (Src == null)
throw new InvalidDataException("Image src missing");
rect = new Rectangle(int.Parse(e.GetAttribute("x")),
int.Parse(e.GetAttribute("y")),
int.Parse(e.GetAttribute("width")),
int.Parse(e.GetAttribute("height")));
}
public Sprite GetImage(Renderer r, Sheet s)
{
return new Sprite(s, rect, TextureChannel.Alpha);
}
}
}

View File

@@ -1,4 +1,5 @@
using System.Drawing; using System;
using System.Drawing;
using System.Linq; using System.Linq;
using OpenRa.Game.Traits; using OpenRa.Game.Traits;
using OpenRa.FileFormats; using OpenRa.FileFormats;
@@ -10,36 +11,32 @@ namespace OpenRa.Game.Graphics
{ {
Sheet sheet; Sheet sheet;
SpriteRenderer rgbaRenderer; SpriteRenderer rgbaRenderer;
SpriteRenderer shpRenderer;
Sprite sprite; Sprite sprite;
Bitmap terrain, oreLayer; Bitmap terrain, oreLayer;
Animation radarAnim, alliesAnim, sovietAnim; const int alpha = 230;
public void Tick() { } public void Tick() { }
public Minimap(Renderer r) public Minimap(Renderer r)
{ {
sheet = new Sheet(r, new Size(128, 128)); sheet = new Sheet(r, new Size(128, 128));
shpRenderer = new SpriteRenderer(r, true);
rgbaRenderer = new SpriteRenderer(r, true, r.RgbaSpriteShader);
sprite = new Sprite(sheet, new Rectangle(0, 0, 128, 128), TextureChannel.Alpha);
sovietAnim = new Animation("ussrradr"); rgbaRenderer = new SpriteRenderer(r, true, r.RgbaSpriteShader);
sovietAnim.PlayRepeating("idle"); var size = Math.Max(Rules.Map.Width, Rules.Map.Height);
alliesAnim = new Animation("natoradr"); var dw = (size - Rules.Map.Width) / 2;
alliesAnim.PlayRepeating("idle"); var dh = (size - Rules.Map.Height) / 2;
radarAnim = Game.LocalPlayer.Race == Race.Allies ? alliesAnim : sovietAnim;
sprite = new Sprite(sheet, new Rectangle(Rules.Map.Offset.X+dw, Rules.Map.Offset.Y+dh, size, size), TextureChannel.Alpha);
} }
Color[] terrainTypeColors; Color[] terrainTypeColors;
Color[] playerColors;
Color shroudColor;
public void InvalidateOre() { oreLayer = null; } public void InvalidateOre() { oreLayer = null; }
public void Update() public void Update()
{ {
radarAnim = Game.LocalPlayer.Race == Race.Allies ? alliesAnim : sovietAnim;
radarAnim.Tick();
if (!Game.world.Actors.Any(a => a.Owner == Game.LocalPlayer && a.traits.Contains<ProvidesRadar>())) if (!Game.world.Actors.Any(a => a.Owner == Game.LocalPlayer && a.traits.Contains<ProvidesRadar>()))
return; return;
@@ -47,17 +44,20 @@ namespace OpenRa.Game.Graphics
{ {
var pal = new Palette(FileSystem.Open(Rules.Map.Theater + ".pal")); var pal = new Palette(FileSystem.Open(Rules.Map.Theater + ".pal"));
terrainTypeColors = new[] { terrainTypeColors = new[] {
pal.GetColor(0x1a), Color.FromArgb(alpha, pal.GetColor(0x1a)),
pal.GetColor(0x63), Color.FromArgb(alpha, pal.GetColor(0x63)),
pal.GetColor(0x2f), Color.FromArgb(alpha, pal.GetColor(0x2f)),
pal.GetColor(0x1f), Color.FromArgb(alpha, pal.GetColor(0x1f)),
pal.GetColor(0x14), Color.FromArgb(alpha, pal.GetColor(0x14)),
pal.GetColor(0x64), Color.FromArgb(alpha, pal.GetColor(0x64)),
pal.GetColor(0x1f), Color.FromArgb(alpha, pal.GetColor(0x1f)),
pal.GetColor(0x68), Color.FromArgb(alpha, pal.GetColor(0x68)),
pal.GetColor(0x6b), Color.FromArgb(alpha, pal.GetColor(0x6b)),
pal.GetColor(0x6d), Color.FromArgb(alpha, pal.GetColor(0x6d)),
}; };
playerColors = Util.MakeArray<Color>( 8, b => Color.FromArgb(alpha, Chat.paletteColors[b]) );
shroudColor = Color.FromArgb(alpha, Color.Black);
} }
if (terrain == null) if (terrain == null)
@@ -67,7 +67,7 @@ namespace OpenRa.Game.Graphics
for (var x = 0; x < 128; x++) for (var x = 0; x < 128; x++)
terrain.SetPixel(x, y, Rules.Map.IsInMap(x, y) terrain.SetPixel(x, y, Rules.Map.IsInMap(x, y)
? terrainTypeColors[Rules.TileSet.GetWalkability(Rules.Map.MapTiles[x, y])] ? terrainTypeColors[Rules.TileSet.GetWalkability(Rules.Map.MapTiles[x, y])]
: Color.Black); : shroudColor);
} }
if (oreLayer == null) if (oreLayer == null)
@@ -92,19 +92,19 @@ namespace OpenRa.Game.Graphics
{ {
var b = Game.BuildingInfluence.GetBuildingAt(new int2(x, y)); var b = Game.BuildingInfluence.GetBuildingAt(new int2(x, y));
if (b != null) if (b != null)
*(c + (y * bitmapData.Stride >> 2) + x) = *(c + (y * bitmapData.Stride >> 2) + x) =
(b.Owner != null ? Chat.paletteColors[(int)b.Owner.Palette] : terrainTypeColors[4]).ToArgb(); (b.Owner != null ? playerColors[(int)b.Owner.Palette] : terrainTypeColors[4]).ToArgb();
} }
foreach (var a in Game.world.Actors.Where(a => a.traits.Contains<Unit>())) foreach (var a in Game.world.Actors.Where(a => a.traits.Contains<Unit>()))
*(c + (a.Location.Y * bitmapData.Stride >> 2) + a.Location.X) = Chat.paletteColors[(int)a.Owner.Palette].ToArgb(); *(c + (a.Location.Y * bitmapData.Stride >> 2) + a.Location.X) = Chat.paletteColors[(int)a.Owner.Palette].ToArgb();
unchecked unchecked
{ {
for (var y = 0; y < 128; y++) for (var y = 0; y < 128; y++)
for (var x = 0; x < 128; x++) for (var x = 0; x < 128; x++)
if (!Game.LocalPlayer.Shroud.IsExplored(new int2(x, y))) if (!Game.LocalPlayer.Shroud.IsExplored(new int2(x, y)))
*(c + (y * bitmapData.Stride >> 2) + x) = (int)0xff000000; *(c + (y * bitmapData.Stride >> 2) + x) = shroudColor.ToArgb();
} }
} }
@@ -112,27 +112,10 @@ namespace OpenRa.Game.Graphics
sheet.Texture.SetData(bitmap); sheet.Texture.SetData(bitmap);
} }
public void Draw(float2 pos, bool hasRadar, bool isJammed) public void Draw(RectangleF rect, bool hasRadar, bool isJammed)
{ {
if (hasRadar && radarAnim.CurrentSequence.Name == "idle") rgbaRenderer.DrawSprite(sprite, new float2(rect.X, rect.Y), PaletteType.Chrome, new float2(rect.Width, rect.Height));
radarAnim.PlayThen("open", () => radarAnim.PlayRepeating("active")); rgbaRenderer.Flush();
if (hasRadar && radarAnim.CurrentSequence.Name == "no-power")
radarAnim.PlayBackwardsThen("close", () => radarAnim.PlayRepeating("active"));
if (!hasRadar && radarAnim.CurrentSequence.Name == "active")
radarAnim.PlayThen("close", () => radarAnim.PlayRepeating("no-power"));
if (isJammed && radarAnim.CurrentSequence.Name == "active")
radarAnim.PlayRepeating("jammed");
if (!isJammed && radarAnim.CurrentSequence.Name == "jammed")
radarAnim.PlayRepeating("active");
shpRenderer.DrawSprite(radarAnim.Image, pos + Game.viewport.Location - new float2( 290-256,0), PaletteType.Chrome, new float2(290, 272));
shpRenderer.Flush();
if (radarAnim.CurrentSequence.Name == "active")
{
rgbaRenderer.DrawSprite(sprite, pos - new float2((290-256)/2, -5), PaletteType.Chrome, new float2(256, 256));
rgbaRenderer.Flush();
}
} }
} }
} }

View File

@@ -10,15 +10,25 @@ namespace OpenRa.Game.Graphics
{ {
static Dictionary<string, Dictionary<string, Sequence>> units; static Dictionary<string, Dictionary<string, Sequence>> units;
static Dictionary<string, CursorSequence> cursors; static Dictionary<string, CursorSequence> cursors;
static Dictionary<string, Dictionary<string, MappedImage>> collections;
static Dictionary<string, Sheet> cachedSheets;
static Dictionary<string, Dictionary<string, Sprite>> cachedSprites;
public static void Initialize( bool useAftermath ) public static void Initialize( bool useAftermath )
{ {
units = new Dictionary<string, Dictionary<string, Sequence>>(); units = new Dictionary<string, Dictionary<string, Sequence>>();
cursors = new Dictionary<string, CursorSequence>(); cursors = new Dictionary<string, CursorSequence>();
collections = new Dictionary<string, Dictionary<string, MappedImage>>();
cachedSheets = new Dictionary<string, Sheet>();
cachedSprites = new Dictionary<string, Dictionary<string, Sprite>>();
LoadSequenceSource("sequences.xml"); LoadSequenceSource("sequences.xml");
if (useAftermath) if (useAftermath)
LoadSequenceSource("sequences-aftermath.xml"); LoadSequenceSource("sequences-aftermath.xml");
LoadChromeSource("chrome.xml");
} }
static void LoadSequenceSource(string filename) static void LoadSequenceSource(string filename)
@@ -32,7 +42,27 @@ namespace OpenRa.Game.Graphics
foreach (XmlElement eCursor in document.SelectNodes("/sequences/cursor")) foreach (XmlElement eCursor in document.SelectNodes("/sequences/cursor"))
LoadSequencesForCursor(eCursor); LoadSequencesForCursor(eCursor);
} }
static void LoadChromeSource(string filename)
{
XmlDocument document = new XmlDocument();
document.Load(FileSystem.Open(filename));
foreach (XmlElement eCollection in document.SelectNodes("/chrome/collection"))
LoadChromeForCollection(eCollection);
}
static void LoadChromeForCollection(XmlElement eCollection)
{
string elementName = eCollection.GetAttribute("name");
string defaultSrc = (eCollection.HasAttribute("src") ? eCollection.GetAttribute("src") : null);
var images = eCollection.SelectNodes("./image").OfType<XmlElement>()
.Select(e => new MappedImage(defaultSrc, e))
.ToDictionary(s => s.Name);
collections.Add(elementName, images);
}
static void LoadSequencesForCursor(XmlElement eCursor) static void LoadSequencesForCursor(XmlElement eCursor)
{ {
string cursorSrc = eCursor.GetAttribute("src"); string cursorSrc = eCursor.GetAttribute("src");
@@ -73,5 +103,40 @@ namespace OpenRa.Game.Graphics
{ {
return cursors[cursor]; return cursors[cursor];
} }
public static Sprite GetImageFromCollection(Renderer renderer,string collection, string image)
{
// Cached sprite
if (cachedSprites.ContainsKey(collection) && cachedSprites[collection].ContainsKey(image))
return cachedSprites[collection][image];
MappedImage mi;
try { mi = collections[collection][image];}
catch (KeyNotFoundException)
{
throw new InvalidOperationException(
"Collection `{0}` does not have an image `{1}`".F(collection, image));
}
// Cached sheet
Sheet sheet;
if (cachedSheets.ContainsKey(mi.Src))
sheet = cachedSheets[mi.Src];
else
{
sheet = new Sheet(renderer, mi.Src);
cachedSheets.Add(mi.Src, sheet);
}
// Cache the sprite
if (!cachedSprites.ContainsKey(collection))
cachedSprites.Add(collection, new Dictionary<string,Sprite>());
cachedSprites[collection].Add(image, mi.GetImage(renderer, sheet));
return cachedSprites[collection][image];
}
} }
} }

View File

@@ -100,6 +100,7 @@
<Compile Include="GameRules\UserSettings.cs" /> <Compile Include="GameRules\UserSettings.cs" />
<Compile Include="GameRules\VoiceInfo.cs" /> <Compile Include="GameRules\VoiceInfo.cs" />
<Compile Include="Effects\IEffect.cs" /> <Compile Include="Effects\IEffect.cs" />
<Compile Include="Graphics\MappedImage.cs" />
<Compile Include="Graphics\Minimap.cs" /> <Compile Include="Graphics\Minimap.cs" />
<Compile Include="Orders\ChronoshiftSelfDestinationOrderGenerator.cs" /> <Compile Include="Orders\ChronoshiftSelfDestinationOrderGenerator.cs" />
<Compile Include="Orders\ChronosphereSelectOrderGenerator.cs" /> <Compile Include="Orders\ChronosphereSelectOrderGenerator.cs" />

View File

@@ -154,5 +154,10 @@ namespace OpenRa.Game
{ {
return new Order("CancelProduction", subject.PlayerActor, null, int2.Zero, item); return new Order("CancelProduction", subject.PlayerActor, null, int2.Zero, item);
} }
public static Order PlayAnimation(Actor actor, string animationString)
{
return new Order("PlayAnimation", actor, null, int2.Zero, animationString);
}
} }
} }

View File

@@ -19,14 +19,14 @@ namespace OpenRa.Game.SupportPowers
Sound.Play("chrono2.aud"); Sound.Play("chrono2.aud");
foreach (var a in Game.world.Actors.Where(a => a.traits.Contains<ChronoshiftPaletteEffect>()))
a.traits.Get<ChronoshiftPaletteEffect>().DoChronoshift();
// Play chronosphere active anim // Play chronosphere active anim
var chronosphere = Game.world.Actors.Where(a => a.Owner == p.Owner && a.traits.Contains<Chronosphere>()).FirstOrDefault(); var chronosphere = Game.world.Actors.Where(a => a.Owner == p.Owner && a.traits.Contains<Chronosphere>()).FirstOrDefault();
if (chronosphere != null) if (chronosphere != null)
chronosphere.traits.Get<RenderBuilding>().PlayCustomAnim(chronosphere, "active"); Game.controller.AddOrder(Order.PlayAnimation(chronosphere, "active"));
// Trigger screen desaturate effect
foreach (var a in Game.world.Actors.Where(a => a.traits.Contains<ChronoshiftPaletteEffect>()))
a.traits.Get<ChronoshiftPaletteEffect>().DoChronoshift();
} }
SupportPower p; SupportPower p;
public void Activate(SupportPower p) public void Activate(SupportPower p)

View File

@@ -29,7 +29,8 @@ namespace OpenRa.Game.SupportPowers
.Where(a => a.Owner == p.Owner && a.traits.Contains<IronCurtain>()) .Where(a => a.Owner == p.Owner && a.traits.Contains<IronCurtain>())
.FirstOrDefault(); .FirstOrDefault();
if (ironCurtain != null) if (ironCurtain != null)
ironCurtain.traits.Get<RenderBuilding>().PlayCustomAnim(ironCurtain, "active"); Game.controller.AddOrder(Order.PlayAnimation(ironCurtain, "active"));
} }
SupportPower p; SupportPower p;
public void Activate(SupportPower p) public void Activate(SupportPower p)

View File

@@ -5,8 +5,18 @@ using System.Text;
namespace OpenRa.Game.Traits namespace OpenRa.Game.Traits
{ {
class Chronosphere class Chronosphere : IResolveOrder
{ {
public Chronosphere(Actor self) { } public Chronosphere(Actor self) { }
public void ResolveOrder(Actor self, Order order)
{
if (order.OrderString == "PlayAnimation")
{
var rb = self.traits.Get<RenderBuilding>();
if (rb != null)
rb.PlayCustomAnim(self, order.TargetString);
}
}
} }
} }

View File

@@ -5,8 +5,18 @@ using System.Text;
namespace OpenRa.Game.Traits namespace OpenRa.Game.Traits
{ {
class IronCurtain class IronCurtain : IResolveOrder
{ {
public IronCurtain(Actor self) {} public IronCurtain(Actor self) {}
public void ResolveOrder(Actor self, Order order)
{
if (order.OrderString == "PlayAnimation")
{
var rb = self.traits.Get<RenderBuilding>();
if (rb != null)
rb.PlayCustomAnim(self, order.TargetString);
}
}
} }
} }

BIN
artsrc/buildpalette.xcf Normal file

Binary file not shown.

BIN
artsrc/chrome.xcf Normal file

Binary file not shown.

BIN
artsrc/tabs.xcf Normal file

Binary file not shown.

BIN
chrome-allies.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

BIN
chrome-soviet.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

125
chrome.xml Normal file
View File

@@ -0,0 +1,125 @@
<chrome>
<collection name="chrome-allies" src="chrome-allies.png">
<image name="specialbin-top" x="0" y="0" width="30" height="51" />
<image name="specialbin-middle" x="0" y="51" width="30" height="51" />
<image name="specialbin-bottom" x="0" y="153" width="30" height="39" />
<image name="moneybin" x="192" y="0" width="320" height="32" />
<image name="tooltip-bg" x="0" y="288" width="272" height="136" />
</collection>
<collection name="radar-allies" src="chrome-allies.png">
<image name="left" x="297" y="31" width="9" height="192" />
<image name="right" x="498" y="31" width="9" height="192" />
<image name="bottom" x="297" y="223" width="210" height="30" />
<image name="bg" x="306" y="31" width="192" height="192" />
<image name="power-indicator" x="187" y="4" width="4" height="7" />
</collection>
<collection name="palette-allies" src="chrome-allies.png">
<image name="top" x="297" y="288" width="201" height="9" />
<image name="dock-top" x="498" y="274" width="14" height="23" />
<image name="bottom" x="297" y="489" width="201" height="9" />
<image name="dock-bottom" x="498" y="489" width="14" height="23" />
<image name="bg-0" x="297" y="297" width="201" height="48" />
<image name="dock-0" x="498" y="297" width="14" height="48" />
<image name="bg-1" x="297" y="345" width="201" height="48" />
<image name="dock-1" x="498" y="345" width="14" height="48" />
<image name="bg-2" x="297" y="393" width="201" height="48" />
<image name="dock-2" x="498" y="393" width="14" height="48" />
<image name="bg-3" x="297" y="441" width="201" height="48" />
<image name="dock-3" x="498" y="441" width="14" height="48" />
</collection>
<collection name="digits-allies" src="chrome-allies.png">
<image name="0" x="32" y="0" width="13" height="17" />
<image name="1" x="45" y="0" width="13" height="17" />
<image name="2" x="58" y="0" width="13" height="17" />
<image name="3" x="71" y="0" width="13" height="17" />
<image name="4" x="84" y="0" width="13" height="17" />
<image name="5" x="97" y="0" width="13" height="17" />
<image name="6" x="110" y="0" width="13" height="17" />
<image name="7" x="123" y="0" width="13" height="17" />
<image name="8" x="136" y="0" width="13" height="17" />
<image name="9" x="149" y="0" width="13" height="17" />
</collection>
<collection name="chrome-soviet" src="chrome-soviet.png">
<image name="specialbin-top" x="0" y="0" width="30" height="51" />
<image name="specialbin-middle" x="0" y="51" width="30" height="51" />
<image name="specialbin-bottom" x="0" y="153" width="30" height="39" />
<image name="moneybin" x="192" y="0" width="320" height="32" />
<image name="tooltip-bg" x="0" y="288" width="272" height="136" />
</collection>
<collection name="radar-soviet" src="chrome-soviet.png">
<image name="left" x="297" y="31" width="9" height="192" />
<image name="right" x="498" y="31" width="9" height="192" />
<image name="bottom" x="297" y="223" width="210" height="30" />
<image name="bg" x="306" y="31" width="192" height="192" />
<image name="power-indicator" x="187" y="4" width="4" height="7" />
</collection>
<collection name="palette-soviet" src="chrome-soviet.png">
<image name="top" x="297" y="288" width="201" height="9" />
<image name="dock-top" x="498" y="274" width="14" height="23" />
<image name="bottom" x="297" y="489" width="201" height="9" />
<image name="dock-bottom" x="498" y="489" width="14" height="23" />
<image name="bg-0" x="297" y="297" width="201" height="48" />
<image name="dock-0" x="498" y="297" width="14" height="48" />
<image name="bg-1" x="297" y="345" width="201" height="48" />
<image name="dock-1" x="498" y="345" width="14" height="48" />
<image name="bg-2" x="297" y="393" width="201" height="48" />
<image name="dock-2" x="498" y="393" width="14" height="48" />
<image name="bg-3" x="297" y="441" width="201" height="48" />
<image name="dock-3" x="498" y="441" width="14" height="48" />
</collection>
<collection name="digits-soviet" src="chrome-soviet.png">
<image name="0" x="32" y="0" width="13" height="17" />
<image name="1" x="45" y="0" width="13" height="17" />
<image name="2" x="58" y="0" width="13" height="17" />
<image name="3" x="71" y="0" width="13" height="17" />
<image name="4" x="84" y="0" width="13" height="17" />
<image name="5" x="97" y="0" width="13" height="17" />
<image name="6" x="110" y="0" width="13" height="17" />
<image name="7" x="123" y="0" width="13" height="17" />
<image name="8" x="136" y="0" width="13" height="17" />
<image name="9" x="149" y="0" width="13" height="17" />
</collection>
<collection name="tabs-selected" src="tabs.png">
<image name="allies-Building" x="0" y="0" width="27" height="41" />
<image name="allies-Defense" x="0" y="40" width="27" height="41" />
<image name="allies-Infantry" x="0" y="80" width="27" height="41" />
<image name="allies-Vehicle" x="0" y="120" width="27" height="41" />
<image name="allies-Plane" x="0" y="160" width="27" height="41" />
<image name="allies-Ship" x="0" y="200" width="27" height="41" />
<image name="soviet-Building" x="80" y="0" width="27" height="41" />
<image name="soviet-Defense" x="80" y="40" width="27" height="41" />
<image name="soviet-Infantry" x="80" y="80" width="27" height="41" />
<image name="soviet-Vehicle" x="80" y="120" width="27" height="41" />
<image name="soviet-Plane" x="80" y="160" width="27" height="41" />
<image name="soviet-Ship" x="80" y="200" width="27" height="41" />
</collection>
<collection name="tabs-ready" src="tabs.png">
<image name="allies-Building" x="27" y="0" width="27" height="41" />
<image name="allies-Defense" x="27" y="40" width="27" height="41" />
<image name="allies-Infantry" x="27" y="80" width="27" height="41" />
<image name="allies-Vehicle" x="27" y="120" width="27" height="41" />
<image name="allies-Plane" x="27" y="160" width="27" height="41" />
<image name="allies-Ship" x="27" y="200" width="27" height="41" />
<image name="soviet-Building" x="107" y="0" width="27" height="41" />
<image name="soviet-Defense" x="107" y="40" width="27" height="41" />
<image name="soviet-Infantry" x="107" y="80" width="27" height="41" />
<image name="soviet-Vehicle" x="107" y="120" width="27" height="41" />
<image name="soviet-Plane" x="107" y="160" width="27" height="41" />
<image name="soviet-Ship" x="107" y="200" width="27" height="41" />
</collection>
<collection name="tabs-normal" src="tabs.png">
<image name="allies-Building" x="54" y="0" width="27" height="41" />
<image name="allies-Defense" x="54" y="40" width="27" height="41" />
<image name="allies-Infantry" x="54" y="80" width="27" height="41" />
<image name="allies-Vehicle" x="54" y="120" width="27" height="41" />
<image name="allies-Plane" x="54" y="160" width="27" height="41" />
<image name="allies-Ship" x="54" y="200" width="27" height="41" />
<image name="soviet-Building" x="134" y="0" width="27" height="41" />
<image name="soviet-Defense" x="134" y="40" width="27" height="41" />
<image name="soviet-Infantry" x="134" y="80" width="27" height="41" />
<image name="soviet-Vehicle" x="134" y="120" width="27" height="41" />
<image name="soviet-Plane" x="134" y="160" width="27" height="41" />
<image name="soviet-Ship" x="134" y="200" width="27" height="41" />
</collection>
</chrome>

View File

@@ -1010,13 +1010,6 @@
<unit name="select"> <unit name="select">
<sequence name="repair" start="2" length="1" /> <sequence name="repair" start="2" length="1" />
</unit> </unit>
<unit name="power">
<sequence name="power-level-indicator" start="0" length="1" />
</unit>
<unit name="powerbar">
<sequence name="powerbar-top" start="0" length="1" />
<sequence name="powerbar-bottom" start="1" length="1" />
</unit>
<unit name="repair"> <unit name="repair">
<sequence name="normal" start="0" length="1" /> <sequence name="normal" start="0" length="1" />
<sequence name="pressed" start="1" length="1" /> <sequence name="pressed" start="1" length="1" />
@@ -1041,20 +1034,4 @@
<sequence name="bottom-left" start="2" length="1" /> <sequence name="bottom-left" start="2" length="1" />
<sequence name="bottom-right" start="3" length="1" /> <sequence name="bottom-right" start="3" length="1" />
</unit> </unit>
<unit name="ussrradr">
<sequence name="idle" start="0" length="1" />
<sequence name="open" start="1" length="20" />
<sequence name="jammed" start="21" length="4" />
<sequence name="close" start="25" length="16" />
<sequence name="no-power" start="41" length="1" />
<sequence name="active" start="42" length="1" />
</unit>
<unit name="natoradr">
<sequence name="idle" start="0" length="1" />
<sequence name="open" start="1" length="20" />
<sequence name="active" start="42" length="1" />
<sequence name="jammed" start="21" length="4" />
<sequence name="close" start="25" length="16" />
<sequence name="no-power" start="41" length="1" />
</unit>
</sequences> </sequences>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

BIN
tabs.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB