Selectively power-up/down buildings via chrome

This commit is contained in:
Paul Chote
2010-01-04 21:04:57 +13:00
parent 3b0fd0e22c
commit 88c3e21ed0
10 changed files with 115 additions and 13 deletions

View File

@@ -26,6 +26,7 @@ namespace OpenRa.Game
readonly Animation repairButton; readonly Animation repairButton;
readonly Animation sellButton; readonly Animation sellButton;
readonly Animation pwrdownButton;
readonly SpriteRenderer buildPaletteRenderer; readonly SpriteRenderer buildPaletteRenderer;
readonly Animation cantBuild; readonly Animation cantBuild;
@@ -77,6 +78,9 @@ namespace OpenRa.Game
sellButton = new Animation("sell"); sellButton = new Animation("sell");
sellButton.PlayRepeating("normal"); sellButton.PlayRepeating("normal");
pwrdownButton = new Animation("repair");
pwrdownButton.PlayRepeating("normal");
blank = SheetBuilder.Add(new Size(64, 48), 16); blank = SheetBuilder.Add(new Size(64, 48), 16);
@@ -285,7 +289,7 @@ namespace OpenRa.Game
// Repair // Repair
Rectangle repairRect = new Rectangle(Game.viewport.Width - 100, 5, repairButton.Image.bounds.Width, repairButton.Image.bounds.Height); Rectangle repairRect = new Rectangle(Game.viewport.Width - 120, 5, 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>());
@@ -300,7 +304,7 @@ namespace OpenRa.Game
buildPaletteRenderer.DrawSprite(repairButton.Image, repairDrawPos, PaletteType.Chrome); buildPaletteRenderer.DrawSprite(repairButton.Image, repairDrawPos, PaletteType.Chrome);
// Sell // Sell
Rectangle sellRect = new Rectangle(Game.viewport.Width - 60, 5, Rectangle sellRect = new Rectangle(Game.viewport.Width - 80, 5,
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);
@@ -310,6 +314,21 @@ namespace OpenRa.Game
AddButton(sellRect, isLmb => Game.controller.ToggleInputMode<SellOrderGenerator>()); AddButton(sellRect, isLmb => Game.controller.ToggleInputMode<SellOrderGenerator>());
buildPaletteRenderer.DrawSprite(sellButton.Image, sellDrawPos, PaletteType.Chrome); buildPaletteRenderer.DrawSprite(sellButton.Image, sellDrawPos, PaletteType.Chrome);
buildPaletteRenderer.Flush(); buildPaletteRenderer.Flush();
if (Game.Settings.PowerDownBuildings)
{
// Power Down
Rectangle pwrdownRect = new Rectangle(Game.viewport.Width - 40, 5,
pwrdownButton.Image.bounds.Width, pwrdownButton.Image.bounds.Height);
var pwrdownDrawPos = Game.viewport.Location + new float2(pwrdownRect.Location);
pwrdownButton.ReplaceAnim(Game.controller.orderGenerator is PowerDownOrderGenerator ? "pressed" : "normal");
AddButton(pwrdownRect, isLmb => Game.controller.ToggleInputMode<PowerDownOrderGenerator>());
buildPaletteRenderer.DrawSprite(pwrdownButton.Image, pwrdownDrawPos, PaletteType.Chrome);
}
buildPaletteRenderer.Flush();
} }
void HandleChronosphereButton() void HandleChronosphereButton()

View File

@@ -32,5 +32,6 @@ namespace OpenRa.Game
public static Cursor SellBlocked { get { return new Cursor("sell-blocked"); } } public static Cursor SellBlocked { get { return new Cursor("sell-blocked"); } }
public static Cursor Repair { get { return new Cursor("repair"); } } public static Cursor Repair { get { return new Cursor("repair"); } }
public static Cursor RepairBlocked { get { return new Cursor("repair-blocked"); } } public static Cursor RepairBlocked { get { return new Cursor("repair-blocked"); } }
public static Cursor PowerDown { get { return new Cursor("powerdown"); } }
} }
} }

View File

@@ -27,6 +27,7 @@ namespace OpenRa.Game.GameRules
// Gameplay options // Gameplay options
public readonly bool RepairRequiresConyard = true; public readonly bool RepairRequiresConyard = true;
public readonly bool PowerDownBuildings = true;
} }
} }

View File

@@ -11,8 +11,16 @@ namespace OpenRa.Game.Graphics
static Sprite[] LoadCursors(string filename) static Sprite[] LoadCursors(string filename)
{ {
var shp = new Dune2ShpReader(FileSystem.OpenWithExts(filename, exts)); try
return shp.Select(a => SheetBuilder.Add(a.Image, a.Size)).ToArray(); {
var shp = new Dune2ShpReader(FileSystem.OpenWithExts(filename, exts));
return shp.Select(a => SheetBuilder.Add(a.Image, a.Size)).ToArray();
}
catch (System.IndexOutOfRangeException) // This will occur when loading a custom (RA-format) .shp
{
var shp = new ShpReader(FileSystem.OpenWithExts(filename, exts));
return shp.Select(a => SheetBuilder.Add(a.Image, shp.Size)).ToArray();
}
} }
public static Sprite[] LoadAllSprites(string filename) { return cursors[filename]; } public static Sprite[] LoadAllSprites(string filename) { return cursors[filename]; }

View File

