Compare commits
91 Commits
playtest-2
...
playtest-2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c85dbfb53d | ||
|
|
d6c71c6618 | ||
|
|
7802931e54 | ||
|
|
14737cc1dc | ||
|
|
d8d33811e4 | ||
|
|
c99f89c987 | ||
|
|
7c76b25a44 | ||
|
|
4fdc8222e8 | ||
|
|
07d2e54bcc | ||
|
|
f3d0e4b8ed | ||
|
|
2fad6f3bf1 | ||
|
|
9482955a83 | ||
|
|
9d75c8d820 | ||
|
|
e3925b752d | ||
|
|
f990006587 | ||
|
|
0b7bee480c | ||
|
|
05f4aeea9f | ||
|
|
5f37b9e7d2 | ||
|
|
734b464de3 | ||
|
|
4206cf1b09 | ||
|
|
17e3ef131c | ||
|
|
2c13ebc6e7 | ||
|
|
4f3b16cab2 | ||
|
|
25ebdea758 | ||
|
|
8b82df8298 | ||
|
|
0298a9e3a9 | ||
|
|
f2f60fb1f7 | ||
|
|
b07eb9b8a1 | ||
|
|
f5bffc4da9 | ||
|
|
55d60bd466 | ||
|
|
c2a945b7ed | ||
|
|
48b7cdad44 | ||
|
|
c7500084df | ||
|
|
d1850e8b4b | ||
|
|
c465a58976 | ||
|
|
6b05b2c2f0 | ||
|
|
cd10fb1db0 | ||
|
|
172e1eb295 | ||
|
|
9e16eb513f | ||
|
|
24b322053c | ||
|
|
e52771c367 | ||
|
|
76f792bfdf | ||
|
|
c6fad7fe98 | ||
|
|
915cb589b3 | ||
|
|
664692cef9 | ||
|
|
220579ff85 | ||
|
|
1a8e964c04 | ||
|
|
3a309ec916 | ||
|
|
d46c64fad5 | ||
|
|
3f47715c36 | ||
|
|
94715a1561 | ||
|
|
a752c47b5a | ||
|
|
4d0535daa9 | ||
|
|
a3e64d1733 | ||
|
|
2618a7dadc | ||
|
|
5617465294 | ||
|
|
9c20fba4a0 | ||
|
|
05718f9e8e | ||
|
|
81dad0bd34 | ||
|
|
c177cf9f9a | ||
|
|
e1761d8969 | ||
|
|
0ae464d1f7 | ||
|
|
4913d82bce | ||
|
|
4f6027e772 | ||
|
|
fa84cfb26e | ||
|
|
971287e989 | ||
|
|
deed6c7267 | ||
|
|
f58f460355 | ||
|
|
2c897d4454 | ||
|
|
b4101c03ee | ||
|
|
200e90a590 | ||
|
|
be8f042e49 | ||
|
|
4b1eb993e4 | ||
|
|
f6ce673345 | ||
|
|
08eeec4d99 | ||
|
|
564a4598b9 | ||
|
|
7e25b6e58e | ||
|
|
57f74606f0 | ||
|
|
b44cb9ad57 | ||
|
|
dfd5906d7f | ||
|
|
2e7b5e8712 | ||
|
|
eb8682fd0e | ||
|
|
2d224a207c | ||
|
|
5070a81db4 | ||
|
|
e97dd2ee47 | ||
|
|
da74c6ad23 | ||
|
|
c7f1d08748 | ||
|
|
7850acc6fb | ||
|
|
ec5b9a1150 | ||
|
|
83f67a9d48 | ||
|
|
fb799ad436 |
@@ -143,6 +143,16 @@ namespace OpenRA.Editor
|
||||
{
|
||||
var queue = new Queue<int2>();
|
||||
var replace = Map.MapTiles[pos.X, pos.Y];
|
||||
var touched = new bool[Map.MapSize.X, Map.MapSize.Y];
|
||||
|
||||
Action<int, int> MaybeEnqueue = (x, y) =>
|
||||
{
|
||||
if (Map.IsInMap(x, y) && !touched[x, y])
|
||||
{
|
||||
queue.Enqueue(new int2(x, y));
|
||||
touched[x, y] = true;
|
||||
}
|
||||
};
|
||||
|
||||
queue.Enqueue(pos);
|
||||
while (queue.Count > 0)
|
||||
@@ -157,10 +167,10 @@ namespace OpenRA.Editor
|
||||
for (var x = a.X; x <= b.X; x++)
|
||||
{
|
||||
Map.MapTiles[x, p.Y] = new TileReference<ushort, byte> { type = Brush.N, image = (byte)0, index = (byte)0 };
|
||||
if (Map.MapTiles[x, p.Y - 1].Equals(replace) && Map.IsInMap(x, p.Y - 1))
|
||||
queue.Enqueue(new int2(x, p.Y - 1));
|
||||
if (Map.MapTiles[x, p.Y + 1].Equals(replace) && Map.IsInMap(x, p.Y + 1))
|
||||
queue.Enqueue(new int2(x, p.Y + 1));
|
||||
if (Map.MapTiles[x, p.Y - 1].Equals(replace))
|
||||
MaybeEnqueue(x, p.Y - 1);
|
||||
if (Map.MapTiles[x, p.Y + 1].Equals(replace))
|
||||
MaybeEnqueue(x, p.Y + 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ namespace OpenRA.FileFormats
|
||||
[FieldLoader.Load] public bool Selectable;
|
||||
|
||||
[FieldLoader.Load] public string Title;
|
||||
[FieldLoader.Load] public string Type = "Conquest";
|
||||
[FieldLoader.Load] public string Description;
|
||||
[FieldLoader.Load] public string Author;
|
||||
[FieldLoader.Load] public int PlayerCount;
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace OpenRA
|
||||
[Sync]
|
||||
public Player Owner;
|
||||
|
||||
IActivity currentActivity;
|
||||
private IActivity currentActivity;
|
||||
public Group Group;
|
||||
|
||||
internal Actor(World world, string name, TypeDictionary initDict )
|
||||
@@ -77,7 +77,7 @@ namespace OpenRA
|
||||
|
||||
public bool IsIdle
|
||||
{
|
||||
get { return currentActivity == null || currentActivity is Idle; }
|
||||
get { return currentActivity == null; }
|
||||
}
|
||||
|
||||
OpenRA.FileFormats.Lazy<float2> Size;
|
||||
@@ -130,7 +130,6 @@ namespace OpenRA
|
||||
currentActivity.Cancel( this );
|
||||
}
|
||||
|
||||
// For pathdebug, et al
|
||||
public IActivity GetCurrentActivity()
|
||||
{
|
||||
return currentActivity;
|
||||
|
||||
@@ -52,29 +52,36 @@ namespace OpenRA
|
||||
|
||||
public static void JoinServer(string host, int port)
|
||||
{
|
||||
if (orderManager != null) orderManager.Dispose();
|
||||
|
||||
var replayFilename = ChooseReplayFilename();
|
||||
string path = Path.Combine( Game.SupportDir, "Replays" );
|
||||
if( !Directory.Exists( path ) ) Directory.CreateDirectory( path );
|
||||
var replayFile = File.Create( Path.Combine( path, replayFilename ) );
|
||||
|
||||
orderManager = new OrderManager( host, port, new ReplayRecorderConnection( new NetworkConnection( host, port ), replayFile ) );
|
||||
lastConnectionState = ConnectionState.PreConnecting;
|
||||
ConnectionStateChanged(orderManager);
|
||||
}
|
||||
JoinInner(new OrderManager(host, port,
|
||||
new ReplayRecorderConnection(new NetworkConnection(host, port), replayFile)));
|
||||
}
|
||||
|
||||
static string ChooseReplayFilename()
|
||||
{
|
||||
return DateTime.UtcNow.ToString("OpenRA-yyyy-MM-ddThhmmssZ.rep");
|
||||
}
|
||||
|
||||
static void JoinLocal()
|
||||
static void JoinInner(OrderManager om)
|
||||
{
|
||||
if (orderManager != null) orderManager.Dispose();
|
||||
orderManager = new OrderManager("<no server>", -1, new EchoConnection());
|
||||
orderManager = om;
|
||||
lastConnectionState = ConnectionState.PreConnecting;
|
||||
ConnectionStateChanged( orderManager );
|
||||
ConnectionStateChanged(orderManager);
|
||||
}
|
||||
|
||||
public static void JoinReplay(string replayFile)
|
||||
{
|
||||
JoinInner(new OrderManager("<no server>", -1, new ReplayConnection(replayFile)));
|
||||
}
|
||||
|
||||
static void JoinLocal()
|
||||
{
|
||||
JoinInner(new OrderManager("<no server>", -1, new EchoConnection()));
|
||||
}
|
||||
|
||||
public static int RenderFrame = 0;
|
||||
@@ -128,29 +135,33 @@ namespace OpenRA
|
||||
Sound.Tick();
|
||||
Sync.CheckSyncUnchanged( world, () => { orderManager.TickImmediate(); } );
|
||||
|
||||
var isNetTick = LocalTick % NetTickScale == 0;
|
||||
|
||||
if( !isNetTick || orderManager.IsReadyForNextFrame )
|
||||
if (world != null)
|
||||
{
|
||||
++orderManager.LocalFrameNumber;
|
||||
var isNetTick = LocalTick % NetTickScale == 0;
|
||||
|
||||
Log.Write( "debug", "--Tick: {0} ({1})", LocalTick, isNetTick ? "net" : "local" );
|
||||
if (!isNetTick || orderManager.IsReadyForNextFrame)
|
||||
{
|
||||
++orderManager.LocalFrameNumber;
|
||||
|
||||
if( isNetTick ) orderManager.Tick();
|
||||
Log.Write("debug", "--Tick: {0} ({1})", LocalTick, isNetTick ? "net" : "local");
|
||||
|
||||
Sync.CheckSyncUnchanged(world, () =>
|
||||
{
|
||||
world.OrderGenerator.Tick(world);
|
||||
world.Selection.Tick(world);
|
||||
});
|
||||
|
||||
world.Tick();
|
||||
if (isNetTick) orderManager.Tick();
|
||||
|
||||
PerfHistory.Tick();
|
||||
|
||||
Sync.CheckSyncUnchanged(world, () =>
|
||||
{
|
||||
world.OrderGenerator.Tick(world);
|
||||
world.Selection.Tick(world);
|
||||
});
|
||||
|
||||
world.Tick();
|
||||
|
||||
PerfHistory.Tick();
|
||||
}
|
||||
else
|
||||
if (orderManager.NetFrameNumber == 0)
|
||||
orderManager.LastTickTime = Environment.TickCount;
|
||||
}
|
||||
else
|
||||
if( orderManager.NetFrameNumber == 0 )
|
||||
orderManager.LastTickTime = Environment.TickCount;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -56,13 +56,14 @@ namespace OpenRA.Graphics
|
||||
PlayThen( sequenceName, () => PlayRepeating( CurrentSequence.Name ) );
|
||||
}
|
||||
|
||||
public void ReplaceAnim(string sequenceName)
|
||||
public bool ReplaceAnim(string sequenceName)
|
||||
{
|
||||
if (!HasSequence(sequenceName))
|
||||
return;
|
||||
return false;
|
||||
|
||||
CurrentSequence = SequenceProvider.GetSequence(name, sequenceName);
|
||||
frame %= CurrentSequence.Length;
|
||||
return true;
|
||||
}
|
||||
|
||||
public void PlayThen( string sequenceName, Action after )
|
||||
@@ -124,14 +125,15 @@ namespace OpenRA.Graphics
|
||||
}
|
||||
}
|
||||
|
||||
public void ChangeImage(string newImage)
|
||||
public void ChangeImage(string newImage, string newAnimIfMissing)
|
||||
{
|
||||
newImage = newImage.ToLowerInvariant();
|
||||
|
||||
if (name != newImage)
|
||||
{
|
||||
name = newImage.ToLowerInvariant();
|
||||
ReplaceAnim(CurrentSequence.Name);
|
||||
if (!ReplaceAnim(CurrentSequence.Name))
|
||||
ReplaceAnim(newAnimIfMissing);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -78,6 +78,13 @@ namespace OpenRA.Graphics
|
||||
|
||||
terrainRenderer.Draw(this, Game.viewport);
|
||||
|
||||
foreach (var a in world.Selection.Actors)
|
||||
if (!a.Destroyed)
|
||||
foreach (var t in a.TraitsImplementing<IPreRenderSelection>())
|
||||
t.RenderBeforeWorld(this, a);
|
||||
|
||||
Game.Renderer.Flush();
|
||||
|
||||
if (world.OrderGenerator != null)
|
||||
world.OrderGenerator.RenderBeforeWorld(this, world);
|
||||
|
||||
|
||||
@@ -58,6 +58,10 @@ namespace OpenRA
|
||||
this.ExtraLocation = extraLocation;
|
||||
}
|
||||
|
||||
// For scripting special powers
|
||||
public Order()
|
||||
: this(null, null, null, int2.Zero, null, false, int2.Zero) { }
|
||||
|
||||
public Order(string orderString, Actor subject, bool queued)
|
||||
: this(orderString, subject, null, int2.Zero, null, queued, int2.Zero) { }
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ using System.IO;
|
||||
|
||||
namespace OpenRA.Network
|
||||
{
|
||||
static class OrderIO
|
||||
public static class OrderIO
|
||||
{
|
||||
public static void Write(this Stream s, byte[] buf)
|
||||
{
|
||||
|
||||
@@ -6,7 +6,7 @@ using System.IO;
|
||||
|
||||
namespace OpenRA.Network
|
||||
{
|
||||
class ReplayConnection : IConnection
|
||||
public class ReplayConnection : IConnection
|
||||
{
|
||||
//uint nextFrame = 1;
|
||||
FileStream replayStream;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
@@ -118,7 +118,6 @@
|
||||
<Compile Include="Graphics\CursorSheetBuilder.cs" />
|
||||
<Compile Include="Graphics\LineRenderer.cs" />
|
||||
<Compile Include="Graphics\WorldRenderer.cs" />
|
||||
<Compile Include="Traits\Activities\Idle.cs" />
|
||||
<Compile Include="Orders\IOrderGenerator.cs" />
|
||||
<Compile Include="Player.cs" />
|
||||
<Compile Include="Graphics\Sheet.cs" />
|
||||
@@ -225,6 +224,9 @@
|
||||
<ItemGroup>
|
||||
<Content Include="OpenRA.ico" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Widgets\Delegates\" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
|
||||
@@ -65,20 +65,9 @@ namespace OpenRA.Orders
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Tick(World world) { }
|
||||
|
||||
public void RenderBeforeWorld(WorldRenderer wr, World world)
|
||||
{
|
||||
foreach (var a in world.Selection.Actors)
|
||||
if (!a.Destroyed)
|
||||
foreach (var t in a.TraitsImplementing<IPreRenderSelection>())
|
||||
t.RenderBeforeWorld(wr, a);
|
||||
|
||||
Game.Renderer.Flush();
|
||||
}
|
||||
|
||||
public void RenderAfterWorld(WorldRenderer wr, World world) {}
|
||||
|
||||
public virtual void Tick(World world) { }
|
||||
public void RenderBeforeWorld(WorldRenderer wr, World world) { }
|
||||
public void RenderAfterWorld(WorldRenderer wr, World world) { }
|
||||
public string GetCursor(World world, int2 xy, MouseInput mi) { return world.Map.IsInMap(xy) ? cursor : "generic-blocked"; }
|
||||
}
|
||||
|
||||
|
||||
@@ -74,11 +74,6 @@ namespace OpenRA.Orders
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var a in world.Selection.Actors)
|
||||
if (!a.Destroyed)
|
||||
foreach (var t in a.TraitsImplementing<IPreRenderSelection>())
|
||||
t.RenderBeforeWorld( wr, a );
|
||||
|
||||
Game.Renderer.Flush();
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
@@ -171,18 +170,16 @@ namespace OpenRA.Server
|
||||
|
||||
public void UpdateInFlightFrames(Connection conn)
|
||||
{
|
||||
if (conn.Frame != 0)
|
||||
{
|
||||
if (!inFlightFrames.ContainsKey(conn.Frame))
|
||||
inFlightFrames[conn.Frame] = new List<Connection> { conn };
|
||||
else
|
||||
inFlightFrames[conn.Frame].Add(conn);
|
||||
if (conn.Frame == 0)
|
||||
return;
|
||||
|
||||
if (conns.All(c => inFlightFrames[conn.Frame].Contains(c)))
|
||||
{
|
||||
inFlightFrames.Remove(conn.Frame);
|
||||
}
|
||||
}
|
||||
if (!inFlightFrames.ContainsKey(conn.Frame))
|
||||
inFlightFrames[conn.Frame] = new List<Connection> { conn };
|
||||
else
|
||||
inFlightFrames[conn.Frame].Add(conn);
|
||||
|
||||
if (conns.All(c => inFlightFrames[conn.Frame].Contains(c)))
|
||||
inFlightFrames.Remove(conn.Frame);
|
||||
}
|
||||
|
||||
void DispatchOrdersToClient(Connection c, int client, int frame, byte[] data)
|
||||
@@ -266,15 +263,18 @@ namespace OpenRA.Server
|
||||
|
||||
case "Chat":
|
||||
case "TeamChat":
|
||||
var fromClient = GetClient(conn);
|
||||
var fromIndex = fromClient != null ? fromClient.Index : 0;
|
||||
|
||||
foreach (var c in conns.Except(conn).ToArray())
|
||||
DispatchOrdersToClient(c, GetClient(conn).Index, 0, so.Serialize());
|
||||
DispatchOrdersToClient(c, fromIndex, 0, so.Serialize());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public Session.Client GetClient(Connection conn)
|
||||
{
|
||||
return lobbyInfo.Clients.First(c => c.Index == conn.PlayerIndex);
|
||||
return lobbyInfo.ClientWithIndex(conn.PlayerIndex);
|
||||
}
|
||||
|
||||
public void DropClient(Connection toDrop, Exception e)
|
||||
|
||||
@@ -3,7 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace OpenRA.Traits
|
||||
namespace OpenRA.Traits.Activities
|
||||
{
|
||||
public abstract class CancelableActivity : IActivity
|
||||
{
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2010 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see LICENSE.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
namespace OpenRA.Traits.Activities
|
||||
{
|
||||
public class Idle : CancelableActivity
|
||||
{
|
||||
public override IActivity Tick(Actor self) { return NextActivity ?? this; }
|
||||
}
|
||||
}
|
||||
@@ -36,14 +36,13 @@ namespace OpenRA.Traits
|
||||
|
||||
[Sync]
|
||||
public int Cash;
|
||||
[Sync]
|
||||
public int DisplayCash;
|
||||
|
||||
[Sync]
|
||||
public int Ore;
|
||||
[Sync]
|
||||
public int OreCapacity;
|
||||
[Sync]
|
||||
|
||||
public int DisplayCash;
|
||||
public int DisplayOre;
|
||||
|
||||
public float GetSiloFullness() { return (float)Ore / OreCapacity; }
|
||||
|
||||
@@ -24,6 +24,8 @@ namespace OpenRA.Traits
|
||||
|
||||
public Sprite[][] Sprites;
|
||||
public int PaletteIndex;
|
||||
|
||||
public PipType PipColor = PipType.Yellow;
|
||||
|
||||
public object Create(ActorInitializer init) { return new ResourceType(this); }
|
||||
}
|
||||
|
||||
@@ -216,6 +216,11 @@ namespace OpenRA.Traits
|
||||
if (Disabled)
|
||||
return true;
|
||||
|
||||
// Visibility is allowed to extend beyond the map cordon so that
|
||||
// the fog tiles are not visible at the edge of the world
|
||||
if (x < 0 || x >= map.MapSize.X || y < 0 || y >= map.MapSize.Y)
|
||||
return false;
|
||||
|
||||
return visibleCells[x,y] != 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -117,12 +117,11 @@ namespace OpenRA.Widgets
|
||||
|
||||
public static void ShowDropPanel(Widget w, Widget panel, IEnumerable<Widget> dismissAfter, Func<bool> onDismiss)
|
||||
{
|
||||
var fullscreenMask = new ContainerWidget
|
||||
{
|
||||
Bounds = new Rectangle(0, 0, Game.viewport.Width, Game.viewport.Height),
|
||||
ClickThrough = false,
|
||||
Visible = true
|
||||
};
|
||||
var fullscreenMask = new ContainerWidget();
|
||||
// Don't use initializers - breaks on mono 2.6.7
|
||||
fullscreenMask.Bounds = new Rectangle(0, 0, Game.viewport.Width, Game.viewport.Height);
|
||||
fullscreenMask.ClickThrough = false;
|
||||
fullscreenMask.Visible = true;
|
||||
Widget.RootWidget.AddChild(fullscreenMask);
|
||||
|
||||
Action HideDropDown = () =>
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using OpenRA.Graphics;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace OpenRA.Widgets
|
||||
{
|
||||
@@ -24,6 +25,7 @@ namespace OpenRA.Widgets
|
||||
public TextAlign Align = TextAlign.Left;
|
||||
public TextVAlign VAlign = TextVAlign.Middle;
|
||||
public bool Bold = false;
|
||||
public bool WordWrap = false;
|
||||
public Func<string> GetText;
|
||||
public Func<string> GetBackground;
|
||||
|
||||
@@ -58,7 +60,7 @@ namespace OpenRA.Widgets
|
||||
|
||||
int2 textSize = font.Measure(text);
|
||||
int2 position = RenderOrigin;
|
||||
|
||||
|
||||
if (VAlign == TextVAlign.Middle)
|
||||
position += new int2(0, (Bounds.Height - textSize.Y)/2);
|
||||
|
||||
@@ -69,7 +71,58 @@ namespace OpenRA.Widgets
|
||||
position += new int2((Bounds.Width - textSize.X)/2, 0);
|
||||
|
||||
if (Align == TextAlign.Right)
|
||||
position += new int2(Bounds.Width - textSize.X,0);
|
||||
position += new int2(Bounds.Width - textSize.X,0);
|
||||
|
||||
if (WordWrap)
|
||||
{
|
||||
if (textSize.X > Bounds.Width)
|
||||
{
|
||||
string[] lines = text.Split('\n');
|
||||
List<string> newLines = new List<string>();
|
||||
int i = 0;
|
||||
string line = lines[i++];
|
||||
while (true)
|
||||
{
|
||||
newLines.Add(line);
|
||||
int2 m = font.Measure(line);
|
||||
int spaceIndex = 0, start = line.Length - 1;
|
||||
|
||||
if (m.X <= Bounds.Width)
|
||||
{
|
||||
if (i < lines.Length - 1)
|
||||
{
|
||||
line = lines[i++];
|
||||
continue;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
while (m.X > Bounds.Width)
|
||||
{
|
||||
if (-1 == (spaceIndex = line.LastIndexOf(' ', start)))
|
||||
break;
|
||||
start = spaceIndex - 1;
|
||||
m = font.Measure(line.Substring(0, spaceIndex));
|
||||
}
|
||||
|
||||
if (spaceIndex != -1)
|
||||
{
|
||||
newLines.RemoveAt(newLines.Count - 1);
|
||||
newLines.Add(line.Substring(0, spaceIndex));
|
||||
line = line.Substring(spaceIndex + 1);
|
||||
}
|
||||
else if (i < lines.Length - 1)
|
||||
{
|
||||
line = lines[i++];
|
||||
continue;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
text = string.Join("\n", newLines.ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
font.DrawText(text, position, Color.White);
|
||||
}
|
||||
|
||||
@@ -346,11 +346,26 @@ namespace OpenRA.Widgets
|
||||
}
|
||||
|
||||
public class ContainerWidget : Widget {
|
||||
public ContainerWidget() : base() { }
|
||||
public Func<string> GetBackground;
|
||||
public string Background = null;
|
||||
|
||||
public ContainerWidget() : base()
|
||||
{
|
||||
GetBackground = () => Background;
|
||||
}
|
||||
|
||||
public ContainerWidget(ContainerWidget other) : base(other)
|
||||
{
|
||||
Background = other.Background;
|
||||
GetBackground = other.GetBackground;
|
||||
}
|
||||
|
||||
public ContainerWidget(Widget other) : base(other) { }
|
||||
|
||||
public override void DrawInner( WorldRenderer wr ) { }
|
||||
public override void DrawInner( WorldRenderer wr )
|
||||
{
|
||||
var bg = GetBackground();
|
||||
if (bg != null)
|
||||
WidgetUtils.DrawPanel(bg, RenderBounds );
|
||||
}
|
||||
|
||||
public override string GetCursor(int2 pos) { return null; }
|
||||
public override Widget Clone() { return new ContainerWidget(this); }
|
||||
|
||||
@@ -132,7 +132,7 @@ namespace OpenRA.Widgets
|
||||
|
||||
public static string FormatTime(int ticks)
|
||||
{
|
||||
var seconds = ticks / 25;
|
||||
var seconds = (int)Math.Ceiling(ticks / 25f);
|
||||
var minutes = seconds / 60;
|
||||
|
||||
if (minutes >= 60)
|
||||
|
||||
@@ -48,7 +48,8 @@ namespace OpenRA
|
||||
|
||||
public void SetLocalPlayer(int index)
|
||||
{
|
||||
localPlayerIndex = index;
|
||||
if (!(orderManager.Connection is ReplayConnection))
|
||||
localPlayerIndex = index;
|
||||
}
|
||||
|
||||
public readonly Actor WorldActor;
|
||||
|
||||
@@ -101,7 +101,7 @@ namespace OpenRA.Launcher
|
||||
string[] args = e.Argument as string[];
|
||||
string url = args[0];
|
||||
string dest = args[1];
|
||||
var p = UtilityProgram.CallWithAdmin("--download-url", url, dest);
|
||||
var p = UtilityProgram.Call("--download-url", url, dest);
|
||||
Regex r = new Regex(@"(\d{1,3})% (\d+)/(\d+) bytes");
|
||||
|
||||
NamedPipeClientStream pipe = new NamedPipeClientStream(".", "OpenRA.Utility", PipeDirection.In);
|
||||
|
||||
@@ -58,6 +58,7 @@ namespace OpenRA.Launcher
|
||||
Process p = new Process();
|
||||
p.StartInfo.FileName = "OpenRA.Game.exe";
|
||||
p.StartInfo.Arguments = "Game.Mods=" + string.Join(",", modList.ToArray());
|
||||
p.StartInfo.Arguments += " Graphics.Renderer=" + Launcher.Renderer;
|
||||
p.Start();
|
||||
return true;
|
||||
}
|
||||
|
||||
38
OpenRA.Launcher/Launcher.Designer.cs
generated
38
OpenRA.Launcher/Launcher.Designer.cs
generated
@@ -29,13 +29,14 @@
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.Windows.Forms.TreeNode treeNode1 = new System.Windows.Forms.TreeNode("Mods", -2, -2);
|
||||
System.Windows.Forms.TreeNode treeNode2 = new System.Windows.Forms.TreeNode("Broken Mods");
|
||||
this.installButton = new System.Windows.Forms.Button();
|
||||
this.installModDialog = new System.Windows.Forms.OpenFileDialog();
|
||||
this.treeView = new System.Windows.Forms.TreeView();
|
||||
this.splitContainer1 = new System.Windows.Forms.SplitContainer();
|
||||
this.webBrowser = new System.Windows.Forms.WebBrowser();
|
||||
this.panel1 = new System.Windows.Forms.Panel();
|
||||
this.cgButton = new System.Windows.Forms.RadioButton();
|
||||
this.glButton = new System.Windows.Forms.RadioButton();
|
||||
this.splitContainer1.Panel1.SuspendLayout();
|
||||
this.splitContainer1.Panel2.SuspendLayout();
|
||||
this.splitContainer1.SuspendLayout();
|
||||
@@ -67,11 +68,8 @@
|
||||
treeNode1.Name = "ModsNode";
|
||||
treeNode1.SelectedImageIndex = -2;
|
||||
treeNode1.Text = "Mods";
|
||||
treeNode2.Name = "BrokenModsNode";
|
||||
treeNode2.Text = "Broken Mods";
|
||||
this.treeView.Nodes.AddRange(new System.Windows.Forms.TreeNode[] {
|
||||
treeNode1,
|
||||
treeNode2});
|
||||
treeNode1});
|
||||
this.treeView.ShowLines = false;
|
||||
this.treeView.Size = new System.Drawing.Size(160, 465);
|
||||
this.treeView.TabIndex = 3;
|
||||
@@ -107,6 +105,8 @@
|
||||
//
|
||||
// panel1
|
||||
//
|
||||
this.panel1.Controls.Add(this.cgButton);
|
||||
this.panel1.Controls.Add(this.glButton);
|
||||
this.panel1.Controls.Add(this.installButton);
|
||||
this.panel1.Dock = System.Windows.Forms.DockStyle.Bottom;
|
||||
this.panel1.Location = new System.Drawing.Point(0, 465);
|
||||
@@ -114,6 +114,30 @@
|
||||
this.panel1.Size = new System.Drawing.Size(671, 47);
|
||||
this.panel1.TabIndex = 5;
|
||||
//
|
||||
// cgButton
|
||||
//
|
||||
this.cgButton.AutoSize = true;
|
||||
this.cgButton.Location = new System.Drawing.Point(481, 18);
|
||||
this.cgButton.Name = "cgButton";
|
||||
this.cgButton.Size = new System.Drawing.Size(87, 17);
|
||||
this.cgButton.TabIndex = 4;
|
||||
this.cgButton.TabStop = true;
|
||||
this.cgButton.Text = "CG Renderer";
|
||||
this.cgButton.UseVisualStyleBackColor = true;
|
||||
this.cgButton.CheckedChanged += new System.EventHandler(this.rendererChanged);
|
||||
//
|
||||
// glButton
|
||||
//
|
||||
this.glButton.AutoSize = true;
|
||||
this.glButton.Location = new System.Drawing.Point(574, 18);
|
||||
this.glButton.Name = "glButton";
|
||||
this.glButton.Size = new System.Drawing.Size(86, 17);
|
||||
this.glButton.TabIndex = 3;
|
||||
this.glButton.TabStop = true;
|
||||
this.glButton.Text = "GL Renderer";
|
||||
this.glButton.UseVisualStyleBackColor = true;
|
||||
this.glButton.CheckedChanged += new System.EventHandler(this.rendererChanged);
|
||||
//
|
||||
// Launcher
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
@@ -123,7 +147,6 @@
|
||||
this.Controls.Add(this.panel1);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.Name = "Launcher";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||
this.Text = "OpenRA Launcher";
|
||||
@@ -131,6 +154,7 @@
|
||||
this.splitContainer1.Panel2.ResumeLayout(false);
|
||||
this.splitContainer1.ResumeLayout(false);
|
||||
this.panel1.ResumeLayout(false);
|
||||
this.panel1.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
@@ -143,5 +167,7 @@
|
||||
private System.Windows.Forms.SplitContainer splitContainer1;
|
||||
private System.Windows.Forms.Panel panel1;
|
||||
private System.Windows.Forms.WebBrowser webBrowser;
|
||||
private System.Windows.Forms.RadioButton cgButton;
|
||||
private System.Windows.Forms.RadioButton glButton;
|
||||
}
|
||||
}
|
||||
@@ -21,14 +21,15 @@ namespace OpenRA.Launcher
|
||||
public partial class Launcher : Form
|
||||
{
|
||||
Dictionary<string, Mod> allMods;
|
||||
public static string Renderer = "Gl";
|
||||
static string SupportDir = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + Path.DirectorySeparatorChar + "OpenRA";
|
||||
|
||||
public Launcher()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
Util.UacShield(installButton);
|
||||
|
||||
//treeView.Nodes["ModsNode"].ImageIndex = 1;
|
||||
//treeView.Nodes["ModsNode"].SelectedImageIndex = 1;
|
||||
webBrowser.ObjectForScripting = new JSBridge();
|
||||
webBrowser.DocumentCompleted += (o, e) =>
|
||||
{
|
||||
@@ -36,16 +37,17 @@ namespace OpenRA.Launcher
|
||||
(b.ObjectForScripting as JSBridge).Document = b.Document;
|
||||
};
|
||||
RefreshMods();
|
||||
string response = UtilityProgram.CallSimpleResponse("--settings-value", SupportDir, "Graphics.Renderer");
|
||||
if (Util.IsError(ref response) || response.Equals("gl", StringComparison.InvariantCultureIgnoreCase))
|
||||
glButton.Checked = true;
|
||||
else
|
||||
cgButton.Checked = true;
|
||||
}
|
||||
|
||||
Mod GetMetadata(string mod)
|
||||
{
|
||||
string responseString;
|
||||
using (var response = UtilityProgram.Call("-i", mod))
|
||||
{
|
||||
responseString = response.ReadToEnd();
|
||||
}
|
||||
|
||||
string responseString = UtilityProgram.CallSimpleResponse("-i", mod);
|
||||
|
||||
if (Util.IsError(ref responseString)) return null;
|
||||
string[] lines = responseString.Split(new string[] { "\n" }, StringSplitOptions.RemoveEmptyEntries);
|
||||
for (int i = 0; i < lines.Length; i++)
|
||||
@@ -89,11 +91,7 @@ namespace OpenRA.Launcher
|
||||
|
||||
void RefreshMods()
|
||||
{
|
||||
string responseString;
|
||||
using (var response = UtilityProgram.Call("--list-mods"))
|
||||
{
|
||||
responseString = response.ReadToEnd();
|
||||
}
|
||||
string responseString = UtilityProgram.CallSimpleResponse("--list-mods");
|
||||
|
||||
string[] mods;
|
||||
if (!Util.IsError(ref responseString))
|
||||
@@ -167,12 +165,22 @@ namespace OpenRA.Launcher
|
||||
missing.Nodes.Add(new TreeNode(allMods[s].Title)
|
||||
{ ForeColor = SystemColors.GrayText, Name = s });
|
||||
}
|
||||
|
||||
treeView.Nodes["BrokenModsNode"].Nodes.Add(unspecified);
|
||||
treeView.Nodes["BrokenModsNode"].Nodes.Add(missing);
|
||||
string brokenKey = "BrokenModsNode";
|
||||
if (treeView.Nodes[brokenKey] != null)
|
||||
treeView.Nodes.RemoveByKey(brokenKey);
|
||||
treeView.Nodes.Add(brokenKey, "Broken Mods");
|
||||
treeView.Nodes[brokenKey].Nodes.Add(unspecified);
|
||||
treeView.Nodes[brokenKey].Nodes.Add(missing);
|
||||
}
|
||||
treeView.Nodes["ModsNode"].ExpandAll();
|
||||
treeView.Invalidate();
|
||||
|
||||
string responseString = UtilityProgram.CallSimpleResponse("--settings-value", SupportDir, "Game.Mods");
|
||||
|
||||
if (Util.IsError(ref responseString))
|
||||
treeView.SelectedNode = treeView.Nodes["ModsNode"].Nodes["ra"];
|
||||
else
|
||||
treeView.SelectedNode = treeView.Nodes["ModsNode"].Nodes[responseString];
|
||||
}
|
||||
|
||||
void treeView_AfterSelect(object sender, TreeViewEventArgs e)
|
||||
@@ -182,7 +190,14 @@ namespace OpenRA.Launcher
|
||||
string modHtmlPath = string.Format("mods{0}{1}{0}mod.html", Path.DirectorySeparatorChar, e.Node.Name);
|
||||
if (!File.Exists(modHtmlPath)) return;
|
||||
webBrowser.Navigate(Path.GetFullPath(modHtmlPath));
|
||||
|
||||
}
|
||||
|
||||
private void rendererChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (sender == glButton)
|
||||
Renderer = "Gl";
|
||||
else
|
||||
Renderer = "Cg";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ namespace OpenRA.Launcher
|
||||
return arguments.ToString();
|
||||
}
|
||||
|
||||
public static StreamReader Call(string command, params string[] args)
|
||||
public static Process Call(string command, params string[] args)
|
||||
{
|
||||
Process p = new Process();
|
||||
p.StartInfo.FileName = "OpenRA.Utility.exe";
|
||||
@@ -76,9 +76,21 @@ namespace OpenRA.Launcher
|
||||
|
||||
p.Start();
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
public static string CallSimpleResponse(string command, params string[] args)
|
||||
{
|
||||
var p = Call(command, args);
|
||||
string responseString;
|
||||
NamedPipeClientStream pipe = new NamedPipeClientStream(".", "OpenRA.Utility", PipeDirection.In);
|
||||
pipe.Connect();
|
||||
return new StreamReader(pipe);
|
||||
using (var response = new StreamReader(pipe))
|
||||
{
|
||||
responseString = response.ReadToEnd();
|
||||
}
|
||||
|
||||
return responseString;
|
||||
}
|
||||
|
||||
public static Process CallWithAdmin(string command, params string[] args)
|
||||
|
||||
@@ -20,33 +20,16 @@ namespace OpenRA.Mods.Cnc
|
||||
public override object Create(ActorInitializer init) { return new IonCannonPower(init.self, this); }
|
||||
}
|
||||
|
||||
class IonCannonPower : SupportPower, IResolveOrder
|
||||
class IonCannonPower : SupportPower
|
||||
{
|
||||
public IonCannonPower(Actor self, IonCannonPowerInfo info) : base(self, info) { }
|
||||
|
||||
public void ResolveOrder(Actor self, Order order)
|
||||
public override void Activate(Actor self, Order order)
|
||||
{
|
||||
if (!IsReady) return;
|
||||
|
||||
if (order.OrderString == "IonCannon")
|
||||
self.World.AddFrameEndTask(w =>
|
||||
{
|
||||
Owner.World.AddFrameEndTask(w =>
|
||||
{
|
||||
Sound.Play(Info.LaunchSound, Game.CellSize * order.TargetLocation.ToFloat2());
|
||||
w.Add(new IonCannon(self, w, order.TargetLocation));
|
||||
});
|
||||
|
||||
FinishActivate();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnActivate()
|
||||
{
|
||||
Self.World.OrderGenerator =
|
||||
new GenericSelectTargetWithBuilding<IonControl>(Owner.PlayerActor, "IonCannon", "ability");
|
||||
Sound.Play(Info.LaunchSound, Game.CellSize * order.TargetLocation.ToFloat2());
|
||||
w.Add(new IonCannon(self, w, order.TargetLocation));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class IonControlInfo : TraitInfo<IonControl> { }
|
||||
class IonControl { }
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace OpenRA.Mods.RA.Activities
|
||||
/* non-turreted attack */
|
||||
public class Attack : CancelableActivity
|
||||
{
|
||||
Target Target;
|
||||
protected Target Target;
|
||||
ITargetable targetable;
|
||||
int Range;
|
||||
bool AllowMovement;
|
||||
@@ -47,7 +47,7 @@ namespace OpenRA.Mods.RA.Activities
|
||||
return ret;
|
||||
}
|
||||
|
||||
IActivity InnerTick( Actor self, AttackBase attack )
|
||||
protected virtual IActivity InnerTick( Actor self, AttackBase attack )
|
||||
{
|
||||
if (IsCanceled) return NextActivity;
|
||||
var facing = self.Trait<IFacing>();
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
using System.Linq;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Traits.Activities;
|
||||
|
||||
namespace OpenRA.Mods.RA.Activities
|
||||
{
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
using System.Linq;
|
||||
using OpenRA.Effects;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Traits.Activities;
|
||||
|
||||
namespace OpenRA.Mods.RA.Activities
|
||||
{
|
||||
@@ -24,7 +25,6 @@ namespace OpenRA.Mods.RA.Activities
|
||||
{
|
||||
if (IsCanceled) return NextActivity;
|
||||
if (target == null || !target.IsInWorld || target.IsDead()) return NextActivity;
|
||||
if (target.Owner == self.Owner) return NextActivity;
|
||||
|
||||
if( !target.Trait<IOccupySpace>().OccupiedCells().Any( x => x == self.Location ) )
|
||||
return NextActivity;
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#endregion
|
||||
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Traits.Activities;
|
||||
|
||||
namespace OpenRA.Mods.RA.Activities
|
||||
{
|
||||
|
||||
32
OpenRA.Mods.RA/Activities/Heal.cs
Executable file
32
OpenRA.Mods.RA/Activities/Heal.cs
Executable file
@@ -0,0 +1,32 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2010 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see LICENSE.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using OpenRA.Mods.RA.Render;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Traits.Activities;
|
||||
using OpenRA.Mods.RA.Move;
|
||||
|
||||
namespace OpenRA.Mods.RA.Activities
|
||||
{
|
||||
/* non-turreted attack */
|
||||
public class Heal : Attack
|
||||
{
|
||||
public Heal(Target target, int range, bool allowMovement)
|
||||
: base(target, range, allowMovement) {}
|
||||
|
||||
protected override IActivity InnerTick( Actor self, AttackBase attack )
|
||||
{
|
||||
if (Target.IsActor && Target.Actor.GetDamageState() == DamageState.Undamaged)
|
||||
return NextActivity;
|
||||
|
||||
return base.InnerTick(self, attack);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2010 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see LICENSE.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using OpenRA.Mods.RA.Render;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Traits.Activities;
|
||||
|
||||
namespace OpenRA.Mods.RA.Activities
|
||||
{
|
||||
public class IdleAnimation : Idle
|
||||
{
|
||||
string sequence;
|
||||
int delay;
|
||||
|
||||
public IdleAnimation(string sequence, int delay)
|
||||
{
|
||||
this.sequence = sequence;
|
||||
this.delay = delay;
|
||||
}
|
||||
|
||||
bool active = true;
|
||||
public override IActivity Tick(Actor self)
|
||||
{
|
||||
if (!active) return NextActivity;
|
||||
|
||||
if (delay > 0 && --delay == 0)
|
||||
self.Trait<RenderInfantry>().anim.PlayThen(sequence, () => active = false);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
protected override bool OnCancel( Actor self )
|
||||
{
|
||||
active = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
using System.Linq;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Traits.Activities;
|
||||
|
||||
namespace OpenRA.Mods.RA.Activities
|
||||
{
|
||||
|
||||
@@ -10,8 +10,9 @@
|
||||
|
||||
using System.Linq;
|
||||
using OpenRA.Mods.RA.Render;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Mods.RA.Move;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Traits.Activities;
|
||||
|
||||
namespace OpenRA.Mods.RA.Activities
|
||||
{
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
using System.Linq;
|
||||
using OpenRA.Mods.RA.Render;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Traits.Activities;
|
||||
|
||||
namespace OpenRA.Mods.RA.Activities
|
||||
{
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#endregion
|
||||
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Traits.Activities;
|
||||
|
||||
namespace OpenRA.Mods.RA.Activities
|
||||
{
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
using System;
|
||||
using OpenRA.Mods.RA.Render;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Traits.Activities;
|
||||
|
||||
namespace OpenRA.Mods.RA.Activities
|
||||
{
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
using System.Linq;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Traits.Activities;
|
||||
|
||||
namespace OpenRA.Mods.RA.Activities
|
||||
{
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
using System.Linq;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Traits.Activities;
|
||||
|
||||
namespace OpenRA.Mods.RA.Activities
|
||||
{
|
||||
|
||||
@@ -12,6 +12,7 @@ using OpenRA.FileFormats;
|
||||
using OpenRA.Mods.RA.Buildings;
|
||||
using OpenRA.Mods.RA.Render;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Traits.Activities;
|
||||
|
||||
namespace OpenRA.Mods.RA.Activities
|
||||
{
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
using System.Linq;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Traits.Activities;
|
||||
|
||||
namespace OpenRA.Mods.RA.Activities
|
||||
{
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#endregion
|
||||
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Traits.Activities;
|
||||
|
||||
namespace OpenRA.Mods.RA.Activities
|
||||
{
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
using OpenRA.Mods.RA.Activities;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Traits.Activities;
|
||||
|
||||
namespace OpenRA.Mods.RA.Air
|
||||
{
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Traits.Activities;
|
||||
|
||||
namespace OpenRA.Mods.RA.Air
|
||||
{
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#endregion
|
||||
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Traits.Activities;
|
||||
|
||||
namespace OpenRA.Mods.RA.Air
|
||||
{
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#endregion
|
||||
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Traits.Activities;
|
||||
|
||||
namespace OpenRA.Mods.RA.Air
|
||||
{
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Traits.Activities;
|
||||
|
||||
namespace OpenRA.Mods.RA.Air
|
||||
{
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Traits.Activities;
|
||||
|
||||
namespace OpenRA.Mods.RA.Air
|
||||
{
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#endregion
|
||||
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Traits.Activities;
|
||||
|
||||
namespace OpenRA.Mods.RA.Air
|
||||
{
|
||||
|
||||
@@ -109,6 +109,17 @@ namespace OpenRA.Mods.RA.Air
|
||||
self.QueueActivity(Info.RearmBuildings.Contains(order.TargetActor.Info.Name)
|
||||
? (IActivity)new Rearm() : new Repair(order.TargetActor));
|
||||
}
|
||||
|
||||
if (order.OrderString == "Stop")
|
||||
{
|
||||
self.CancelActivity();
|
||||
|
||||
if (Info.LandWhenIdle)
|
||||
{
|
||||
self.QueueActivity(new Turn(Info.InitialFacing));
|
||||
self.QueueActivity(new HeliLand(true));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int offsetTicks = 0;
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Traits.Activities;
|
||||
|
||||
namespace OpenRA.Mods.RA.Air
|
||||
{
|
||||
|
||||
@@ -112,6 +112,11 @@ namespace OpenRA.Mods.RA.Air
|
||||
info.RearmBuildings.Contains(order.TargetActor.Info.Name)
|
||||
? (IActivity)new Rearm() : new Repair(order.TargetActor));
|
||||
}
|
||||
else if (order.OrderString == "Stop")
|
||||
{
|
||||
UnReserve();
|
||||
self.CancelActivity();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Game.Debug("Unreserve due to unhandled order: {0}".F(order.OrderString));
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Traits.Activities;
|
||||
|
||||
namespace OpenRA.Mods.RA.Air
|
||||
{
|
||||
|
||||
@@ -115,7 +115,7 @@ namespace OpenRA.Mods.RA
|
||||
a();
|
||||
}
|
||||
|
||||
public void DoAttack(Actor self, Target target)
|
||||
public virtual void DoAttack(Actor self, Target target)
|
||||
{
|
||||
if( !CanAttack( self, target ) ) return;
|
||||
|
||||
@@ -149,14 +149,14 @@ namespace OpenRA.Mods.RA
|
||||
return null;
|
||||
}
|
||||
|
||||
public void ResolveOrder(Actor self, Order order)
|
||||
public virtual void ResolveOrder(Actor self, Order order)
|
||||
{
|
||||
if (order.OrderString == "Attack")
|
||||
AttackTarget( Target.FromOrder( order ), order.Queued, true );
|
||||
|
||||
else if(order.OrderString == "AttackHold")
|
||||
AttackTarget( Target.FromOrder( order ), order.Queued, false );
|
||||
|
||||
if (order.OrderString == "Attack" || order.OrderString == "AttackHold")
|
||||
{
|
||||
var target = Target.FromOrder(order);
|
||||
self.SetTargetLine(target, Color.Red);
|
||||
AttackTarget(target, order.Queued, order.OrderString == "Attack");
|
||||
}
|
||||
else
|
||||
{
|
||||
/* hack */
|
||||
@@ -181,7 +181,6 @@ namespace OpenRA.Mods.RA
|
||||
{
|
||||
if( !target.IsValid ) return;
|
||||
self.QueueActivity(queued, GetAttackActivity(self, target, allowMove));
|
||||
self.SetTargetLine(target, Color.Red);
|
||||
}
|
||||
|
||||
public void ScanAndAttack(Actor self, bool allowMovement, bool holdStill)
|
||||
@@ -217,6 +216,7 @@ namespace OpenRA.Mods.RA
|
||||
|
||||
return inRange
|
||||
.Where(a => a.Owner != null && self.Owner.Stances[a.Owner] == Stance.Enemy)
|
||||
.Where(a => !a.HasTrait<AutoTargetIgnore>())
|
||||
.Where(a => HasAnyValidWeapons(Target.FromActor(a)))
|
||||
.OrderBy(a => (a.CenterLocation - self.CenterLocation).LengthSquared)
|
||||
.FirstOrDefault();
|
||||
|
||||
@@ -14,25 +14,22 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
class AttackLeapInfo : AttackBaseInfo
|
||||
class AttackLeapInfo : AttackFrontalInfo
|
||||
{
|
||||
public override object Create(ActorInitializer init) { return new AttackLeap(init.self); }
|
||||
public override object Create(ActorInitializer init) { return new AttackLeap(init.self, this); }
|
||||
}
|
||||
|
||||
class AttackLeap : AttackBase
|
||||
class AttackLeap : AttackFrontal
|
||||
{
|
||||
internal bool IsLeaping;
|
||||
protected Target target;
|
||||
|
||||
public AttackLeap(Actor self)
|
||||
: base(self) {}
|
||||
public AttackLeap(Actor self, AttackLeapInfo info)
|
||||
: base(self, info) {}
|
||||
|
||||
public override void Tick(Actor self)
|
||||
public override void DoAttack(Actor self, Target target)
|
||||
{
|
||||
base.Tick(self);
|
||||
|
||||
if (!target.IsValid) return;
|
||||
if (IsLeaping) return;
|
||||
if( !CanAttack( self, target ) ) return;
|
||||
|
||||
var weapon = Weapons[0].Info;
|
||||
if( !Combat.IsInRange( self.CenterLocation, weapon.Range, target ) ) return;
|
||||
|
||||
34
OpenRA.Mods.RA/AttackMedic.cs
Normal file
34
OpenRA.Mods.RA/AttackMedic.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2010 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see LICENSE.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
public class AttackMedicInfo : AttackFrontalInfo
|
||||
{
|
||||
public override object Create( ActorInitializer init ) { return new AttackMedic( init.self, this ); }
|
||||
}
|
||||
|
||||
public class AttackMedic : AttackFrontal
|
||||
{
|
||||
public AttackMedic(Actor self, AttackMedicInfo info)
|
||||
: base( self, info ) {}
|
||||
|
||||
public override IActivity GetAttackActivity(Actor self, Target newTarget, bool allowMove)
|
||||
{
|
||||
var weapon = ChooseWeaponForTarget(newTarget);
|
||||
if( weapon == null )
|
||||
return null;
|
||||
return new Activities.Heal(newTarget, Math.Max(0, (int)weapon.Info.Range), allowMove);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,7 @@ using System.Drawing;
|
||||
using OpenRA.Effects;
|
||||
using OpenRA.Mods.RA.Move;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Traits.Activities;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
using OpenRA.Mods.RA.Buildings;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Traits.Activities;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
using OpenRA.Mods.RA.Activities;
|
||||
using OpenRA.Mods.RA.Render;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Traits.Activities;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
|
||||
@@ -14,6 +14,7 @@ using OpenRA.Mods.RA.Activities;
|
||||
using OpenRA.Mods.RA.Buildings;
|
||||
using OpenRA.Mods.RA.Move;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Traits.Activities;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
@@ -52,6 +53,14 @@ namespace OpenRA.Mods.RA
|
||||
return new AttackActivity( newTarget );
|
||||
}
|
||||
|
||||
public override void ResolveOrder(Actor self, Order order)
|
||||
{
|
||||
base.ResolveOrder(self, order);
|
||||
|
||||
if (order.OrderString == "Stop")
|
||||
target = Target.None;
|
||||
}
|
||||
|
||||
bool buildComplete = false;
|
||||
public void BuildingComplete(Actor self) { buildComplete = true; }
|
||||
|
||||
|
||||
@@ -20,70 +20,19 @@ namespace OpenRA.Mods.RA
|
||||
{
|
||||
public void TickIdle( Actor self )
|
||||
{
|
||||
self.QueueActivity( new IdleHealActivity() );
|
||||
}
|
||||
var attack = self.Trait<AttackBase>();
|
||||
var inRange = self.World.FindUnitsInCircle(self.CenterLocation, Game.CellSize * attack.GetMaximumRange());
|
||||
|
||||
class IdleHealActivity : Idle
|
||||
{
|
||||
Actor currentTarget;
|
||||
IActivity inner;
|
||||
|
||||
public override IActivity Tick( Actor self )
|
||||
{
|
||||
if( inner == null )
|
||||
{
|
||||
if( NextActivity != null )
|
||||
return NextActivity;
|
||||
|
||||
var attack = self.Trait<AttackBase>();
|
||||
var range = attack.GetMaximumRange();
|
||||
|
||||
if (NeedsNewTarget(self))
|
||||
{
|
||||
currentTarget = ChooseTarget(self, range);
|
||||
if( currentTarget != null )
|
||||
inner = self.Trait<AttackBase>().GetAttackActivity(self, Target.FromActor( currentTarget ), false );
|
||||
}
|
||||
}
|
||||
if( inner != null )
|
||||
{
|
||||
if( NeedsNewTarget(self) )
|
||||
inner.Cancel( self );
|
||||
inner = Util.RunActivity( self, inner );
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
bool NeedsNewTarget(Actor self)
|
||||
{
|
||||
var attack = self.Trait<AttackBase>();
|
||||
var range = attack.GetMaximumRange();
|
||||
|
||||
if (currentTarget == null || !currentTarget.IsInWorld)
|
||||
return true; // he's dead.
|
||||
if( !Combat.IsInRange( self.CenterLocation, range, currentTarget ) )
|
||||
return true; // wandered off faster than we could follow
|
||||
|
||||
if (currentTarget.GetDamageState() == DamageState.Undamaged)
|
||||
return true; // fully healed
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Actor ChooseTarget(Actor self, float range)
|
||||
{
|
||||
var inRange = self.World.FindUnitsInCircle(self.CenterLocation, Game.CellSize * range);
|
||||
var attack = self.Trait<AttackBase>();
|
||||
|
||||
return inRange
|
||||
.Where(a => a != self && self.Owner.Stances[a.Owner] == Stance.Ally)
|
||||
.Where(a => a.IsInWorld && !a.IsDead())
|
||||
.Where(a => a.HasTrait<Health>() && a.GetDamageState() > DamageState.Undamaged)
|
||||
.Where(a => attack.HasAnyValidWeapons(Target.FromActor(a)))
|
||||
.OrderBy(a => (a.CenterLocation - self.CenterLocation).LengthSquared)
|
||||
.FirstOrDefault();
|
||||
}
|
||||
var target = inRange
|
||||
.Where(a => a != self && self.Owner.Stances[a.Owner] == Stance.Ally)
|
||||
.Where(a => a.IsInWorld && !a.IsDead())
|
||||
.Where(a => a.HasTrait<Health>() && a.GetDamageState() > DamageState.Undamaged)
|
||||
.Where(a => attack.HasAnyValidWeapons(Target.FromActor(a)))
|
||||
.OrderBy(a => (a.CenterLocation - self.CenterLocation).LengthSquared)
|
||||
.FirstOrDefault();
|
||||
|
||||
if( target != null )
|
||||
self.QueueActivity(self.Trait<AttackBase>().GetAttackActivity(self, Target.FromActor( target ), false ));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Traits.Activities;
|
||||
using System.Drawing;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
@@ -24,7 +25,7 @@ namespace OpenRA.Mods.RA
|
||||
{
|
||||
if (!self.IsIdle) return;
|
||||
if (e.Attacker.Destroyed) return;
|
||||
|
||||
|
||||
// not a lot we can do about things we can't hurt... although maybe we should automatically run away?
|
||||
var attack = self.Trait<AttackBase>();
|
||||
if (!attack.HasAnyValidWeapons(Target.FromActor(e.Attacker))) return;
|
||||
@@ -37,35 +38,20 @@ namespace OpenRA.Mods.RA
|
||||
self.Trait<AttackBase>().AttackTarget(Target.FromActor(e.Attacker), false, self.Info.Traits.Get<AutoTargetInfo>().AllowMovement);
|
||||
}
|
||||
|
||||
public void TickIdle( Actor self )
|
||||
public void TickIdle(Actor self)
|
||||
{
|
||||
self.QueueActivity( new IdleAttackActivity() );
|
||||
}
|
||||
|
||||
class IdleAttackActivity : Idle
|
||||
{
|
||||
Actor currentTarget;
|
||||
IActivity inner;
|
||||
|
||||
public override IActivity Tick( Actor self )
|
||||
var attack = self.Trait<AttackBase>();
|
||||
var target = attack.ScanForTarget(self, null);
|
||||
if (target != null)
|
||||
{
|
||||
if( NextActivity != null && inner != null )
|
||||
inner.Cancel( self );
|
||||
if( inner == null )
|
||||
{
|
||||
if( NextActivity != null )
|
||||
return NextActivity;
|
||||
|
||||
var attack = self.Trait<AttackBase>();
|
||||
currentTarget = attack.ScanForTarget(self, null);
|
||||
if( currentTarget != null )
|
||||
inner = attack.GetAttackActivity( self, Target.FromActor(currentTarget), self.Info.Traits.Get<AutoTargetInfo>().AllowMovement );
|
||||
}
|
||||
if( inner != null )
|
||||
inner = Util.RunActivity( self, inner );
|
||||
|
||||
return this;
|
||||
self.SetTargetLine(Target.FromActor(target), Color.Red, false);
|
||||
self.QueueActivity(attack.GetAttackActivity(self,
|
||||
Target.FromActor(target),
|
||||
self.Info.Traits.Get<AutoTargetInfo>().AllowMovement));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class AutoTargetIgnoreInfo : TraitInfo<AutoTargetIgnore> { }
|
||||
class AutoTargetIgnore { }
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA.Buildings
|
||||
|
||||
@@ -46,13 +46,7 @@ namespace OpenRA.Mods.RA.Buildings
|
||||
|
||||
public void Add(string key, List<string> prerequisites, ITechTreeElement tte)
|
||||
{
|
||||
Add(key, prerequisites, false, tte);
|
||||
}
|
||||
|
||||
// set requiresPowered = true to discard buildings that have an IDisabled active (eg manually powered down)
|
||||
public void Add(string key, List<string> prerequisites, bool requiresPowered, ITechTreeElement tte)
|
||||
{
|
||||
watchers.Add(new Watcher( key, prerequisites, requiresPowered, tte ));
|
||||
watchers.Add(new Watcher( key, prerequisites, tte ));
|
||||
}
|
||||
|
||||
public void Remove(string key)
|
||||
@@ -86,21 +80,19 @@ namespace OpenRA.Mods.RA.Buildings
|
||||
bool hasPrerequisites;
|
||||
bool requiresPowered;
|
||||
|
||||
public Watcher(string key, List<string> prerequisites, bool requiresPowered, ITechTreeElement watcher)
|
||||
public Watcher(string key, List<string> prerequisites, ITechTreeElement watcher)
|
||||
{
|
||||
this.key = key;
|
||||
this.prerequisites = prerequisites;
|
||||
this.watcher = watcher;
|
||||
this.hasPrerequisites = false;
|
||||
this.requiresPowered = requiresPowered;
|
||||
}
|
||||
|
||||
public void Update(Cache<string, List<Actor>> buildings)
|
||||
{
|
||||
var nowHasPrerequisites = true;
|
||||
foreach (var p in prerequisites)
|
||||
if (!buildings.Keys.Contains(p) ||
|
||||
(requiresPowered && buildings[p].All(b => b.TraitsImplementing<IDisable>().Any(d => d.Disabled))))
|
||||
if (!buildings.Keys.Contains(p))
|
||||
{
|
||||
nowHasPrerequisites = false;
|
||||
break;
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace OpenRA.Mods.RA
|
||||
return;
|
||||
|
||||
var frac = (float)remainingFrames / chronoEffectLength;
|
||||
var excludePalettes = new List<string>(){"cursor", "chrome", "colorpicker"};
|
||||
var excludePalettes = new List<string>(){"cursor", "chrome", "colorpicker", "shroud", "fog"};
|
||||
foreach (var pal in palettes)
|
||||
{
|
||||
if (excludePalettes.Contains(pal.Key))
|
||||
|
||||
@@ -12,7 +12,7 @@ using System.Collections.Generic;
|
||||
using OpenRA.FileFormats;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Widgets.Delegates;
|
||||
using OpenRA.Mods.RA.Widgets.Delegates;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
|
||||
@@ -10,31 +10,31 @@
|
||||
|
||||
using System.Linq;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.FileFormats;
|
||||
|
||||
namespace OpenRA.Mods.RA.Crates
|
||||
{
|
||||
class SupportPowerCrateActionInfo : CrateActionInfo
|
||||
{
|
||||
public readonly string Power = null;
|
||||
[ActorReference]
|
||||
public readonly string Proxy = null;
|
||||
public override object Create(ActorInitializer init) { return new SupportPowerCrateAction(init.self, this); }
|
||||
}
|
||||
|
||||
class SupportPowerCrateAction : CrateAction
|
||||
{
|
||||
SupportPowerCrateActionInfo Info;
|
||||
public SupportPowerCrateAction(Actor self, SupportPowerCrateActionInfo info)
|
||||
: base(self, info) { }
|
||||
: base(self, info) { Info = info; }
|
||||
|
||||
// The free unit crate requires same race, and the actor to be at least ITeleportable.
|
||||
// We want neither of these properties for crate power proxies.
|
||||
public override void Activate(Actor collector)
|
||||
{
|
||||
// shit and broken. if you have a single-use and a multi-use version of the same
|
||||
// support power, this only works by order-coincidence. that's stupid.
|
||||
|
||||
var p = collector.Owner.PlayerActor.TraitsImplementing<SupportPower>()
|
||||
.FirstOrDefault(sp => sp.GetType().Name == (info as SupportPowerCrateActionInfo).Power);
|
||||
|
||||
if (p != null) p.Give(1);
|
||||
|
||||
base.Activate(collector);
|
||||
collector.World.AddFrameEndTask(w => w.CreateActor(Info.Proxy, new TypeDictionary
|
||||
{
|
||||
new OwnerInit( collector.Owner )
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,14 +51,15 @@ namespace OpenRA.Mods.RA
|
||||
Pair.New(Actors["ca2"], new int2(92, 71))
|
||||
}, Actors["pdox"], -1, false);
|
||||
}
|
||||
|
||||
|
||||
if (ticks == 100)
|
||||
Actors["mslo1"].Trait<NukeSilo>().Attack(new int2(98, 52));
|
||||
Actors["mslo1"].Trait<NukePower>().Activate(Actors["mslo1"], new Order(){ TargetLocation = new int2(98, 52) });
|
||||
if (ticks == 140)
|
||||
Actors["mslo2"].Trait<NukeSilo>().Attack(new int2(95, 54));
|
||||
Actors["mslo2"].Trait<NukePower>().Activate(Actors["mslo2"], new Order(){ TargetLocation = new int2(95, 54) });
|
||||
if (ticks == 180)
|
||||
Actors["mslo3"].Trait<NukeSilo>().Attack(new int2(95, 49));
|
||||
|
||||
Actors["mslo3"].Trait<NukePower>().Activate(Actors["mslo3"], new Order(){ TargetLocation = new int2(95, 49) });
|
||||
|
||||
if (ticks == 430)
|
||||
{
|
||||
Actors["mig1"].Trait<AttackPlane>().AttackTarget(Target.FromActor(Actors["greeceweap"]), false, true);
|
||||
|
||||
@@ -32,10 +32,17 @@ namespace OpenRA.Mods.RA.Effects
|
||||
circles.Play("circles");
|
||||
}
|
||||
|
||||
int2 cachedLocation;
|
||||
public void Tick( World world )
|
||||
{
|
||||
flag.Tick();
|
||||
circles.Tick();
|
||||
if (cachedLocation != rp.rallyPoint)
|
||||
{
|
||||
cachedLocation = rp.rallyPoint;
|
||||
circles.Play("circles");
|
||||
}
|
||||
|
||||
if (!building.IsInWorld || building.IsDead())
|
||||
world.AddFrameEndTask(w => w.Remove(this));
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using OpenRA.Effects;
|
||||
using OpenRA.Mods.RA.Activities;
|
||||
using OpenRA.Mods.RA.Buildings;
|
||||
using OpenRA.Mods.RA.Orders;
|
||||
@@ -51,7 +50,6 @@ namespace OpenRA.Mods.RA
|
||||
|
||||
self.CancelActivity();
|
||||
self.QueueActivity(new Enter(order.TargetActor));
|
||||
//self.QueueActivity(new Move(order.TargetActor.Location, order.TargetActor));
|
||||
self.QueueActivity(new CaptureBuilding(order.TargetActor));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using OpenRA.Effects;
|
||||
using OpenRA.Mods.RA.Activities;
|
||||
using OpenRA.Mods.RA.Buildings;
|
||||
using OpenRA.Mods.RA.Orders;
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using OpenRA.Effects;
|
||||
using OpenRA.Mods.RA.Activities;
|
||||
using OpenRA.Mods.RA.Move;
|
||||
using OpenRA.Mods.RA.Orders;
|
||||
@@ -23,7 +22,6 @@ namespace OpenRA.Mods.RA
|
||||
{
|
||||
public readonly int Capacity = 28;
|
||||
public readonly int PipCount = 7;
|
||||
public readonly PipType PipColor = PipType.Yellow;
|
||||
public readonly string[] Resources = { };
|
||||
public readonly decimal FullyLoadedSpeed = .85m;
|
||||
|
||||
@@ -64,11 +62,11 @@ namespace OpenRA.Mods.RA
|
||||
var refs = self.World.Queries.OwnedBy[self.Owner]
|
||||
.Where(x => x != ignore && x.HasTrait<IAcceptOre>())
|
||||
.ToList();
|
||||
var mi = self.Info.Traits.Get<MobileInfo>();
|
||||
var path = self.World.WorldActor.Trait<PathFinder>().FindPath(PathSearch.FromPoints(self.World, mi,
|
||||
refs.Select(r => r.Location + r.Trait<IAcceptOre>().DeliverOffset),
|
||||
self.Location,
|
||||
false));
|
||||
var mi = self.Info.Traits.Get<MobileInfo>();
|
||||
var path = self.World.WorldActor.Trait<PathFinder>().FindPath(
|
||||
PathSearch.FromPoints(self.World, mi,
|
||||
refs.Select(r => r.Location + r.Trait<IAcceptOre>().DeliverOffset),
|
||||
self.Location, false));
|
||||
path.Reverse();
|
||||
if (path.Count != 0)
|
||||
return refs.FirstOrDefault(x => x.Location + x.Trait<IAcceptOre>().DeliverOffset == path[0]);
|
||||
@@ -168,20 +166,27 @@ namespace OpenRA.Mods.RA
|
||||
return;
|
||||
|
||||
ChooseNewProc(self, proc);
|
||||
}
|
||||
|
||||
PipType GetPipAt(int i)
|
||||
{
|
||||
var n = i * Info.Capacity / Info.PipCount;
|
||||
|
||||
foreach (var rt in contents)
|
||||
if (n < rt.Value)
|
||||
return rt.Key.PipColor;
|
||||
else
|
||||
n -= rt.Value;
|
||||
|
||||
return PipType.Transparent;
|
||||
}
|
||||
|
||||
public IEnumerable<PipType> GetPips(Actor self)
|
||||
{
|
||||
int numPips = Info.PipCount;
|
||||
int n = contents.Values.Sum();
|
||||
|
||||
for (int i = 0; i < numPips; i++)
|
||||
{
|
||||
if (n * 1.0f / Info.Capacity > i * 1.0f / numPips)
|
||||
yield return Info.PipColor;
|
||||
else
|
||||
yield return PipType.Transparent;
|
||||
}
|
||||
int numPips = Info.PipCount;
|
||||
|
||||
for (int i = 0; i < numPips; i++)
|
||||
yield return GetPipAt(i);
|
||||
}
|
||||
|
||||
public IEnumerable<Renderable> ModifyRender(Actor self, IEnumerable<Renderable> r)
|
||||
|
||||
@@ -8,36 +8,68 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using OpenRA.Mods.RA.Render;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
class IdleAnimationInfo : ITraitInfo
|
||||
class IdleAnimationInfo : ITraitInfo, ITraitPrerequisite<RenderInfantryInfo>
|
||||
{
|
||||
public readonly int IdleWaitTicks = 50;
|
||||
public readonly string[] Animations = {};
|
||||
public object Create(ActorInitializer init) { return new IdleAnimation(this); }
|
||||
}
|
||||
|
||||
// infantry prone behavior
|
||||
class IdleAnimation : INotifyDamage, INotifyIdle
|
||||
class IdleAnimation : ITick, INotifyIdle
|
||||
{
|
||||
enum IdleState
|
||||
{
|
||||
None,
|
||||
Waiting,
|
||||
Active
|
||||
};
|
||||
|
||||
IdleAnimationInfo Info;
|
||||
string sequence;
|
||||
int delay;
|
||||
IdleState state;
|
||||
|
||||
public IdleAnimation(IdleAnimationInfo info)
|
||||
{
|
||||
Info = info;
|
||||
}
|
||||
|
||||
public void Damaged(Actor self, AttackInfo e)
|
||||
{
|
||||
if (self.GetCurrentActivity() is Activities.IdleAnimation)
|
||||
self.CancelActivity();
|
||||
}
|
||||
|
||||
public void Tick(Actor self)
|
||||
{
|
||||
if (!self.IsIdle)
|
||||
{
|
||||
state = IdleState.None;
|
||||
return;
|
||||
}
|
||||
|
||||
if (state == IdleState.Active)
|
||||
return;
|
||||
|
||||
else if (delay > 0 && --delay == 0)
|
||||
{
|
||||
state = IdleState.Active;
|
||||
var ri = self.TraitOrDefault<RenderInfantry>();
|
||||
|
||||
if (ri.anim.HasSequence(sequence))
|
||||
ri.anim.PlayThen(sequence, () => state = IdleState.None);
|
||||
else
|
||||
state = IdleState.None;
|
||||
}
|
||||
}
|
||||
|
||||
public void TickIdle(Actor self)
|
||||
{
|
||||
self.QueueActivity(new Activities.IdleAnimation(Info.Animations.Random(self.World.SharedRandom),
|
||||
Info.IdleWaitTicks));
|
||||
if (state != IdleState.None)
|
||||
return;
|
||||
|
||||
state = IdleState.Waiting;
|
||||
sequence = Info.Animations.Random(self.World.SharedRandom);
|
||||
delay = Info.IdleWaitTicks;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,29 +10,31 @@
|
||||
|
||||
using System.Linq;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.FileFormats;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
class InfiltrateForSupportPowerInfo : ITraitInfo
|
||||
{
|
||||
public readonly string Power = null;
|
||||
[ActorReference]
|
||||
public readonly string Proxy = null;
|
||||
public object Create(ActorInitializer init) { return new InfiltrateForSupportPower(this); }
|
||||
}
|
||||
|
||||
class InfiltrateForSupportPower : IAcceptSpy
|
||||
{
|
||||
InfiltrateForSupportPowerInfo info;
|
||||
InfiltrateForSupportPowerInfo Info;
|
||||
public InfiltrateForSupportPower(InfiltrateForSupportPowerInfo info)
|
||||
{
|
||||
this.info = info;
|
||||
Info = info;
|
||||
}
|
||||
|
||||
public void OnInfiltrate(Actor self, Actor spy)
|
||||
{
|
||||
var p = spy.Owner.PlayerActor.TraitsImplementing<SupportPower>()
|
||||
.FirstOrDefault(sp => sp.GetType().Name == info.Power);
|
||||
|
||||
if (p != null) p.Give(1);
|
||||
spy.World.AddFrameEndTask(w => w.CreateActor(Info.Proxy, new TypeDictionary
|
||||
{
|
||||
new OwnerInit( spy.Owner )
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,6 +205,11 @@ namespace OpenRA.Mods.RA.Move
|
||||
var target = order.TargetLocation.Clamp(self.World.Map.Bounds);
|
||||
PerformMove(self, target, order.Queued && !self.IsIdle);
|
||||
}
|
||||
|
||||
if (order.OrderString == "Stop")
|
||||
{
|
||||
self.CancelActivity();
|
||||
}
|
||||
}
|
||||
|
||||
public string VoicePhraseForOrder(Actor self, Order order)
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace OpenRA.Mods.RA
|
||||
|
||||
var frac = (float)remainingFrames / nukeEffectLength;
|
||||
|
||||
var excludePalettes = new List<string>(){"cursor", "chrome", "colorpicker"};
|
||||
var excludePalettes = new List<string>(){"cursor", "chrome", "colorpicker", "shroud", "fog"};
|
||||
foreach (var pal in palettes)
|
||||
{
|
||||
if (excludePalettes.Contains(pal.Key))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
@@ -259,6 +259,7 @@
|
||||
<Compile Include="Widgets\BuildPaletteWidget.cs" />
|
||||
<Compile Include="Widgets\Delegates\IngameObserverChromeDelegate.cs" />
|
||||
<Compile Include="Widgets\Delegates\IngameChromeDelegate.cs" />
|
||||
<Compile Include="Widgets\Delegates\ReplayBrowserDelegate.cs" />
|
||||
<Compile Include="Widgets\MoneyBinWidget.cs" />
|
||||
<Compile Include="Widgets\OrderButtonWidget.cs" />
|
||||
<Compile Include="Widgets\PowerBinWidget.cs" />
|
||||
@@ -299,7 +300,6 @@
|
||||
<Compile Include="HackyAI.cs" />
|
||||
<Compile Include="RALoadScreen.cs" />
|
||||
<Compile Include="NullLoadScreen.cs" />
|
||||
<Compile Include="Activities\IdleAnimation.cs" />
|
||||
<Compile Include="IdleAnimation.cs" />
|
||||
<Compile Include="World\GotoNextBase.cs" />
|
||||
<Compile Include="World\SmudgeLayer.cs" />
|
||||
@@ -324,6 +324,9 @@
|
||||
<Compile Include="Widgets\Delegates\VideoPlayerDelegate.cs" />
|
||||
<Compile Include="TargetableSubmarine.cs" />
|
||||
<Compile Include="Effects\RallyPoint.cs" />
|
||||
<Compile Include="AttackMedic.cs" />
|
||||
<Compile Include="Activities\Heal.cs" />
|
||||
<Compile Include="SupportPowers\SupportPowerManager.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\OpenRA.FileFormats\OpenRA.FileFormats.csproj">
|
||||
@@ -350,4 +353,8 @@
|
||||
copy "$(TargetPath)" "$(SolutionDir)mods/ra/"
|
||||
cd "$(SolutionDir)"</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="SupportPowers\" />
|
||||
<Folder Include="Player\" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -21,60 +21,62 @@ namespace OpenRA.Mods.RA.Render
|
||||
public override object Create(ActorInitializer init) { return new RenderInfantry(init.self); }
|
||||
}
|
||||
|
||||
public class RenderInfantry : RenderSimple, INotifyAttack, INotifyDamage
|
||||
public class RenderInfantry : RenderSimple, INotifyAttack, INotifyDamage, INotifyIdle
|
||||
{
|
||||
public enum AnimationState
|
||||
{
|
||||
Idle,
|
||||
Attacking,
|
||||
Moving,
|
||||
Waiting
|
||||
};
|
||||
|
||||
public AnimationState State { get; private set; }
|
||||
Mobile mobile;
|
||||
public RenderInfantry(Actor self)
|
||||
: base(self, () => self.Trait<IFacing>().Facing)
|
||||
{
|
||||
anim.Play("stand");
|
||||
}
|
||||
|
||||
bool ChooseMoveAnim(Actor self)
|
||||
{
|
||||
var mobile = self.Trait<Mobile>();
|
||||
if( !mobile.IsMoving ) return false;
|
||||
|
||||
if (float2.WithinEpsilon(self.CenterLocation, Util.CenterOfCell(mobile.toCell), 2)) return false;
|
||||
|
||||
var seq = IsProne(self) ? "crawl" : "run";
|
||||
|
||||
if (anim.CurrentSequence.Name != seq)
|
||||
anim.PlayRepeating(seq);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool inAttack = false;
|
||||
bool IsProne(Actor self)
|
||||
{
|
||||
var takeCover = self.TraitOrDefault<TakeCover>();
|
||||
return takeCover != null && takeCover.IsProne;
|
||||
State = AnimationState.Idle;
|
||||
mobile = self.Trait<Mobile>();
|
||||
}
|
||||
|
||||
public void Attacking(Actor self, Target target)
|
||||
{
|
||||
inAttack = true;
|
||||
|
||||
var seq = IsProne(self) ? "prone-shoot" : "shoot";
|
||||
|
||||
if (anim.HasSequence(seq))
|
||||
anim.PlayThen(seq, () => inAttack = false);
|
||||
State = AnimationState.Attacking;
|
||||
if (anim.HasSequence("shoot"))
|
||||
anim.PlayThen("shoot", () => State = AnimationState.Idle);
|
||||
else if (anim.HasSequence("heal"))
|
||||
anim.PlayThen("heal", () => inAttack = false);
|
||||
anim.PlayThen("heal", () => State = AnimationState.Idle);
|
||||
}
|
||||
|
||||
public override void Tick(Actor self)
|
||||
{
|
||||
base.Tick(self);
|
||||
if (inAttack) return;
|
||||
if (self.GetCurrentActivity() is Activities.IdleAnimation) return;
|
||||
if (ChooseMoveAnim(self)) return;
|
||||
|
||||
if (IsProne(self))
|
||||
anim.PlayFetchIndex("crawl", () => 0); /* what a hack. */
|
||||
else
|
||||
// If path is blocked, we can have !isMoving and !idle
|
||||
// Need to handle this case specially
|
||||
if (!mobile.IsMoving && State == AnimationState.Moving)
|
||||
{
|
||||
State = AnimationState.Waiting;
|
||||
anim.Play("stand");
|
||||
}
|
||||
else if (State != AnimationState.Moving && mobile.IsMoving)
|
||||
{
|
||||
State = AnimationState.Moving;
|
||||
anim.PlayRepeating("run");
|
||||
}
|
||||
}
|
||||
|
||||
public void TickIdle(Actor self)
|
||||
{
|
||||
if (State != AnimationState.Idle)
|
||||
{
|
||||
anim.Play("stand");
|
||||
State = AnimationState.Idle;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void Damaged(Actor self, AttackInfo e)
|
||||
{
|
||||
|
||||
@@ -46,13 +46,13 @@ namespace OpenRA.Mods.RA.Render
|
||||
{
|
||||
disguisedAsPlayer = target.Owner;
|
||||
disguisedAsSprite = target.Trait<RenderSimple>().GetImage(target);
|
||||
anim.ChangeImage(disguisedAsSprite);
|
||||
anim.ChangeImage(disguisedAsSprite, "stand");
|
||||
}
|
||||
else
|
||||
{
|
||||
disguisedAsPlayer = null;
|
||||
disguisedAsSprite = null;
|
||||
anim.ChangeImage(GetImage(self));
|
||||
anim.ChangeImage(GetImage(self), "stand");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,16 +6,10 @@
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see LICENSE.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.Traits;
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using OpenRA.Widgets;
|
||||
using OpenRA.Traits.Activities;
|
||||
using OpenRA.FileFormats;
|
||||
using OpenRA.Mods.RA.Activities;
|
||||
using System;
|
||||
|
||||
namespace OpenRA.Scripting
|
||||
{
|
||||
|
||||
@@ -6,13 +6,13 @@
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see LICENSE.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using OpenRA.FileFormats;
|
||||
using OpenRA.Mods.RA;
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.FileFormats;
|
||||
using OpenRA.Mods.RA;
|
||||
using OpenRA.Mods.RA.Render;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace OpenRA.Scripting
|
||||
{
|
||||
|
||||
@@ -285,7 +285,7 @@ namespace OpenRA.Mods.RA.Server
|
||||
};
|
||||
|
||||
var slotData = server.lobbyInfo.Slots.FirstOrDefault( x => x.Index == client.Slot );
|
||||
if (slotData != null)
|
||||
if (slotData != null && slotData.MapPlayer != null)
|
||||
SyncClientToPlayerReference(client, server.Map.Players[slotData.MapPlayer]);
|
||||
|
||||
server.lobbyInfo.Clients.Add(client);
|
||||
|
||||
@@ -38,9 +38,10 @@ namespace OpenRA.Mods.RA
|
||||
{
|
||||
if (order.OrderString == "SpyInfiltrate")
|
||||
{
|
||||
self.CancelActivity();
|
||||
self.QueueActivity(new MoveAdjacentTo(order.TargetActor));
|
||||
self.SetTargetLine(Target.FromOrder(order), Color.Red);
|
||||
|
||||
self.CancelActivity();
|
||||
self.QueueActivity(new Enter(order.TargetActor));
|
||||
self.QueueActivity(new Infiltrate(order.TargetActor));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,53 +26,39 @@ namespace OpenRA.Mods.RA
|
||||
public override object Create(ActorInitializer init) { return new AirstrikePower(init.self, this); }
|
||||
}
|
||||
|
||||
class AirstrikePower : SupportPower, IResolveOrder
|
||||
class AirstrikePower : SupportPower
|
||||
{
|
||||
public AirstrikePower(Actor self, AirstrikePowerInfo info) : base(self, info) { }
|
||||
|
||||
protected override void OnActivate()
|
||||
public override void Activate(Actor self, Order order)
|
||||
{
|
||||
Self.World.OrderGenerator = new GenericSelectTarget(Owner.PlayerActor, Info.OrderName, "ability");
|
||||
}
|
||||
|
||||
public void ResolveOrder(Actor self, Order order)
|
||||
{
|
||||
if (!IsAvailable) return;
|
||||
|
||||
if (order.OrderString == Info.OrderName)
|
||||
var startPos = self.World.ChooseRandomEdgeCell();
|
||||
self.World.AddFrameEndTask(w =>
|
||||
{
|
||||
var startPos = Owner.World.ChooseRandomEdgeCell();
|
||||
var info = (Info as AirstrikePowerInfo);
|
||||
var flare = info.FlareType != null ? w.CreateActor(info.FlareType, new TypeDictionary
|
||||
{
|
||||
new LocationInit( order.TargetLocation ),
|
||||
new OwnerInit( self.Owner ),
|
||||
}) : null;
|
||||
|
||||
var a = w.CreateActor(info.UnitType, new TypeDictionary
|
||||
{
|
||||
new LocationInit( startPos ),
|
||||
new OwnerInit( self.Owner ),
|
||||
new FacingInit( Util.GetFacing(order.TargetLocation - startPos, 0) ),
|
||||
new AltitudeInit( Rules.Info[info.UnitType].Traits.Get<PlaneInfo>().CruiseAltitude ),
|
||||
});
|
||||
a.Trait<CarpetBomb>().SetTarget(order.TargetLocation);
|
||||
|
||||
Owner.World.AddFrameEndTask(w =>
|
||||
{
|
||||
var info = (Info as AirstrikePowerInfo);
|
||||
var flare = info.FlareType != null ? w.CreateActor(info.FlareType, new TypeDictionary
|
||||
{
|
||||
new LocationInit( order.TargetLocation ),
|
||||
new OwnerInit( Owner ),
|
||||
}) : null;
|
||||
|
||||
var a = w.CreateActor(info.UnitType, new TypeDictionary
|
||||
{
|
||||
new LocationInit( startPos ),
|
||||
new OwnerInit( Owner ),
|
||||
new FacingInit( Util.GetFacing(order.TargetLocation - startPos, 0) ),
|
||||
new AltitudeInit( Rules.Info[info.UnitType].Traits.Get<PlaneInfo>().CruiseAltitude ),
|
||||
});
|
||||
a.Trait<CarpetBomb>().SetTarget(order.TargetLocation);
|
||||
a.CancelActivity();
|
||||
a.QueueActivity(Fly.ToCell(order.TargetLocation));
|
||||
|
||||
a.CancelActivity();
|
||||
a.QueueActivity(Fly.ToCell(order.TargetLocation));
|
||||
if (flare != null)
|
||||
a.QueueActivity(new CallFunc(() => flare.Destroy()));
|
||||
|
||||
if (flare != null)
|
||||
a.QueueActivity(new CallFunc(() => flare.Destroy()));
|
||||
|
||||
a.QueueActivity(new FlyOffMap { Interruptible = false });
|
||||
a.QueueActivity(new RemoveSelf());
|
||||
});
|
||||
|
||||
FinishActivate();
|
||||
}
|
||||
a.QueueActivity(new FlyOffMap { Interruptible = false });
|
||||
a.QueueActivity(new RemoveSelf());
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,62 +20,52 @@ namespace OpenRA.Mods.RA
|
||||
{
|
||||
class ChronoshiftPowerInfo : SupportPowerInfo
|
||||
{
|
||||
public readonly int Range = 2; // Range in cells
|
||||
public readonly int Duration = 30;
|
||||
public readonly int Range = 1; // Range in cells
|
||||
public readonly int Duration = 30; // Seconds
|
||||
public readonly bool KillCargo = true;
|
||||
|
||||
public override object Create(ActorInitializer init) { return new ChronoshiftPower(init.self,this); }
|
||||
}
|
||||
|
||||
class ChronoshiftPower : SupportPower, IResolveOrder
|
||||
class ChronoshiftPower : SupportPower
|
||||
{
|
||||
public ChronoshiftPower(Actor self, ChronoshiftPowerInfo info) : base(self, info) { }
|
||||
protected override void OnActivate() { Self.World.OrderGenerator = new SelectTarget(this); }
|
||||
|
||||
public void ResolveOrder(Actor self, Order order)
|
||||
|
||||
public override IOrderGenerator OrderGenerator(string order, SupportPowerManager manager)
|
||||
{
|
||||
if (!IsReady) return;
|
||||
|
||||
if (order.OrderString == "Chronoshift")
|
||||
Sound.PlayToPlayer(manager.self.Owner, Info.SelectTargetSound);
|
||||
return new SelectTarget(order, manager, this);
|
||||
}
|
||||
|
||||
public override void Activate(Actor self, Order order)
|
||||
{
|
||||
self.Trait<RenderBuilding>().PlayCustomAnim(self, "active");
|
||||
|
||||
// Trigger screen desaturate effect
|
||||
foreach (var a in self.World.Queries.WithTrait<ChronoshiftPaletteEffect>())
|
||||
a.Trait.Enable();
|
||||
|
||||
Sound.Play("chrono2.aud", Game.CellSize * order.TargetLocation);
|
||||
Sound.Play("chrono2.aud", Game.CellSize * order.ExtraLocation);
|
||||
foreach (var target in UnitsInRange(order.ExtraLocation))
|
||||
{
|
||||
var chronosphere = self.World.Queries
|
||||
.OwnedBy[self.Owner]
|
||||
.WithTrait<Chronosphere>()
|
||||
.Select(x => x.Actor).FirstOrDefault();
|
||||
|
||||
if (chronosphere != null)
|
||||
chronosphere.Trait<RenderBuilding>().PlayCustomAnim(chronosphere, "active");
|
||||
|
||||
// Trigger screen desaturate effect
|
||||
foreach (var a in self.World.Queries.WithTrait<ChronoshiftPaletteEffect>())
|
||||
a.Trait.Enable();
|
||||
|
||||
Sound.Play("chrono2.aud", Game.CellSize * order.TargetLocation);
|
||||
Sound.Play("chrono2.aud", Game.CellSize * order.ExtraLocation);
|
||||
|
||||
var targets = UnitsInRange(order.ExtraLocation);
|
||||
foreach (var target in targets)
|
||||
{
|
||||
var cs = target.Trait<Chronoshiftable>();
|
||||
var targetCell = target.Location + order.TargetLocation - order.ExtraLocation;
|
||||
|
||||
if (cs.CanChronoshiftTo(target, targetCell))
|
||||
target.Trait<Chronoshiftable>().Teleport(target,
|
||||
targetCell,
|
||||
(int)((Info as ChronoshiftPowerInfo).Duration * 25 * 60),
|
||||
(Info as ChronoshiftPowerInfo).KillCargo,
|
||||
chronosphere);
|
||||
}
|
||||
|
||||
FinishActivate();
|
||||
var cs = target.Trait<Chronoshiftable>();
|
||||
var targetCell = target.Location + order.TargetLocation - order.ExtraLocation;
|
||||
// TODO: Fix CanChronoshiftTo desync
|
||||
if (cs.CanChronoshiftTo(target, targetCell))
|
||||
target.Trait<Chronoshiftable>().Teleport(target,
|
||||
targetCell,
|
||||
(Info as ChronoshiftPowerInfo).Duration * 25,
|
||||
(Info as ChronoshiftPowerInfo).KillCargo,
|
||||
self);
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<Actor> UnitsInRange(int2 xy)
|
||||
{
|
||||
int range = (Info as ChronoshiftPowerInfo).Range;
|
||||
var uim = Self.World.WorldActor.Trait<UnitInfluence>();
|
||||
var tiles = Self.World.FindTilesInCircle(xy, range);
|
||||
var uim = self.World.WorldActor.Trait<UnitInfluence>();
|
||||
var tiles = self.World.FindTilesInCircle(xy, range);
|
||||
var units = new List<Actor>();
|
||||
foreach (var t in tiles)
|
||||
units.AddRange(uim.GetUnitsAt(t));
|
||||
@@ -85,36 +75,35 @@ namespace OpenRA.Mods.RA
|
||||
|
||||
class SelectTarget : IOrderGenerator
|
||||
{
|
||||
ChronoshiftPower power;
|
||||
int range;
|
||||
Sprite tile;
|
||||
readonly ChronoshiftPower power;
|
||||
readonly int range;
|
||||
readonly Sprite tile;
|
||||
readonly SupportPowerManager manager;
|
||||
readonly string order;
|
||||
|
||||
public SelectTarget(ChronoshiftPower power)
|
||||
public SelectTarget(string order, SupportPowerManager manager, ChronoshiftPower power)
|
||||
{
|
||||
this.manager = manager;
|
||||
this.order = order;
|
||||
this.power = power;
|
||||
this.range = (power.Info as ChronoshiftPowerInfo).Range;
|
||||
tile = UiOverlay.SynthesizeTile(0x04);
|
||||
}
|
||||
|
||||
|
||||
public IEnumerable<Order> Order(World world, int2 xy, MouseInput mi)
|
||||
{
|
||||
if (mi.Button == MouseButton.Right)
|
||||
world.CancelInputMode();
|
||||
|
||||
world.OrderGenerator = new SelectDestination(power, xy);
|
||||
world.CancelInputMode();
|
||||
world.OrderGenerator = new SelectDestination(order, manager, power, xy);
|
||||
yield break;
|
||||
}
|
||||
|
||||
public void Tick( World world )
|
||||
public void Tick(World world)
|
||||
{
|
||||
var hasChronosphere = world.Queries.OwnedBy[world.LocalPlayer]
|
||||
.WithTrait<Chronosphere>()
|
||||
.Any();
|
||||
|
||||
if (!hasChronosphere)
|
||||
// Cancel the OG if we can't use the power
|
||||
if (!manager.Powers.ContainsKey(order))
|
||||
world.CancelInputMode();
|
||||
}
|
||||
|
||||
|
||||
public void RenderAfterWorld(WorldRenderer wr, World world)
|
||||
{
|
||||
var xy = Game.viewport.ViewToWorld(Viewport.LastMousePos).ToInt2();
|
||||
@@ -139,13 +128,17 @@ namespace OpenRA.Mods.RA
|
||||
|
||||
class SelectDestination : IOrderGenerator
|
||||
{
|
||||
ChronoshiftPower power;
|
||||
int2 sourceLocation;
|
||||
int range;
|
||||
Sprite validTile, invalidTile, sourceTile;
|
||||
readonly ChronoshiftPower power;
|
||||
readonly int2 sourceLocation;
|
||||
readonly int range;
|
||||
readonly Sprite validTile, invalidTile, sourceTile;
|
||||
readonly SupportPowerManager manager;
|
||||
readonly string order;
|
||||
|
||||
public SelectDestination(ChronoshiftPower power, int2 sourceLocation)
|
||||
public SelectDestination(string order, SupportPowerManager manager, ChronoshiftPower power, int2 sourceLocation)
|
||||
{
|
||||
this.manager = manager;
|
||||
this.order = order;
|
||||
this.power = power;
|
||||
this.sourceLocation = sourceLocation;
|
||||
this.range = (power.Info as ChronoshiftPowerInfo).Range;
|
||||
@@ -174,23 +167,20 @@ namespace OpenRA.Mods.RA
|
||||
{
|
||||
// Cannot chronoshift into unexplored location
|
||||
if (isValidTarget(xy))
|
||||
yield return new Order("Chronoshift", world.LocalPlayer.PlayerActor, false)
|
||||
yield return new Order(order, manager.self, false)
|
||||
{
|
||||
TargetLocation = xy,
|
||||
ExtraLocation = sourceLocation
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public void Tick(World world)
|
||||
{
|
||||
var hasChronosphere = world.Queries.OwnedBy[world.LocalPlayer]
|
||||
.WithTrait<Chronosphere>()
|
||||
.Any();
|
||||
|
||||
if (!hasChronosphere)
|
||||
// Cancel the OG if we can't use the power
|
||||
if (!manager.Powers.ContainsKey(order))
|
||||
world.CancelInputMode();
|
||||
}
|
||||
|
||||
|
||||
public void RenderAfterWorld(WorldRenderer wr, World world)
|
||||
{
|
||||
foreach (var unit in power.UnitsInRange(sourceLocation))
|
||||
@@ -243,14 +233,11 @@ namespace OpenRA.Mods.RA
|
||||
}
|
||||
return canTeleport;
|
||||
}
|
||||
|
||||
public string GetCursor(World world, int2 xy, MouseInput mi)
|
||||
{
|
||||
return isValidTarget(xy) ? "chrono-target" : "move-blocked";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// tag trait for the building
|
||||
class ChronosphereInfo : TraitInfo<Chronosphere> {}
|
||||
class Chronosphere {}
|
||||
}
|
||||
|
||||
@@ -26,28 +26,21 @@ namespace OpenRA.Mods.RA
|
||||
{
|
||||
public GpsPower(Actor self, GpsPowerInfo info) : base(self, info) { }
|
||||
|
||||
protected override void OnFinishCharging()
|
||||
public override void Charged(Actor self, string key)
|
||||
{
|
||||
var launchSite = Owner.World.Queries.OwnedBy[Owner]
|
||||
.FirstOrDefault(a => a.HasTrait<GpsLaunchSite>());
|
||||
|
||||
if (launchSite == null)
|
||||
return;
|
||||
|
||||
Owner.World.AddFrameEndTask(w =>
|
||||
self.Owner.PlayerActor.Trait<SupportPowerManager>().Powers[key].Activate(new Order());
|
||||
}
|
||||
|
||||
public override void Activate(Actor self, Order order)
|
||||
{
|
||||
self.World.AddFrameEndTask(w =>
|
||||
{
|
||||
Sound.PlayToPlayer(Owner, Info.LaunchSound);
|
||||
Sound.PlayToPlayer(self.Owner, Info.LaunchSound);
|
||||
|
||||
w.Add(new SatelliteLaunch(launchSite));
|
||||
w.Add(new SatelliteLaunch(self));
|
||||
w.Add(new DelayedAction((Info as GpsPowerInfo).RevealDelay * 25,
|
||||
() => Owner.Shroud.Disabled = true));
|
||||
() => self.Owner.Shroud.Disabled = true));
|
||||
});
|
||||
|
||||
FinishActivate();
|
||||
}
|
||||
}
|
||||
|
||||
// tag trait to identify the building
|
||||
class GpsLaunchSiteInfo : TraitInfo<GpsLaunchSite> { }
|
||||
class GpsLaunchSite { }
|
||||
}
|
||||
|
||||
@@ -21,52 +21,35 @@ namespace OpenRA.Mods.RA
|
||||
{
|
||||
class IronCurtainPowerInfo : SupportPowerInfo
|
||||
{
|
||||
public readonly float Duration = 0f;
|
||||
public readonly int Range = 2; // Range in cells
|
||||
public readonly int Duration = 10; // Seconds
|
||||
public readonly int Range = 1; // Range in cells
|
||||
|
||||
public override object Create(ActorInitializer init) { return new IronCurtainPower(init.self, this); }
|
||||
}
|
||||
|
||||
class IronCurtainPower : SupportPower, IResolveOrder
|
||||
class IronCurtainPower : SupportPower
|
||||
{
|
||||
public IronCurtainPower(Actor self, IronCurtainPowerInfo info) : base(self, info) { }
|
||||
|
||||
protected override void OnBeginCharging() { Sound.PlayToPlayer(Owner, "ironchg1.aud"); }
|
||||
protected override void OnFinishCharging() { Sound.PlayToPlayer(Owner, "ironrdy1.aud"); }
|
||||
protected override void OnActivate()
|
||||
public override IOrderGenerator OrderGenerator(string order, SupportPowerManager manager)
|
||||
{
|
||||
Self.World.OrderGenerator = new SelectTarget(this);
|
||||
Sound.Play("slcttgt1.aud");
|
||||
Sound.PlayToPlayer(manager.self.Owner, Info.SelectTargetSound);
|
||||
return new SelectTarget(order, manager, this);
|
||||
}
|
||||
|
||||
public void ResolveOrder(Actor self, Order order)
|
||||
|
||||
public override void Activate(Actor self, Order order)
|
||||
{
|
||||
if (!IsReady) return;
|
||||
|
||||
if (order.OrderString == "IronCurtain")
|
||||
{
|
||||
var curtain = self.World.Queries
|
||||
.OwnedBy[self.Owner]
|
||||
.WithTrait<IronCurtain>()
|
||||
.Select(x => x.Actor).FirstOrDefault();
|
||||
|
||||
if (curtain != null)
|
||||
curtain.Trait<RenderBuilding>().PlayCustomAnim(curtain, "active");
|
||||
|
||||
Sound.Play("ironcur9.aud", Game.CellSize * order.TargetLocation);
|
||||
foreach (var target in UnitsInRange(order.TargetLocation))
|
||||
target.Trait<IronCurtainable>().Activate(target, (int)((Info as IronCurtainPowerInfo).Duration * 25 * 60));
|
||||
|
||||
FinishActivate();
|
||||
}
|
||||
self.Trait<RenderBuilding>().PlayCustomAnim(self, "active");
|
||||
|
||||
Sound.Play("ironcur9.aud", Game.CellSize * order.TargetLocation);
|
||||
foreach (var target in UnitsInRange(order.TargetLocation))
|
||||
target.Trait<IronCurtainable>().Activate(target, (Info as IronCurtainPowerInfo).Duration * 25);
|
||||
}
|
||||
|
||||
public IEnumerable<Actor> UnitsInRange(int2 xy)
|
||||
{
|
||||
int range = (Info as IronCurtainPowerInfo).Range;
|
||||
var uim = Self.World.WorldActor.Trait<UnitInfluence>();
|
||||
var tiles = Self.World.FindTilesInCircle(xy, range);
|
||||
var uim = self.World.WorldActor.Trait<UnitInfluence>();
|
||||
var tiles = self.World.FindTilesInCircle(xy, range);
|
||||
var units = new List<Actor>();
|
||||
foreach (var t in tiles)
|
||||
units.AddRange(uim.GetUnitsAt(t));
|
||||
@@ -76,12 +59,16 @@ namespace OpenRA.Mods.RA
|
||||
|
||||
class SelectTarget : IOrderGenerator
|
||||
{
|
||||
IronCurtainPower power;
|
||||
int range;
|
||||
Sprite tile;
|
||||
readonly IronCurtainPower power;
|
||||
readonly int range;
|
||||
readonly Sprite tile;
|
||||
readonly SupportPowerManager manager;
|
||||
readonly string order;
|
||||
|
||||
public SelectTarget(IronCurtainPower power)
|
||||
public SelectTarget(string order, SupportPowerManager manager, IronCurtainPower power)
|
||||
{
|
||||
this.manager = manager;
|
||||
this.order = order;
|
||||
this.power = power;
|
||||
this.range = (power.Info as IronCurtainPowerInfo).Range;
|
||||
tile = UiOverlay.SynthesizeTile(0x04);
|
||||
@@ -89,28 +76,15 @@ namespace OpenRA.Mods.RA
|
||||
|
||||
public IEnumerable<Order> Order(World world, int2 xy, MouseInput mi)
|
||||
{
|
||||
if (mi.Button == MouseButton.Right)
|
||||
world.CancelInputMode();
|
||||
|
||||
return OrderInner(world, xy, mi);
|
||||
world.CancelInputMode();
|
||||
if (mi.Button == MouseButton.Left && power.UnitsInRange(xy).Any())
|
||||
yield return new Order(order, manager.self, false) { TargetLocation = xy };
|
||||
}
|
||||
|
||||
IEnumerable<Order> OrderInner(World world, int2 xy, MouseInput mi)
|
||||
{
|
||||
if (mi.Button == MouseButton.Left && power.UnitsInRange(xy).Any() )
|
||||
{
|
||||
world.CancelInputMode();
|
||||
yield return new Order("IronCurtain", world.LocalPlayer.PlayerActor, false) { TargetLocation = xy };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void Tick(World world)
|
||||
{
|
||||
var hasStructure = world.Queries.OwnedBy[world.LocalPlayer]
|
||||
.WithTrait<IronCurtain>()
|
||||
.Any();
|
||||
|
||||
if (!hasStructure)
|
||||
// Cancel the OG if we can't use the power
|
||||
if (!manager.Powers.ContainsKey(order))
|
||||
world.CancelInputMode();
|
||||
}
|
||||
|
||||
@@ -134,8 +108,4 @@ namespace OpenRA.Mods.RA
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// tag trait for the building
|
||||
class IronCurtainInfo : TraitInfo<IronCurtain> { }
|
||||
class IronCurtain { }
|
||||
}
|
||||
|
||||
@@ -17,72 +17,33 @@ using OpenRA.Traits;
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
class NukePowerInfo : SupportPowerInfo
|
||||
{
|
||||
public override object Create(ActorInitializer init) { return new NukePower(init.self, this); }
|
||||
}
|
||||
|
||||
class NukePower : SupportPower, IResolveOrder
|
||||
{
|
||||
public NukePower(Actor self, NukePowerInfo info) : base(self, info) { }
|
||||
|
||||
protected override void OnActivate()
|
||||
{
|
||||
Self.World.OrderGenerator =
|
||||
new GenericSelectTargetWithBuilding<NukeSilo>(Owner.PlayerActor, "NuclearMissile", "nuke");
|
||||
}
|
||||
|
||||
public void ResolveOrder(Actor self, Order order)
|
||||
{
|
||||
if (!IsReady) return;
|
||||
|
||||
if (order.OrderString == "NuclearMissile")
|
||||
{
|
||||
var silo = self.World.Queries.OwnedBy[self.Owner]
|
||||
.Where(a => a.HasTrait<NukeSilo>())
|
||||
.FirstOrDefault();
|
||||
if (silo != null)
|
||||
silo.Trait<RenderBuilding>().PlayCustomAnim(silo, "active");
|
||||
|
||||
// Play to everyone but the current player
|
||||
if (Owner != Owner.World.LocalPlayer)
|
||||
Sound.Play(Info.LaunchSound);
|
||||
|
||||
silo.Trait<NukeSilo>().Attack(order.TargetLocation);
|
||||
|
||||
FinishActivate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// tag trait for the building
|
||||
class NukeSiloInfo : ITraitInfo
|
||||
{
|
||||
[WeaponReference]
|
||||
public readonly string MissileWeapon = "";
|
||||
public readonly int2 SpawnOffset = int2.Zero;
|
||||
|
||||
public object Create(ActorInitializer init) { return new NukeSilo(init.self, this); }
|
||||
|
||||
public override object Create(ActorInitializer init) { return new NukePower(init.self, this); }
|
||||
}
|
||||
|
||||
class NukeSilo
|
||||
{
|
||||
Actor self;
|
||||
NukeSiloInfo info;
|
||||
|
||||
public NukeSilo(Actor self, NukeSiloInfo info)
|
||||
class NukePower : SupportPower
|
||||
{
|
||||
public NukePower(Actor self, NukePowerInfo info) : base(self, info) { }
|
||||
public override IOrderGenerator OrderGenerator(string order, SupportPowerManager manager)
|
||||
{
|
||||
this.self = self;
|
||||
this.info = info;
|
||||
Sound.PlayToPlayer(manager.self.Owner, Info.SelectTargetSound);
|
||||
return new SelectGenericPowerTarget(order, manager, "nuke", MouseButton.Left);
|
||||
}
|
||||
|
||||
public void Attack(int2 targetLocation)
|
||||
public override void Activate(Actor self, Order order)
|
||||
{
|
||||
self.Trait<RenderBuilding>().PlayCustomAnim(self, "active");
|
||||
// Play to everyone but the current player
|
||||
if (self.Owner != self.World.LocalPlayer)
|
||||
Sound.Play(Info.LaunchSound);
|
||||
|
||||
self.Trait<RenderBuilding>().PlayCustomAnim(self, "active");
|
||||
self.World.AddFrameEndTask(w =>
|
||||
{
|
||||
//FIRE ZE MISSILES
|
||||
w.Add(new NukeLaunch(self, info.MissileWeapon, info.SpawnOffset, targetLocation));
|
||||
w.Add(new NukeLaunch(self, (Info as NukePowerInfo).MissileWeapon, (Info as NukePowerInfo).SpawnOffset, order.TargetLocation));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ using OpenRA.Mods.RA.Air;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
class ParatroopersPowerInfo : SupportPowerInfo
|
||||
public class ParatroopersPowerInfo : SupportPowerInfo
|
||||
{
|
||||
[ActorReference]
|
||||
public string[] DropItems = { };
|
||||
@@ -28,56 +28,39 @@ namespace OpenRA.Mods.RA
|
||||
public override object Create(ActorInitializer init) { return new ParatroopersPower(init.self, this); }
|
||||
}
|
||||
|
||||
class ParatroopersPower : SupportPower, IResolveOrder
|
||||
public class ParatroopersPower : SupportPower
|
||||
{
|
||||
public ParatroopersPower(Actor self, ParatroopersPowerInfo info) : base(self, info) { }
|
||||
|
||||
protected override void OnActivate()
|
||||
public override void Activate(Actor self, Order order)
|
||||
{
|
||||
Self.World.OrderGenerator =
|
||||
new GenericSelectTarget( Owner.PlayerActor, "ParatroopersActivate", "ability" );
|
||||
}
|
||||
|
||||
public void ResolveOrder(Actor self, Order order)
|
||||
{
|
||||
if (!IsAvailable) return;
|
||||
|
||||
if (order.OrderString == "ParatroopersActivate")
|
||||
{
|
||||
DoParadrop(Owner, order.TargetLocation,
|
||||
self.Info.Traits.Get<ParatroopersPowerInfo>().DropItems);
|
||||
|
||||
FinishActivate();
|
||||
}
|
||||
}
|
||||
|
||||
void DoParadrop(Player owner, int2 p, string[] items)
|
||||
{
|
||||
var startPos = owner.World.ChooseRandomEdgeCell();
|
||||
owner.World.AddFrameEndTask(w =>
|
||||
var items = (Info as ParatroopersPowerInfo).DropItems;
|
||||
var startPos = self.World.ChooseRandomEdgeCell();
|
||||
|
||||
self.World.AddFrameEndTask(w =>
|
||||
{
|
||||
var info = (Info as ParatroopersPowerInfo);
|
||||
var flare = info.FlareType != null ? w.CreateActor(info.FlareType, new TypeDictionary
|
||||
{
|
||||
new LocationInit( p ),
|
||||
new OwnerInit( owner ),
|
||||
new LocationInit( order.TargetLocation ),
|
||||
new OwnerInit( self.Owner ),
|
||||
}) : null;
|
||||
|
||||
var a = w.CreateActor(info.UnitType, new TypeDictionary
|
||||
{
|
||||
new LocationInit( startPos ),
|
||||
new OwnerInit( owner ),
|
||||
new FacingInit( Util.GetFacing(p - startPos, 0) ),
|
||||
new OwnerInit( self.Owner ),
|
||||
new FacingInit( Util.GetFacing(order.TargetLocation - startPos, 0) ),
|
||||
new AltitudeInit( Rules.Info[info.UnitType].Traits.Get<PlaneInfo>().CruiseAltitude ),
|
||||
});
|
||||
|
||||
a.CancelActivity();
|
||||
a.QueueActivity(new FlyCircle(p));
|
||||
a.Trait<ParaDrop>().SetLZ(p, flare);
|
||||
a.QueueActivity(new FlyCircle(order.TargetLocation));
|
||||
a.Trait<ParaDrop>().SetLZ(order.TargetLocation, flare);
|
||||
|
||||
var cargo = a.Trait<Cargo>();
|
||||
foreach (var i in items)
|
||||
cargo.Load(a, owner.World.CreateActor(false, i.ToLowerInvariant(), new TypeDictionary { new OwnerInit( a.Owner ) }));
|
||||
cargo.Load(a, self.World.CreateActor(false, i.ToLowerInvariant(), new TypeDictionary { new OwnerInit( a.Owner ) }));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,30 +17,15 @@ namespace OpenRA.Mods.RA
|
||||
public override object Create(ActorInitializer init) { return new SonarPulsePower(init.self, this); }
|
||||
}
|
||||
|
||||
public class SonarPulsePower : SupportPower, IResolveOrder
|
||||
public class SonarPulsePower : SupportPower
|
||||
{
|
||||
public SonarPulsePower(Actor self, SonarPulsePowerInfo info) : base(self, info) { }
|
||||
|
||||
protected override void OnBeginCharging() { }
|
||||
protected override void OnFinishCharging() { Sound.PlayToPlayer(Owner, "pulse1.aud"); }
|
||||
|
||||
protected override void OnActivate()
|
||||
public override void Activate(Actor self, Order order)
|
||||
{
|
||||
Self.World.IssueOrder(new Order("SonarPulse", Owner.PlayerActor, false));
|
||||
}
|
||||
// TODO: Reveal submarines
|
||||
|
||||
public void ResolveOrder(Actor self, Order order)
|
||||
{
|
||||
if (!IsAvailable) return;
|
||||
|
||||
if (order.OrderString == "SonarPulse")
|
||||
{
|
||||
// TODO: Reveal submarines
|
||||
|
||||
// Should this play for all players?
|
||||
Sound.Play("sonpulse.aud");
|
||||
FinishActivate();
|
||||
}
|
||||
// Should this play for all players?
|
||||
Sound.Play("sonpulse.aud");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,55 +19,41 @@ namespace OpenRA.Mods.RA
|
||||
{
|
||||
class SpyPlanePowerInfo : SupportPowerInfo
|
||||
{
|
||||
public readonly float RevealTime = .1f; // minutes
|
||||
public readonly int RevealTime = 6; // seconds
|
||||
public override object Create(ActorInitializer init) { return new SpyPlanePower(init.self,this); }
|
||||
}
|
||||
|
||||
class SpyPlanePower : SupportPower, IResolveOrder
|
||||
class SpyPlanePower : SupportPower
|
||||
{
|
||||
public SpyPlanePower(Actor self, SpyPlanePowerInfo info) : base(self, info) { }
|
||||
|
||||
protected override void OnFinishCharging() { Sound.PlayToPlayer(Owner, "spypln1.aud"); }
|
||||
protected override void OnActivate()
|
||||
public override void Activate(Actor self, Order order)
|
||||
{
|
||||
Self.World.OrderGenerator = new GenericSelectTarget(Owner.PlayerActor, "SpyPlane", "ability");
|
||||
Sound.Play("slcttgt1.aud");
|
||||
}
|
||||
var enterCell = self.World.ChooseRandomEdgeCell();
|
||||
|
||||
public void ResolveOrder(Actor self, Order order)
|
||||
{
|
||||
if (!IsAvailable) return;
|
||||
|
||||
if (order.OrderString == "SpyPlane")
|
||||
var plane = self.World.CreateActor("u2", new TypeDictionary
|
||||
{
|
||||
FinishActivate();
|
||||
new LocationInit( enterCell ),
|
||||
new OwnerInit( self.Owner ),
|
||||
new FacingInit( Util.GetFacing(order.TargetLocation - enterCell, 0) ),
|
||||
new AltitudeInit( Rules.Info["u2"].Traits.Get<PlaneInfo>().CruiseAltitude ),
|
||||
});
|
||||
|
||||
var enterCell = self.World.ChooseRandomEdgeCell();
|
||||
|
||||
var plane = self.World.CreateActor("u2", new TypeDictionary
|
||||
plane.CancelActivity();
|
||||
plane.QueueActivity(Fly.ToCell(order.TargetLocation));
|
||||
plane.QueueActivity(new CallFunc(() => plane.World.AddFrameEndTask( w =>
|
||||
{
|
||||
new LocationInit( enterCell ),
|
||||
new OwnerInit( self.Owner ),
|
||||
new FacingInit( Util.GetFacing(order.TargetLocation - enterCell, 0) ),
|
||||
new AltitudeInit( Rules.Info["u2"].Traits.Get<PlaneInfo>().CruiseAltitude ),
|
||||
});
|
||||
var camera = w.CreateActor("camera", new TypeDictionary
|
||||
{
|
||||
new LocationInit( order.TargetLocation ),
|
||||
new OwnerInit( self.Owner ),
|
||||
});
|
||||
|
||||
plane.CancelActivity();
|
||||
plane.QueueActivity(Fly.ToCell(order.TargetLocation));
|
||||
plane.QueueActivity(new CallFunc(() => plane.World.AddFrameEndTask( w =>
|
||||
{
|
||||
var camera = w.CreateActor("camera", new TypeDictionary
|
||||
{
|
||||
new LocationInit( order.TargetLocation ),
|
||||
new OwnerInit( Owner ),
|
||||
});
|
||||
|
||||
camera.QueueActivity(new Wait((int)(25 * 60 * (Info as SpyPlanePowerInfo).RevealTime)));
|
||||
camera.QueueActivity(new RemoveSelf());
|
||||
})));
|
||||
plane.QueueActivity(new FlyOffMap { Interruptible = false });
|
||||
plane.QueueActivity(new RemoveSelf());
|
||||
}
|
||||
camera.QueueActivity(new Wait(25 * (Info as SpyPlanePowerInfo).RevealTime));
|
||||
camera.QueueActivity(new RemoveSelf());
|
||||
})));
|
||||
plane.QueueActivity(new FlyOffMap { Interruptible = false });
|
||||
plane.QueueActivity(new RemoveSelf());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,136 +14,52 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
public abstract class SupportPowerInfo : ITraitInfo, ITraitPrerequisite<TechTreeInfo>, ITraitPrerequisite<PowerManagerInfo>
|
||||
public abstract class SupportPowerInfo : ITraitInfo
|
||||
{
|
||||
public readonly bool RequiresPower = true;
|
||||
public readonly bool OneShot = false;
|
||||
public readonly float ChargeTime = 0;
|
||||
public readonly int ChargeTime = 0;
|
||||
public readonly string Image = null;
|
||||
public readonly string Description = "";
|
||||
public readonly string LongDesc = "";
|
||||
[ActorReference]
|
||||
public readonly string[] Prerequisites = { };
|
||||
public readonly bool GivenAuto = true;
|
||||
|
||||
public readonly string OrderName;
|
||||
public readonly bool AllowMultiple = false;
|
||||
public readonly bool OneShot = false;
|
||||
|
||||
public readonly string BeginChargeSound = null;
|
||||
public readonly string EndChargeSound = null;
|
||||
public readonly string SelectTargetSound = null;
|
||||
public readonly string LaunchSound = null;
|
||||
|
||||
public readonly string OrderName;
|
||||
public abstract object Create(ActorInitializer init);
|
||||
|
||||
public SupportPowerInfo() { OrderName = GetType().Name + "Order"; }
|
||||
}
|
||||
|
||||
public class SupportPower : ITick, ITechTreeElement
|
||||
public class SupportPower
|
||||
{
|
||||
public readonly Actor self;
|
||||
public readonly SupportPowerInfo Info;
|
||||
public int RemainingTime { get; private set; }
|
||||
public int TotalTime { get { return (int)(Info.ChargeTime * 60 * 25); } }
|
||||
public bool IsUsed;
|
||||
public bool IsAvailable;
|
||||
public bool IsReady { get { return IsAvailable && RemainingTime == 0; } }
|
||||
|
||||
protected readonly Actor Self;
|
||||
protected readonly Player Owner;
|
||||
|
||||
bool notifiedCharging;
|
||||
bool notifiedReady;
|
||||
|
||||
readonly PowerManager PlayerPower;
|
||||
public SupportPower(Actor self, SupportPowerInfo info)
|
||||
{
|
||||
Info = info;
|
||||
RemainingTime = TotalTime;
|
||||
Self = self;
|
||||
Owner = self.Owner;
|
||||
PlayerPower = self.Trait<PowerManager>();
|
||||
|
||||
self.Trait<TechTree>().Add( Info.OrderName, Info.Prerequisites.Select( a => a.ToLowerInvariant() ).ToList(), this );
|
||||
this.self = self;
|
||||
}
|
||||
|
||||
public virtual void Charging(Actor self, string key)
|
||||
{
|
||||
Sound.PlayToPlayer(self.Owner, Info.BeginChargeSound);
|
||||
}
|
||||
|
||||
public virtual void Charged(Actor self, string key)
|
||||
{
|
||||
Sound.PlayToPlayer(self.Owner, Info.EndChargeSound);
|
||||
}
|
||||
|
||||
public void Tick(Actor self)
|
||||
public virtual void Activate(Actor self, Order order) { }
|
||||
public virtual IOrderGenerator OrderGenerator(string order, SupportPowerManager manager)
|
||||
{
|
||||
if (Info.OneShot && IsUsed)
|
||||
return;
|
||||
|
||||
if (Info.GivenAuto)
|
||||
IsAvailable = hasPrerequisites;
|
||||
|
||||
if (IsAvailable && (!Info.RequiresPower || PlayerPower.PowerState == PowerState.Normal))
|
||||
{
|
||||
if (self.World.LobbyInfo.GlobalSettings.AllowCheats && self.Trait<DeveloperMode>().FastCharge) RemainingTime = 0;
|
||||
|
||||
if (RemainingTime > 0) --RemainingTime;
|
||||
if (!notifiedCharging)
|
||||
{
|
||||
Sound.PlayToPlayer(Owner, Info.BeginChargeSound);
|
||||
OnBeginCharging();
|
||||
notifiedCharging = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (RemainingTime == 0
|
||||
&& !notifiedReady)
|
||||
{
|
||||
Sound.PlayToPlayer(Owner, Info.EndChargeSound);
|
||||
OnFinishCharging();
|
||||
notifiedReady = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void FinishActivate()
|
||||
{
|
||||
if (Info.OneShot)
|
||||
{
|
||||
IsUsed = true;
|
||||
IsAvailable = false;
|
||||
}
|
||||
RemainingTime = TotalTime;
|
||||
notifiedReady = false;
|
||||
notifiedCharging = false;
|
||||
}
|
||||
|
||||
public void Give(float charge)
|
||||
{
|
||||
IsAvailable = true;
|
||||
IsUsed = false;
|
||||
RemainingTime = (int)(charge * TotalTime);
|
||||
}
|
||||
|
||||
protected virtual void OnBeginCharging() { }
|
||||
protected virtual void OnFinishCharging() { }
|
||||
protected virtual void OnActivate() { }
|
||||
|
||||
public void Activate()
|
||||
{
|
||||
if (!IsAvailable || !IsReady)
|
||||
return;
|
||||
|
||||
if (Info.RequiresPower && PlayerPower.PowerState != PowerState.Normal)
|
||||
{
|
||||
var eva = Owner.World.WorldActor.Info.Traits.Get<EvaAlertsInfo>();
|
||||
Sound.Play(eva.AbilityInsufficientPower);
|
||||
return;
|
||||
}
|
||||
|
||||
Sound.PlayToPlayer(Owner, Info.SelectTargetSound);
|
||||
OnActivate();
|
||||
}
|
||||
|
||||
bool hasPrerequisites;
|
||||
|
||||
public void PrerequisitesAvailable(string key)
|
||||
{
|
||||
hasPrerequisites = true;
|
||||
}
|
||||
|
||||
public void PrerequisitesUnavailable(string key)
|
||||
{
|
||||
hasPrerequisites = false;
|
||||
Sound.PlayToPlayer(manager.self.Owner, Info.SelectTargetSound);
|
||||
return new SelectGenericPowerTarget(order, manager, "ability", MouseButton.Left);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
205
OpenRA.Mods.RA/SupportPowers/SupportPowerManager.cs
Executable file
205
OpenRA.Mods.RA/SupportPowers/SupportPowerManager.cs
Executable file
@@ -0,0 +1,205 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2010 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see LICENSE.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Linq;
|
||||
using OpenRA.Mods.RA.Buildings;
|
||||
using OpenRA.Traits;
|
||||
using System.Collections.Generic;
|
||||
using OpenRA.Graphics;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
public class SupportPowerManagerInfo : ITraitInfo, ITraitPrerequisite<DeveloperModeInfo>
|
||||
{
|
||||
public object Create(ActorInitializer init) { return new SupportPowerManager(init); }
|
||||
}
|
||||
|
||||
public class SupportPowerManager : ITick, IResolveOrder
|
||||
{
|
||||
public readonly Actor self;
|
||||
public Dictionary<string, SupportPowerInstance> Powers = new Dictionary<string, SupportPowerInstance>();
|
||||
|
||||
public readonly DeveloperMode devMode;
|
||||
public SupportPowerManager(ActorInitializer init)
|
||||
{
|
||||
self = init.self;
|
||||
devMode = init.self.Trait<DeveloperMode>();
|
||||
|
||||
init.world.ActorAdded += ActorAdded;
|
||||
init.world.ActorRemoved += ActorRemoved;
|
||||
}
|
||||
|
||||
void ActorAdded(Actor a)
|
||||
{
|
||||
if (a.Owner != self.Owner || !a.HasTrait<SupportPower>())
|
||||
return;
|
||||
|
||||
foreach (var t in a.TraitsImplementing<SupportPower>())
|
||||
{
|
||||
var key = (t.Info.AllowMultiple) ? t.Info.OrderName+"_"+a.ActorID : t.Info.OrderName;
|
||||
|
||||
if (Powers.ContainsKey(key))
|
||||
{
|
||||
Powers[key].Instances.Add(t);
|
||||
}
|
||||
else
|
||||
{
|
||||
var si = new SupportPowerInstance(key, this)
|
||||
{
|
||||
Instances = new List<SupportPower>() { t },
|
||||
RemainingTime = t.Info.ChargeTime * 25,
|
||||
TotalTime = t.Info.ChargeTime * 25,
|
||||
};
|
||||
|
||||
Powers.Add(key, si);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ActorRemoved(Actor a)
|
||||
{
|
||||
if (a.Owner != self.Owner || !a.HasTrait<SupportPower>())
|
||||
return;
|
||||
|
||||
foreach (var t in a.TraitsImplementing<SupportPower>())
|
||||
{
|
||||
var key = (t.Info.AllowMultiple) ? t.Info.OrderName+"_"+a.ActorID : t.Info.OrderName;
|
||||
Powers[key].Instances.Remove(t);
|
||||
if (Powers[key].Instances.Count == 0 && !Powers[key].Disabled)
|
||||
Powers.Remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
public void Tick(Actor self)
|
||||
{
|
||||
foreach(var power in Powers.Values)
|
||||
power.Tick();
|
||||
}
|
||||
|
||||
public void ResolveOrder(Actor self, Order order)
|
||||
{
|
||||
// order.OrderString is the key of the support power
|
||||
if (Powers.ContainsKey(order.OrderString))
|
||||
Powers[order.OrderString].Activate(order);
|
||||
}
|
||||
|
||||
public void Target(string key)
|
||||
{
|
||||
if (Powers.ContainsKey(key))
|
||||
Powers[key].Target();
|
||||
}
|
||||
|
||||
public class SupportPowerInstance
|
||||
{
|
||||
readonly SupportPowerManager Manager;
|
||||
readonly string Key;
|
||||
|
||||
public List<SupportPower> Instances;
|
||||
public int RemainingTime;
|
||||
public int TotalTime;
|
||||
public bool Active { get; private set; }
|
||||
public bool Disabled { get; private set; }
|
||||
|
||||
public SupportPowerInfo Info { get { return Instances.First().Info; } }
|
||||
public bool Ready { get { return Active && RemainingTime == 0; } }
|
||||
|
||||
public SupportPowerInstance(string key, SupportPowerManager manager)
|
||||
{
|
||||
Manager = manager;
|
||||
Key = key;
|
||||
}
|
||||
|
||||
bool notifiedCharging;
|
||||
bool notifiedReady;
|
||||
public void Tick()
|
||||
{
|
||||
Active = !Disabled && Instances.Any(i => !i.self.TraitsImplementing<IDisable>().Any(d => d.Disabled));
|
||||
|
||||
if (Active)
|
||||
{
|
||||
var power = Instances.First();
|
||||
if (Manager.devMode.FastCharge && RemainingTime > 25)
|
||||
RemainingTime = 25;
|
||||
|
||||
if (RemainingTime > 0) --RemainingTime;
|
||||
if (!notifiedCharging)
|
||||
{
|
||||
power.Charging(power.self, Key);
|
||||
notifiedCharging = true;
|
||||
}
|
||||
|
||||
if (RemainingTime == 0
|
||||
&& !notifiedReady)
|
||||
{
|
||||
power.Charged(power.self, Key);
|
||||
notifiedReady = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Target()
|
||||
{
|
||||
if (!Ready)
|
||||
return;
|
||||
|
||||
Manager.self.World.OrderGenerator = Instances.First().OrderGenerator(Key, Manager);
|
||||
}
|
||||
|
||||
public void Activate(Order order)
|
||||
{
|
||||
if (!Ready)
|
||||
return;
|
||||
|
||||
var power = Instances.First();
|
||||
// Note: order.Subject is the *player* actor
|
||||
power.Activate(power.self, order);
|
||||
RemainingTime = TotalTime;
|
||||
notifiedCharging = notifiedReady = false;
|
||||
|
||||
if (Info.OneShot)
|
||||
Disabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class SelectGenericPowerTarget : IOrderGenerator
|
||||
{
|
||||
readonly SupportPowerManager manager;
|
||||
readonly string order;
|
||||
readonly string cursor;
|
||||
readonly MouseButton expectedButton;
|
||||
|
||||
public SelectGenericPowerTarget(string order, SupportPowerManager manager, string cursor, MouseButton button)
|
||||
{
|
||||
this.manager = manager;
|
||||
this.order = order;
|
||||
this.cursor = cursor;
|
||||
expectedButton = button;
|
||||
}
|
||||
|
||||
public IEnumerable<Order> Order(World world, int2 xy, MouseInput mi)
|
||||
{
|
||||
world.CancelInputMode();
|
||||
if (mi.Button == expectedButton && world.Map.IsInMap(xy))
|
||||
yield return new Order(order, manager.self, false) { TargetLocation = xy };
|
||||
}
|
||||
|
||||
public virtual void Tick(World world)
|
||||
{
|
||||
// Cancel the OG if we can't use the power
|
||||
if (!manager.Powers.ContainsKey(order))
|
||||
world.CancelInputMode();
|
||||
}
|
||||
|
||||
public void RenderBeforeWorld(WorldRenderer wr, World world) { }
|
||||
public void RenderAfterWorld(WorldRenderer wr, World world) { }
|
||||
public string GetCursor(World world, int2 xy, MouseInput mi) { return world.Map.IsInMap(xy) ? cursor : "generic-blocked"; }
|
||||
}
|
||||
}
|
||||
@@ -10,10 +10,11 @@
|
||||
|
||||
using OpenRA.GameRules;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Mods.RA.Render;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
class TakeCoverInfo : TraitInfo<TakeCover> { }
|
||||
class TakeCoverInfo : TraitInfo<TakeCover>, ITraitPrerequisite<RenderInfantryInfo> { }
|
||||
|
||||
// infantry prone behavior
|
||||
class TakeCover : ITick, INotifyDamage, IDamageModifier, ISpeedModifier
|
||||
@@ -29,17 +30,45 @@ namespace OpenRA.Mods.RA
|
||||
|
||||
public void Damaged(Actor self, AttackInfo e)
|
||||
{
|
||||
if (e.Damage > 0) /* fix to allow healing via `damage` */
|
||||
if (e.Damage > 0) /* Don't go prone when healed */
|
||||
{
|
||||
if (e.Warhead == null || !e.Warhead.PreventProne)
|
||||
remainingProneTime = defaultProneTime;
|
||||
}
|
||||
}
|
||||
|
||||
public void Tick(Actor self)
|
||||
{
|
||||
if (IsProne)
|
||||
--remainingProneTime;
|
||||
if (!IsProne)
|
||||
return;
|
||||
|
||||
remainingProneTime--;
|
||||
|
||||
var ri = self.Trait<RenderInfantry>();
|
||||
|
||||
// Mobile.IsMoving isn't set to true until after the first move tick
|
||||
// so we need a hack here to prevent a single frame of stand state
|
||||
|
||||
if (IsProne && (ri.State == RenderInfantry.AnimationState.Idle ||
|
||||
ri.State == RenderInfantry.AnimationState.Waiting ||
|
||||
ri.anim.CurrentSequence.Name == "stand"))
|
||||
ri.anim.PlayFetchIndex("crawl", () => 0);
|
||||
else if (!IsProne && (ri.State == RenderInfantry.AnimationState.Idle ||
|
||||
ri.State == RenderInfantry.AnimationState.Waiting ||
|
||||
ri.anim.CurrentSequence.Name == "stand"))
|
||||
ri.anim.Play("stand");
|
||||
|
||||
if (ri.anim.CurrentSequence.Name == "run" && IsProne)
|
||||
ri.anim.ReplaceAnim("crawl");
|
||||
else if (ri.anim.CurrentSequence.Name == "crawl" && !IsProne)
|
||||
ri.anim.ReplaceAnim("run");
|
||||
|
||||
if (ri.anim.CurrentSequence.Name == "shoot" && IsProne)
|
||||
ri.anim.ReplaceAnim("prone-shoot");
|
||||
else if (ri.anim.CurrentSequence.Name == "prone-shoot" && !IsProne)
|
||||
ri.anim.ReplaceAnim("shoot");
|
||||
}
|
||||
|
||||
|
||||
public float GetDamageModifier(Actor attacker, WarheadInfo warhead )
|
||||
{
|
||||
return IsProne ? proneDamage : 1f;
|
||||
|
||||
@@ -54,11 +54,11 @@ namespace OpenRA.Mods.RA.Widgets
|
||||
{
|
||||
this.world = world;
|
||||
}
|
||||
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
|
||||
cantBuild = new Animation("clock");
|
||||
cantBuild.PlayFetchIndex("idle", () => 0);
|
||||
ready = new Animation("pips");
|
||||
@@ -66,12 +66,12 @@ namespace OpenRA.Mods.RA.Widgets
|
||||
clock = new Animation("clock");
|
||||
|
||||
iconSprites = Rules.Info.Values
|
||||
.Where(u => u.Traits.Contains<BuildableInfo>() && u.Name[0] != '^' )
|
||||
.Where(u => u.Traits.Contains<BuildableInfo>() && u.Name[0] != '^')
|
||||
.ToDictionary(
|
||||
u => u.Name,
|
||||
u => SpriteSheetBuilder.LoadAllSprites(u.Traits.Get<TooltipInfo>().Icon ?? (u.Name + "icon"))[0]);
|
||||
|
||||
IsVisible = () => { return CurrentQueue != null || (CurrentQueue == null && !paletteOpen); };
|
||||
|
||||
IsVisible = () => { return CurrentQueue != null || (CurrentQueue == null && !paletteOpen); };
|
||||
}
|
||||
|
||||
public override Rectangle EventBounds
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
* see LICENSE.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
@@ -14,8 +15,9 @@ using System.Linq;
|
||||
using OpenRA.FileFormats;
|
||||
using OpenRA.Network;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Widgets;
|
||||
|
||||
namespace OpenRA.Widgets.Delegates
|
||||
namespace OpenRA.Mods.RA.Widgets.Delegates
|
||||
{
|
||||
public class LobbyDelegate : IWidgetDelegate
|
||||
{
|
||||
|
||||
@@ -21,14 +21,15 @@ namespace OpenRA.Mods.RA.Widgets.Delegates
|
||||
static bool FirstInit = true;
|
||||
|
||||
[ObjectCreator.UseCtor]
|
||||
public MainMenuButtonsDelegate( [ObjectCreator.Param] Widget widget )
|
||||
public MainMenuButtonsDelegate([ObjectCreator.Param] Widget widget)
|
||||
{
|
||||
// Main menu is the default window
|
||||
widget.GetWidget( "MAINMENU_BUTTON_JOIN" ).OnMouseUp = mi => { Widget.OpenWindow( "JOINSERVER_BG" ); return true; };
|
||||
widget.GetWidget( "MAINMENU_BUTTON_CREATE" ).OnMouseUp = mi => { Widget.OpenWindow( "CREATESERVER_BG" ); return true; };
|
||||
widget.GetWidget( "MAINMENU_BUTTON_SETTINGS" ).OnMouseUp = mi => { Widget.OpenWindow( "SETTINGS_MENU" ); return true; };
|
||||
widget.GetWidget( "MAINMENU_BUTTON_MUSIC" ).OnMouseUp = mi => { Widget.OpenWindow( "MUSIC_MENU" ); return true; };
|
||||
widget.GetWidget( "MAINMENU_BUTTON_QUIT" ).OnMouseUp = mi => { Game.Exit(); return true; };
|
||||
widget.GetWidget("MAINMENU_BUTTON_JOIN").OnMouseUp = mi => { Widget.OpenWindow("JOINSERVER_BG"); return true; };
|
||||
widget.GetWidget("MAINMENU_BUTTON_CREATE").OnMouseUp = mi => { Widget.OpenWindow("CREATESERVER_BG"); return true; };
|
||||
widget.GetWidget("MAINMENU_BUTTON_SETTINGS").OnMouseUp = mi => { Widget.OpenWindow("SETTINGS_MENU"); return true; };
|
||||
widget.GetWidget("MAINMENU_BUTTON_MUSIC").OnMouseUp = mi => { Widget.OpenWindow("MUSIC_MENU"); return true; };
|
||||
widget.GetWidget("MAINMENU_BUTTON_REPLAY_VIEWER").OnMouseUp = mi => { Widget.OpenWindow("REPLAYBROWSER_BG"); return true; };
|
||||
widget.GetWidget("MAINMENU_BUTTON_QUIT").OnMouseUp = mi => { Game.Exit(); return true; };
|
||||
|
||||
var version = widget.GetWidget<LabelWidget>("VERSION_STRING");
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user