@@ -103,6 +103,7 @@
<Compile Include="Orders\NetworkOrderSource.cs" /> <Compile Include="Orders\NetworkOrderSource.cs" />
<Compile Include="Orders\OrderIO.cs" /> <Compile Include="Orders\OrderIO.cs" />
<Compile Include="Orders\OrderManager.cs" /> <Compile Include="Orders\OrderManager.cs" />
<Compile Include="Orders\PowerDownOrderGenerator.cs" />
<Compile Include="Orders\RepairOrderGenerator.cs" /> <Compile Include="Orders\RepairOrderGenerator.cs" />
<Compile Include="Orders\SellOrderGenerator.cs" /> <Compile Include="Orders\SellOrderGenerator.cs" />
<Compile Include="Orders\ChronoshiftDestinationOrderGenerator.cs" /> <Compile Include="Orders\ChronoshiftDestinationOrderGenerator.cs" />

View File

@@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OpenRa.Game.GameRules;
using OpenRa.Game.Traits;
namespace OpenRa.Game.Orders
{
class PowerDownOrderGenerator : IOrderGenerator
{
public IEnumerable<Order> Order(int2 xy, MouseInput mi)
{
if (mi.Button == MouseButton.Right)
Game.controller.CancelInputMode();
return OrderInner(xy, mi);
}
IEnumerable<Order> OrderInner(int2 xy, MouseInput mi)
{
if (mi.Button == MouseButton.Left)
{
var loc = mi.Location + Game.viewport.Location;
var underCursor = Game.FindUnits(loc, loc)
.Where(a => a.Owner == Game.LocalPlayer
&& a.traits.Contains<Building>()
&& a.Info.Selectable).FirstOrDefault();
var building = underCursor != null ? underCursor.Info as BuildingInfo : null;
if (building != null)
yield return new Order("PowerDown", underCursor, null, int2.Zero, null);
}
}
public void Tick() { }
public void Render() { }
public Cursor GetCursor(int2 xy, MouseInput mi)
{
mi.Button = MouseButton.Left;
return OrderInner(xy, mi).Any()
? Cursor.PowerDown : Cursor.PowerDown;
}
}
}

View File

@@ -1,5 +1,6 @@
using System; using System;
using System.Linq; using System.Linq;
using System.Collections.Generic;
using OpenRa.Game.GameRules; using OpenRa.Game.GameRules;
using OpenRa.Game.Graphics; using OpenRa.Game.Graphics;
using OpenRa.Game.Traits; using OpenRa.Game.Traits;
@@ -52,11 +53,11 @@ namespace OpenRa.Game
foreach (var a in myBuildings) foreach (var a in myBuildings)
{ {
var bi = a.Info as BuildingInfo; var p = a.traits.Get<Building>().GetPowerUsage();
if (bi.Power > 0) /* todo: is this how real-ra scales it? */ if (p > 0)
PowerProvided += (a.Health * bi.Power) / bi.Strength; PowerProvided += p;
else else
PowerDrained -= bi.Power; PowerDrained -= p;
} }
if (PowerProvided - PowerDrained < 0) if (PowerProvided - PowerDrained < 0)

View File

@@ -26,12 +26,9 @@ namespace OpenRa.Game.Traits
protected override void QueueAttack( Actor self, Order order ) protected override void QueueAttack( Actor self, Order order )
{ {
var bi = self.Info as BuildingInfo; var bi = self.traits.Get<Building>();
if (bi != null && bi.Powered && self.Owner.GetPowerState() != PowerState.Normal) if (bi != null && !bi.IsActive())
{
if (self.Owner == Game.LocalPlayer) Sound.Play("nopowr1.aud");
return; return;
}
const int RangeTolerance = 1; /* how far inside our maximum range we should try to sit */ const int RangeTolerance = 1; /* how far inside our maximum range we should try to sit */
/* todo: choose the appropriate weapon, when only one works against this target */ /* todo: choose the appropriate weapon, when only one works against this target */

View File

@@ -10,15 +10,34 @@ namespace OpenRa.Game.Traits
{ {
class Building : INotifyDamage, IOrder, ITick class Building : INotifyDamage, IOrder, ITick
{ {
readonly Actor self;
public readonly BuildingInfo unitInfo; public readonly BuildingInfo unitInfo;
bool isRepairing = false; bool isRepairing = false;
bool isPoweredDown = false;
public Building(Actor self) public Building(Actor self)
{ {
this.self = self;
unitInfo = (BuildingInfo)self.Info; unitInfo = (BuildingInfo)self.Info;
self.CenterLocation = Game.CellSize self.CenterLocation = Game.CellSize
* ((float2)self.Location + .5f * (float2)unitInfo.Dimensions); * ((float2)self.Location + .5f * (float2)unitInfo.Dimensions);
} }
public bool IsActive()
{
return !(isPoweredDown || (unitInfo.Powered && self.Owner.GetPowerState() != PowerState.Normal));
}
public int GetPowerUsage()
{
if (isPoweredDown)
return 0;
if (unitInfo.Power > 0) /* todo: is this how real-ra scales it? */
return (self.Health * unitInfo.Power) / unitInfo.Strength;
else
return unitInfo.Power;
}
public void Damaged(Actor self, AttackInfo e) public void Damaged(Actor self, AttackInfo e)
{ {
@@ -43,6 +62,11 @@ namespace OpenRa.Game.Traits
{ {
isRepairing = !isRepairing; isRepairing = !isRepairing;
} }
if (order.OrderString == "PowerDown")
{
isPoweredDown = !isPoweredDown;
}
} }
int remainingTicks; int remainingTicks;

View File

@@ -401,6 +401,9 @@
<sequence name="repair2-blocked" start="213" length="1" /> <sequence name="repair2-blocked" start="213" length="1" />
<sequence name="ability-minimap" start="214" length="8" /> <sequence name="ability-minimap" start="214" length="8" />
</cursor> </cursor>
<cursor src="speed">
<sequence name="powerdown" start="3" length="12" />
</cursor>
<unit name="120mm"> <unit name="120mm">
<sequence name="idle" start="0" length="1" /> <sequence name="idle" start="0" length="1" />
</unit> </unit>