Use Tuple syntax

This commit is contained in:
teinarss
2020-08-02 13:41:03 +02:00
committed by Paul Chote
parent 8a74f6ea18
commit 19b02875c7
90 changed files with 738 additions and 826 deletions

View File

@@ -54,10 +54,10 @@ namespace OpenRA.Graphics
public static IReadOnlyDictionary<string, Collection> Collections { get; private set; }
static Dictionary<string, Collection> collections;
static Dictionary<string, Pair<Sheet, int>> cachedSheets;
static Dictionary<string, (Sheet Sheet, int Density)> cachedSheets;
static Dictionary<string, Dictionary<string, Sprite>> cachedSprites;
static Dictionary<string, Sprite[]> cachedPanelSprites;
static Dictionary<Collection, Pair<Sheet, int>> cachedCollectionSheets;
static Dictionary<Collection, (Sheet Sheet, int)> cachedCollectionSheets;
static IReadOnlyFileSystem fileSystem;
static float dpiScale = 1;
@@ -72,10 +72,10 @@ namespace OpenRA.Graphics
fileSystem = modData.DefaultFileSystem;
collections = new Dictionary<string, Collection>();
cachedSheets = new Dictionary<string, Pair<Sheet, int>>();
cachedSheets = new Dictionary<string, (Sheet, int)>();
cachedSprites = new Dictionary<string, Dictionary<string, Sprite>>();
cachedPanelSprites = new Dictionary<string, Sprite[]>();
cachedCollectionSheets = new Dictionary<Collection, Pair<Sheet, int>>();
cachedCollectionSheets = new Dictionary<Collection, (Sheet, int)>();
Collections = new ReadOnlyDictionary<string, Collection>(collections);
@@ -91,7 +91,7 @@ namespace OpenRA.Graphics
{
if (cachedSheets != null)
foreach (var sheet in cachedSheets.Values)
sheet.First.Dispose();
sheet.Sheet.Dispose();
collections = null;
cachedSheets = null;
@@ -108,12 +108,10 @@ namespace OpenRA.Graphics
collections.Add(name, FieldLoader.Load<Collection>(yaml));
}
static Pair<Sheet, int> SheetForCollection(Collection c)
static (Sheet Sheet, int Density) SheetForCollection(Collection c)
{
Pair<Sheet, int> sheetDensity;
// Outer cache avoids recalculating image names
if (!cachedCollectionSheets.TryGetValue(c, out sheetDensity))
if (!cachedCollectionSheets.TryGetValue(c, out (Sheet, int) sheetDensity))
{
var image = c.Image;
var density = 1;
@@ -137,7 +135,7 @@ namespace OpenRA.Graphics
sheet.GetTexture().ScaleFilter = TextureScaleFilter.Linear;
sheetDensity = Pair.New(sheet, density);
sheetDensity = (sheet, density);
cachedSheets.Add(image, sheetDensity);
}
@@ -153,13 +151,10 @@ namespace OpenRA.Graphics
return null;
// Cached sprite
Dictionary<string, Sprite> cachedCollection;
Sprite sprite;
if (cachedSprites.TryGetValue(collectionName, out cachedCollection) && cachedCollection.TryGetValue(imageName, out sprite))
if (cachedSprites.TryGetValue(collectionName, out var cachedCollection) && cachedCollection.TryGetValue(imageName, out var sprite))
return sprite;
Collection collection;
if (!collections.TryGetValue(collectionName, out collection))
if (!collections.TryGetValue(collectionName, out var collection))
{
Log.Write("debug", "Could not find collection '{0}'", collectionName);
return null;
@@ -177,7 +172,7 @@ namespace OpenRA.Graphics
cachedSprites.Add(collectionName, cachedCollection);
}
var image = new Sprite(sheetDensity.First, sheetDensity.Second * mi, TextureChannel.RGBA, 1f / sheetDensity.Second);
var image = new Sprite(sheetDensity.Sheet, sheetDensity.Density * mi, TextureChannel.RGBA, 1f / sheetDensity.Density);
cachedCollection.Add(imageName, image);
return image;
@@ -189,12 +184,10 @@ namespace OpenRA.Graphics
return null;
// Cached sprite
Sprite[] cachedSprites;
if (cachedPanelSprites.TryGetValue(collectionName, out cachedSprites))
if (cachedPanelSprites.TryGetValue(collectionName, out var cachedSprites))
return cachedSprites;
Collection collection;
if (!collections.TryGetValue(collectionName, out collection))
if (!collections.TryGetValue(collectionName, out var collection))
{
Log.Write("debug", "Could not find collection '{0}'", collectionName);
return null;
@@ -214,20 +207,20 @@ namespace OpenRA.Graphics
var pr = collection.PanelRegion;
var ps = collection.PanelSides;
var sides = new[]
var sides = new (PanelSides PanelSides, Rectangle Bounds)[]
{
Pair.New(PanelSides.Top | PanelSides.Left, new Rectangle(pr[0], pr[1], pr[2], pr[3])),
Pair.New(PanelSides.Top, new Rectangle(pr[0] + pr[2], pr[1], pr[4], pr[3])),
Pair.New(PanelSides.Top | PanelSides.Right, new Rectangle(pr[0] + pr[2] + pr[4], pr[1], pr[6], pr[3])),
Pair.New(PanelSides.Left, new Rectangle(pr[0], pr[1] + pr[3], pr[2], pr[5])),
Pair.New(PanelSides.Center, new Rectangle(pr[0] + pr[2], pr[1] + pr[3], pr[4], pr[5])),
Pair.New(PanelSides.Right, new Rectangle(pr[0] + pr[2] + pr[4], pr[1] + pr[3], pr[6], pr[5])),
Pair.New(PanelSides.Bottom | PanelSides.Left, new Rectangle(pr[0], pr[1] + pr[3] + pr[5], pr[2], pr[7])),
Pair.New(PanelSides.Bottom, new Rectangle(pr[0] + pr[2], pr[1] + pr[3] + pr[5], pr[4], pr[7])),
Pair.New(PanelSides.Bottom | PanelSides.Right, new Rectangle(pr[0] + pr[2] + pr[4], pr[1] + pr[3] + pr[5], pr[6], pr[7]))
(PanelSides.Top | PanelSides.Left, new Rectangle(pr[0], pr[1], pr[2], pr[3])),
(PanelSides.Top, new Rectangle(pr[0] + pr[2], pr[1], pr[4], pr[3])),
(PanelSides.Top | PanelSides.Right, new Rectangle(pr[0] + pr[2] + pr[4], pr[1], pr[6], pr[3])),
(PanelSides.Left, new Rectangle(pr[0], pr[1] + pr[3], pr[2], pr[5])),
(PanelSides.Center, new Rectangle(pr[0] + pr[2], pr[1] + pr[3], pr[4], pr[5])),
(PanelSides.Right, new Rectangle(pr[0] + pr[2] + pr[4], pr[1] + pr[3], pr[6], pr[5])),
(PanelSides.Bottom | PanelSides.Left, new Rectangle(pr[0], pr[1] + pr[3] + pr[5], pr[2], pr[7])),
(PanelSides.Bottom, new Rectangle(pr[0] + pr[2], pr[1] + pr[3] + pr[5], pr[4], pr[7])),
(PanelSides.Bottom | PanelSides.Right, new Rectangle(pr[0] + pr[2] + pr[4], pr[1] + pr[3] + pr[5], pr[6], pr[7]))
};
sprites = sides.Select(x => ps.HasSide(x.First) ? new Sprite(sheetDensity.First, sheetDensity.Second * x.Second, TextureChannel.RGBA, 1f / sheetDensity.Second) : null)
sprites = sides.Select(x => ps.HasSide(x.PanelSides) ? new Sprite(sheetDensity.Sheet, sheetDensity.Density * x.Bounds, TextureChannel.RGBA, 1f / sheetDensity.Density) : null)
.ToArray();
}
else
@@ -256,8 +249,7 @@ namespace OpenRA.Graphics
if (string.IsNullOrEmpty(collectionName))
return new Size(0, 0);
Collection collection;
if (!collections.TryGetValue(collectionName, out collection))
if (!collections.TryGetValue(collectionName, out var collection))
{
Log.Write("debug", "Could not find collection '{0}'", collectionName);
return new Size(0, 0);

View File

@@ -48,7 +48,7 @@ namespace OpenRA.Graphics
readonly Dictionary<Sheet, IFrameBuffer> mappedBuffers = new Dictionary<Sheet, IFrameBuffer>();
readonly Stack<KeyValuePair<Sheet, IFrameBuffer>> unmappedBuffers = new Stack<KeyValuePair<Sheet, IFrameBuffer>>();
readonly List<Pair<Sheet, Action>> doRender = new List<Pair<Sheet, Action>>();
readonly List<(Sheet Sheet, Action Func)> doRender = new List<(Sheet, Action)>();
SheetBuilder sheetBuilderForFrame;
bool isInFrame;
@@ -180,7 +180,7 @@ namespace OpenRA.Graphics
var correctionTransform = Util.MatrixMultiply(translateMtx, FlipMtx);
var shadowCorrectionTransform = Util.MatrixMultiply(shadowTranslateMtx, ShadowScaleFlipMtx);
doRender.Add(Pair.New<Sheet, Action>(sprite.Sheet, () =>
doRender.Add((sprite.Sheet, () =>
{
foreach (var m in models)
{
@@ -324,16 +324,16 @@ namespace OpenRA.Graphics
foreach (var v in doRender)
{
// Change sheet
if (v.First != currentSheet)
if (v.Sheet != currentSheet)
{
if (fbo != null)
DisableFrameBuffer(fbo);
currentSheet = v.First;
currentSheet = v.Sheet;
fbo = EnableFrameBuffer(currentSheet);
}
v.Second();
v.Func();
}
if (fbo != null)

View File

@@ -47,8 +47,8 @@ namespace OpenRA.Graphics
remapRamp = ramp.Select(r => r - ramp[rampMaxIndex]);
}
remapColors = remapRamp.Select((x, i) => Pair.New(baseIndex + i, Exts.ColorLerp(x / (float)ramp.Length, c1, c2)))
.ToDictionary(u => u.First, u => u.Second);
remapColors = remapRamp.Select((x, i) => (baseIndex + i, Exts.ColorLerp(x / (float)ramp.Length, c1, c2)))
.ToDictionary(u => u.Item1, u => u.Item2);
}
public Color GetRemappedColor(Color original, int index)

View File

@@ -23,8 +23,8 @@ namespace OpenRA.Graphics
readonly SheetBuilder builder;
readonly Func<string, float> lineWidth;
readonly IFont font;
readonly Cache<Pair<char, Color>, GlyphInfo> glyphs;
readonly Cache<Tuple<char, Color, int>, Sprite> contrastGlyphs;
readonly Cache<(char C, Color Color), GlyphInfo> glyphs;
readonly Cache<(char, Color, int), Sprite> contrastGlyphs;
readonly Cache<int, float[]> dilationElements;
float deviceScale;
@@ -40,12 +40,12 @@ namespace OpenRA.Graphics
font = Game.Renderer.CreateFont(data);
glyphs = new Cache<Pair<char, Color>, GlyphInfo>(CreateGlyph, Pair<char, Color>.EqualityComparer);
contrastGlyphs = new Cache<Tuple<char, Color, int>, Sprite>(CreateContrastGlyph);
glyphs = new Cache<(char, Color), GlyphInfo>(CreateGlyph);
contrastGlyphs = new Cache<(char, Color, int), Sprite>(CreateContrastGlyph);
dilationElements = new Cache<int, float[]>(CreateCircularWeightMap);
// PERF: Cache these delegates for Measure calls.
Func<char, float> characterWidth = character => glyphs[Pair.New(character, Color.White)].Advance;
Func<char, float> characterWidth = character => glyphs[(character, Color.White)].Advance;
lineWidth = line => line.Sum(characterWidth) / deviceScale;
if (size <= 24)
@@ -65,7 +65,7 @@ namespace OpenRA.Graphics
{
using (new PerfTimer("PrecacheColor {0} {1}px {2}".F(name, size, c)))
for (var n = (char)0x20; n < (char)0x7f; n++)
if (glyphs[Pair.New(n, c)] == null)
if (glyphs[(n, c)] == null)
throw new InvalidOperationException();
}
@@ -87,12 +87,12 @@ namespace OpenRA.Graphics
continue;
}
var g = glyphs[Pair.New(s, Color.Black)];
var g = glyphs[(s, Color.Black)];
// Convert screen coordinates back to UI coordinates for drawing
if (g.Sprite != null)
{
var contrastSprite = contrastGlyphs[Tuple.Create(s, contrastColor, screenContrast)];
var contrastSprite = contrastGlyphs[(s, contrastColor, screenContrast)];
Game.Renderer.RgbaSpriteRenderer.DrawSprite(contrastSprite,
(screen + g.Offset - contrastVector) / deviceScale,
contrastSprite.Size / deviceScale);
@@ -118,7 +118,7 @@ namespace OpenRA.Graphics
continue;
}
var g = glyphs[Pair.New(s, c)];
var g = glyphs[(s, c)];
// Convert screen coordinates back to UI coordinates for drawing
if (g.Sprite != null)
@@ -155,7 +155,7 @@ namespace OpenRA.Graphics
continue;
}
var g = glyphs[Pair.New(s, c)];
var g = glyphs[(s, c)];
if (g.Sprite != null)
{
var tl = new float2(
@@ -241,9 +241,9 @@ namespace OpenRA.Graphics
return new int2((int)Math.Ceiling(lines.Max(lineWidth)), lines.Length * size);
}
GlyphInfo CreateGlyph(Pair<char, Color> c)
GlyphInfo CreateGlyph((char C, Color Color) c)
{
var glyph = font.CreateGlyph(c.First, size, deviceScale);
var glyph = font.CreateGlyph(c.C, size, deviceScale);
if (glyph.Data == null)
{
@@ -274,7 +274,7 @@ namespace OpenRA.Graphics
if (p != 0)
{
var q = destStride * (j + s.Bounds.Top) + 4 * (i + s.Bounds.Left);
var pmc = Util.PremultiplyAlpha(Color.FromArgb(p, c.Second));
var pmc = Util.PremultiplyAlpha(Color.FromArgb(p, c.Color));
dest[q] = pmc.B;
dest[q + 1] = pmc.G;
@@ -347,10 +347,10 @@ namespace OpenRA.Graphics
return elem;
}
Sprite CreateContrastGlyph(Tuple<char, Color, int> c)
Sprite CreateContrastGlyph((char, Color, int) c)
{
// Source glyph color doesn't matter, so use black
var glyph = glyphs[Pair.New(c.Item1, Color.Black)];
var glyph = glyphs[(c.Item1, Color.Black)];
var color = c.Item2;
var r = c.Item3;

View File

@@ -34,9 +34,9 @@ namespace OpenRA
mods = GetInstalledMods(searchPaths, explicitPaths);
}
static IEnumerable<Pair<string, string>> GetCandidateMods(IEnumerable<string> searchPaths)
static IEnumerable<(string Id, string Path)> GetCandidateMods(IEnumerable<string> searchPaths)
{
var mods = new List<Pair<string, string>>();
var mods = new List<(string, string)>();
foreach (var path in searchPaths)
{
try
@@ -47,7 +47,7 @@ namespace OpenRA
var directory = new DirectoryInfo(resolved);
foreach (var subdir in directory.EnumerateDirectories())
mods.Add(Pair.New(subdir.Name, subdir.FullName));
mods.Add((subdir.Name, subdir.FullName));
}
catch (Exception e)
{
@@ -88,13 +88,13 @@ namespace OpenRA
{
var ret = new Dictionary<string, Manifest>();
var candidates = GetCandidateMods(searchPaths)
.Concat(explicitPaths.Select(p => Pair.New(Path.GetFileNameWithoutExtension(p), p)));
.Concat(explicitPaths.Select(p => (Id: Path.GetFileNameWithoutExtension(p), Path: p)));
foreach (var pair in candidates)
{
var mod = LoadMod(pair.First, pair.Second);
var mod = LoadMod(pair.Id, pair.Path);
if (mod != null)
ret[pair.First] = mod;
ret[pair.Id] = mod;
}
return ret;

View File

@@ -662,7 +662,7 @@ namespace OpenRA
return dataStream.ToArray();
}
public Pair<Color, Color> GetTerrainColorPair(MPos uv)
public (Color Left, Color Right) GetTerrainColorPair(MPos uv)
{
Color left, right;
var tileset = Rules.TileSet;
@@ -687,7 +687,7 @@ namespace OpenRA
else
left = right = Color.Black;
return Pair.New(left, right);
return (left, right);
}
public byte[] SavePreview()
@@ -695,7 +695,7 @@ namespace OpenRA
var tileset = Rules.TileSet;
var actorTypes = Rules.Actors.Values.Where(a => a.HasTraitInfo<IMapPreviewSignatureInfo>());
var actors = ActorDefinitions.Where(a => actorTypes.Where(ai => ai.Name == a.Value.Value).Any());
var positions = new List<Pair<MPos, Color>>();
var positions = new List<(MPos Position, Color Color)>();
foreach (var actor in actors)
{
var s = new ActorReference(actor.Value.Value, actor.Value.ToDictionary());
@@ -729,7 +729,7 @@ namespace OpenRA
var stride = bitmapWidth * 4;
var pxStride = 4;
var minimapData = new byte[stride * height];
Pair<Color, Color> terrainColor = default(Pair<Color, Color>);
(Color Left, Color Right) terrainColor = default((Color, Color));
for (var y = 0; y < height; y++)
{
@@ -737,8 +737,8 @@ namespace OpenRA
{
var uv = new MPos(x + Bounds.Left, y + Bounds.Top);
// FirstOrDefault will return a Pair(MPos.Zero, Color.Transparent) if positions is empty
var actorColor = positions.FirstOrDefault(ap => ap.First == uv).Second;
// FirstOrDefault will return a (MPos.Zero, Color.Transparent) if positions is empty
var actorColor = positions.FirstOrDefault(ap => ap.Position == uv).Color;
if (actorColor.A == 0)
terrainColor = GetTerrainColorPair(uv);
@@ -750,7 +750,7 @@ namespace OpenRA
if (x + dx > 0)
{
var z = y * stride + xOffset - pxStride;
var c = actorColor.A == 0 ? terrainColor.First : actorColor;
var c = actorColor.A == 0 ? terrainColor.Left : actorColor;
minimapData[z++] = c.R;
minimapData[z++] = c.G;
minimapData[z++] = c.B;
@@ -760,7 +760,7 @@ namespace OpenRA
if (xOffset < stride)
{
var z = y * stride + xOffset;
var c = actorColor.A == 0 ? terrainColor.Second : actorColor;
var c = actorColor.A == 0 ? terrainColor.Right : actorColor;
minimapData[z++] = c.R;
minimapData[z++] = c.G;
minimapData[z++] = c.B;
@@ -770,7 +770,7 @@ namespace OpenRA
else
{
var z = y * stride + pxStride * x;
var c = actorColor.A == 0 ? terrainColor.First : actorColor;
var c = actorColor.A == 0 ? terrainColor.Left : actorColor;
minimapData[z++] = c.R;
minimapData[z++] = c.G;
minimapData[z++] = c.B;

View File

@@ -89,7 +89,7 @@ namespace OpenRA
public bool DefinesUnsafeCustomRules { get; private set; }
public bool RulesLoaded { get; private set; }
public void SetRulesetGenerator(ModData modData, Func<Pair<Ruleset, bool>> generator)
public void SetRulesetGenerator(ModData modData, Func<(Ruleset Ruleset, bool DefinesUnsafeCustomRules)> generator)
{
InvalidCustomRules = false;
RulesLoaded = false;
@@ -106,8 +106,8 @@ namespace OpenRA
try
{
var ret = generator();
DefinesUnsafeCustomRules = ret.Second;
return ret.First;
DefinesUnsafeCustomRules = ret.DefinesUnsafeCustomRules;
return ret.Ruleset;
}
catch (Exception e)
{
@@ -318,7 +318,7 @@ namespace OpenRA
voiceDefinitions, notificationDefinitions, musicDefinitions, sequenceDefinitions, modelSequenceDefinitions);
var flagged = Ruleset.DefinesUnsafeCustomRules(modData, this, ruleDefinitions,
weaponDefinitions, voiceDefinitions, notificationDefinitions, sequenceDefinitions);
return Pair.New(rules, flagged);
return (rules, flagged);
});
if (p.Contains("map.png"))
@@ -402,7 +402,7 @@ namespace OpenRA
voiceDefinitions, notificationDefinitions, musicDefinitions, sequenceDefinitions, modelSequenceDefinitions);
var flagged = Ruleset.DefinesUnsafeCustomRules(modData, this, ruleDefinitions,
weaponDefinitions, voiceDefinitions, notificationDefinitions, sequenceDefinitions);
return Pair.New(rules, flagged);
return (rules, flagged);
});
}
catch (Exception e)

View File

@@ -115,7 +115,7 @@ namespace OpenRA.Network
Connection.SendImmediate(localImmediateOrders.Select(o => o.Serialize()));
localImmediateOrders.Clear();
var immediatePackets = new List<Pair<int, byte[]>>();
var immediatePackets = new List<(int ClientId, byte[] Packet)>();
Connection.Receive(
(clientId, packet) =>
@@ -126,16 +126,16 @@ namespace OpenRA.Network
else if (packet.Length >= 5 && packet[4] == (byte)OrderType.SyncHash)
CheckSync(packet);
else if (frame == 0)
immediatePackets.Add(Pair.New(clientId, packet));
immediatePackets.Add((clientId, packet));
else
frameData.AddFrameOrders(clientId, frame, packet);
});
foreach (var p in immediatePackets)
{
foreach (var o in p.Second.ToOrderList(World))
foreach (var o in p.Packet.ToOrderList(World))
{
UnitOrders.ProcessOrder(this, World, p.First, o);
UnitOrders.ProcessOrder(this, World, p.ClientId, o);
// A mod switch or other event has pulled the ground from beneath us
if (disposed)

View File

@@ -14,7 +14,6 @@ using System.Collections.Generic;
using System.IO;
using System.Net;
using OpenRA.FileFormats;
using OpenRA.Primitives;
namespace OpenRA.Network
{
@@ -23,7 +22,7 @@ namespace OpenRA.Network
class Chunk
{
public int Frame;
public Pair<int, byte[]>[] Packets;
public (int ClientId, byte[] Packet)[] Packets;
}
Queue<Chunk> chunks = new Queue<Chunk>();
@@ -55,7 +54,7 @@ namespace OpenRA.Network
// to avoid issues with all immediate orders being resolved on the first tick.
using (var rs = File.OpenRead(replayFilename))
{
var packets = new List<Pair<int, byte[]>>();
var packets = new List<(int ClientId, byte[] Packet)>();
var chunk = new Chunk();
@@ -67,7 +66,7 @@ namespace OpenRA.Network
var packetLen = rs.ReadInt32();
var packet = rs.ReadBytes(packetLen);
var frame = BitConverter.ToInt32(packet, 0);
packets.Add(Pair.New(client, packet));
packets.Add((client, packet));
if (frame != int.MaxValue &&
(!lastClientsFrame.ContainsKey(client) || frame > lastClientsFrame[client]))
@@ -111,13 +110,13 @@ namespace OpenRA.Network
{
foreach (var tmpPacketPair in tmpChunk.Packets)
{
var client = tmpPacketPair.First;
var client = tmpPacketPair.ClientId;
// Don't replace the final disconnection packet - we still want this to end the replay.
if (client == lastClientToDisconnect)
continue;
var packet = tmpPacketPair.Second;
var packet = tmpPacketPair.Packet;
if (packet.Length == 5 && packet[4] == (byte)OrderType.Disconnect)
{
var lastClientFrame = lastClientsFrame[client];
@@ -156,7 +155,7 @@ namespace OpenRA.Network
while (chunks.Count != 0 && chunks.Peek().Frame <= ordersFrame)
foreach (var o in chunks.Dequeue().Packets)
packetFn(o.First, o.Second);
packetFn(o.ClientId, o.Packet);
}
public void Dispose() { }

View File

@@ -29,7 +29,7 @@ namespace OpenRA.Network
readonly Report[] syncReports = new Report[NumSyncReports];
int curIndex = 0;
static Pair<string[], Values> DumpSyncTrait(ISync sync)
static (string[] Names, Values Values) DumpSyncTrait(ISync sync)
{
var type = sync.GetType();
TypeInfo typeInfo;
@@ -41,7 +41,7 @@ namespace OpenRA.Network
foreach (var func in typeInfo.SerializableCopyOfMemberFunctions)
values[index++] = func(sync);
return Pair.New(typeInfo.Names, values);
return (typeInfo.Names, values);
}
public SyncReport(OrderManager orderManager)
@@ -120,9 +120,9 @@ namespace OpenRA.Network
Log.Write("sync", "\t {0} {1} {2} {3} ({4})".F(a.ActorID, a.Type, a.Owner, a.Trait, a.Hash));
var nvp = a.NamesValues;
for (int i = 0; i < nvp.First.Length; i++)
if (nvp.Second[i] != null)
Log.Write("sync", "\t\t {0}: {1}".F(nvp.First[i], nvp.Second[i]));
for (int i = 0; i < nvp.Names.Length; i++)
if (nvp.Values[i] != null)
Log.Write("sync", "\t\t {0}: {1}".F(nvp.Names[i], nvp.Values[i]));
}
Log.Write("sync", "Synced Effects:");
@@ -131,9 +131,9 @@ namespace OpenRA.Network
Log.Write("sync", "\t {0} ({1})", e.Name, e.Hash);
var nvp = e.NamesValues;
for (int i = 0; i < nvp.First.Length; i++)
if (nvp.Second[i] != null)
Log.Write("sync", "\t\t {0}: {1}".F(nvp.First[i], nvp.Second[i]));
for (int i = 0; i < nvp.Names.Length; i++)
if (nvp.Values[i] != null)
Log.Write("sync", "\t\t {0}: {1}".F(nvp.Names[i], nvp.Values[i]));
}
Log.Write("sync", "Orders Issued:");
@@ -163,14 +163,14 @@ namespace OpenRA.Network
public string Owner;
public string Trait;
public int Hash;
public Pair<string[], Values> NamesValues;
public (string[] Names, Values Values) NamesValues;
}
struct EffectReport
{
public string Name;
public int Hash;
public Pair<string[], Values> NamesValues;
public (string[] Names, Values Values) NamesValues;
}
struct TypeInfo

View File

@@ -26,7 +26,7 @@ namespace OpenRA
readonly Cache<string, Type> typeCache;
readonly Cache<Type, ConstructorInfo> ctorCache;
readonly Pair<Assembly, string>[] assemblies;
readonly (Assembly Assembly, string Namespace)[] assemblies;
public ObjectCreator(Manifest manifest, InstalledMods mods)
{
@@ -59,7 +59,7 @@ namespace OpenRA
}
AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly;
assemblies = assemblyList.SelectMany(asm => asm.GetNamespaces().Select(ns => Pair.New(asm, ns))).ToArray();
assemblies = assemblyList.SelectMany(asm => asm.GetNamespaces().Select(ns => (asm, ns))).ToArray();
}
Assembly ResolveAssembly(object sender, ResolveEventArgs e)
@@ -71,7 +71,7 @@ namespace OpenRA
if (assemblies == null)
return null;
return assemblies.Select(a => a.First).FirstOrDefault(a => a.FullName == e.Name);
return assemblies.Select(a => a.Assembly).FirstOrDefault(a => a.FullName == e.Name);
}
// Only used by the linter to prevent exceptions from being thrown during a lint run
@@ -106,7 +106,7 @@ namespace OpenRA
public Type FindType(string className)
{
return assemblies
.Select(pair => pair.First.GetType(pair.Second + "." + className, false))
.Select(pair => pair.Assembly.GetType(pair.Namespace + "." + className, false))
.FirstOrDefault(t => t != null);
}
@@ -146,7 +146,7 @@ namespace OpenRA
public IEnumerable<Type> GetTypes()
{
return assemblies.Select(ma => ma.First).Distinct()
return assemblies.Select(ma => ma.Assembly).Distinct()
.SelectMany(ma => ma.GetTypes());
}

View File

@@ -5,7 +5,7 @@
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Optimize>true</Optimize>
<UseVSHostingProcess>false</UseVSHostingProcess>
<LangVersion>5</LangVersion>
<LangVersion>7.3</LangVersion>
<DebugSymbols>true</DebugSymbols>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<AutoGenerateBindingRedirects>false</AutoGenerateBindingRedirects>

View File

@@ -32,7 +32,7 @@ namespace OpenRA
SheetBuilder sheetBuilder;
[FieldLoader.Ignore]
Cache<Pair<PlayerBadge, int>, Sprite> iconCache;
Cache<(PlayerBadge, int), Sprite> iconCache;
Sprite LoadSprite(string url, int density)
{
@@ -83,15 +83,15 @@ namespace OpenRA
{
sheetBuilder = new SheetBuilder(SheetType.BGRA, CreateSheet);
iconCache = new Cache<Pair<PlayerBadge, int>, Sprite>(p =>
iconCache = new Cache<(PlayerBadge Badge, int Density), Sprite>(p =>
{
if (p.Second > 2 && !string.IsNullOrEmpty(p.First.Icon3x))
return LoadSprite(p.First.Icon3x, 3);
if (p.Density > 2 && !string.IsNullOrEmpty(p.Badge.Icon3x))
return LoadSprite(p.Badge.Icon3x, 3);
if (p.Second > 1 && !string.IsNullOrEmpty(p.First.Icon2x))
return LoadSprite(p.First.Icon2x, 2);
if (p.Density > 1 && !string.IsNullOrEmpty(p.Badge.Icon2x))
return LoadSprite(p.Badge.Icon2x, 2);
return LoadSprite(p.First.Icon, 1);
return LoadSprite(p.Badge.Icon, 1);
});
}
@@ -113,7 +113,7 @@ namespace OpenRA
{
var ws = Game.Renderer.WindowScale;
var density = ws > 2 ? 3 : ws > 1 ? 2 : 1;
return iconCache[Pair.New(badge, density)];
return iconCache[(badge, density)];
}
}
}

View File

@@ -1,70 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2020 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, either version 3 of
* the License, or (at your option) any later version. For more
* information, see COPYING.
*/
#endregion
using System;
using System.Collections.Generic;
namespace OpenRA.Primitives
{
public struct Pair<T, U> : IEquatable<Pair<T, U>>
{
public T First;
public U Second;
public Pair(T first, U second)
{
First = first;
Second = second;
}
internal static IEqualityComparer<T> Tcomparer = EqualityComparer<T>.Default;
internal static IEqualityComparer<U> Ucomparer = EqualityComparer<U>.Default;
public static bool operator ==(Pair<T, U> a, Pair<T, U> b)
{
return Tcomparer.Equals(a.First, b.First) && Ucomparer.Equals(a.Second, b.Second);
}
public static bool operator !=(Pair<T, U> a, Pair<T, U> b)
{
return !(a == b);
}
public override int GetHashCode() { return First.GetHashCode() ^ Second.GetHashCode(); }
public bool Equals(Pair<T, U> other) { return this == other; }
public override bool Equals(object obj) { return obj is Pair<T, U> && Equals((Pair<T, U>)obj); }
public Pair<T, U> WithFirst(T t) { return new Pair<T, U>(t, Second); }
public Pair<T, U> WithSecond(U u) { return new Pair<T, U>(First, u); }
public static T AsFirst(Pair<T, U> p) { return p.First; }
public static U AsSecond(Pair<T, U> p) { return p.Second; }
public override string ToString()
{
return "({0},{1})".F(First, Second);
}
class PairEqualityComparer : IEqualityComparer<Pair<T, U>>
{
public bool Equals(Pair<T, U> x, Pair<T, U> y) { return x == y; }
public int GetHashCode(Pair<T, U> obj) { return obj.GetHashCode(); }
}
public static IEqualityComparer<Pair<T, U>> EqualityComparer { get { return new PairEqualityComparer(); } }
}
public static class Pair
{
public static Pair<T, U> New<T, U>(T t, U u) { return new Pair<T, U>(t, u); }
}
}

View File

@@ -271,7 +271,7 @@ namespace OpenRA.Traits
public interface IMapPreviewSignatureInfo : ITraitInfoInterface
{
void PopulateMapPreviewSignatureCells(Map map, ActorInfo ai, ActorReference s, List<Pair<MPos, Color>> destinationBuffer);
void PopulateMapPreviewSignatureCells(Map map, ActorInfo ai, ActorReference s, List<(MPos, Color)> destinationBuffer);
}
public interface IOccupySpaceInfo : ITraitInfoInterface
@@ -284,7 +284,7 @@ namespace OpenRA.Traits
{
WPos CenterPosition { get; }
CPos TopLeft { get; }
Pair<CPos, SubCell>[] OccupiedCells();
(CPos Cell, SubCell SubCell)[] OccupiedCells();
}
public enum SubCell : byte { Invalid = byte.MaxValue, Any = byte.MaxValue - 1, FullCell = 0, First = 1 }

View File

@@ -24,7 +24,7 @@ namespace OpenRA.Mods.Cnc.Graphics
static readonly float[] ChannelSelect = { 0.75f, 0.25f, -0.25f, -0.75f };
readonly List<Vertex[]> vertices = new List<Vertex[]>();
readonly Cache<Pair<string, string>, Voxel> voxels;
readonly Cache<(string, string), Voxel> voxels;
readonly IReadOnlyFileSystem fileSystem;
IVertexBuffer<Vertex> vertexBuffer;
int totalVertexCount;
@@ -49,7 +49,7 @@ namespace OpenRA.Mods.Cnc.Graphics
public VoxelLoader(IReadOnlyFileSystem fileSystem)
{
this.fileSystem = fileSystem;
voxels = new Cache<Pair<string, string>, Voxel>(LoadFile);
voxels = new Cache<(string, string), Voxel>(LoadFile);
vertices = new List<Vertex[]>();
totalVertexCount = 0;
cachedVertexCount = 0;
@@ -211,20 +211,20 @@ namespace OpenRA.Mods.Cnc.Graphics
}
}
Voxel LoadFile(Pair<string, string> files)
Voxel LoadFile((string Vxl, string Hva) files)
{
VxlReader vxl;
HvaReader hva;
using (var s = fileSystem.Open(files.First + ".vxl"))
using (var s = fileSystem.Open(files.Vxl + ".vxl"))
vxl = new VxlReader(s);
using (var s = fileSystem.Open(files.Second + ".hva"))
hva = new HvaReader(s, files.Second + ".hva");
using (var s = fileSystem.Open(files.Hva + ".hva"))
hva = new HvaReader(s, files.Hva + ".hva");
return new Voxel(this, vxl, hva);
}
public Voxel Load(string vxl, string hva)
{
return voxels[Pair.New(vxl, hva)];
return voxels[(vxl, hva)];
}
public void Finish()

View File

@@ -3,7 +3,7 @@
<TargetFramework>net472</TargetFramework>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Optimize>true</Optimize>
<LangVersion>5</LangVersion>
<LangVersion>7.3</LangVersion>
<DebugSymbols>true</DebugSymbols>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<OutputPath>../mods/common</OutputPath>

View File

@@ -146,7 +146,7 @@ namespace OpenRA.Mods.Cnc.Traits
get { return OpenRA.Mods.Common.Util.ApplyPercentageModifiers(Info.Speed, speedModifiers); }
}
public Pair<CPos, SubCell>[] OccupiedCells() { return new[] { Pair.New(TopLeft, SubCell.FullCell) }; }
public (CPos, SubCell)[] OccupiedCells() { return new[] { (TopLeft, SubCell.FullCell) }; }
WVec MoveStep(WAngle facing)
{

View File

@@ -17,7 +17,6 @@ using System.Text;
using OpenRA.Mods.Cnc.FileFormats;
using OpenRA.Mods.Common.FileFormats;
using OpenRA.Mods.Common.UtilityCommands;
using OpenRA.Primitives;
namespace OpenRA.Mods.Cnc.UtilityCommands
{
@@ -52,17 +51,17 @@ namespace OpenRA.Mods.Cnc.UtilityCommands
"fpls", "wcrate", "scrate", "barb", "sbag",
};
static Dictionary<string, Pair<byte, byte>> overlayResourceMapping = new Dictionary<string, Pair<byte, byte>>()
static Dictionary<string, (byte Type, byte Index)> overlayResourceMapping = new Dictionary<string, (byte, byte)>()
{
// RA ore & crystals
{ "gold01", new Pair<byte, byte>(1, 0) },
{ "gold02", new Pair<byte, byte>(1, 1) },
{ "gold03", new Pair<byte, byte>(1, 2) },
{ "gold04", new Pair<byte, byte>(1, 3) },
{ "gem01", new Pair<byte, byte>(2, 0) },
{ "gem02", new Pair<byte, byte>(2, 1) },
{ "gem03", new Pair<byte, byte>(2, 2) },
{ "gem04", new Pair<byte, byte>(2, 3) },
{ "gold01", (1, 0) },
{ "gold02", (1, 1) },
{ "gold03", (1, 2) },
{ "gold04", (1, 3) },
{ "gem01", (2, 0) },
{ "gem02", (2, 1) },
{ "gem03", (2, 2) },
{ "gem04", (2, 3) },
};
void UnpackTileData(MemoryStream ms)
@@ -101,13 +100,13 @@ namespace OpenRA.Mods.Cnc.UtilityCommands
for (var i = 0; i < MapSize; i++)
{
var o = ms.ReadUInt8();
var res = Pair.New((byte)0, (byte)0);
var res = (Type: (byte)0, Index: (byte)0);
if (o != 255 && overlayResourceMapping.ContainsKey(redAlertOverlayNames[o]))
res = overlayResourceMapping[redAlertOverlayNames[o]];
var cell = new CPos(i, j);
Map.Resources[cell] = new ResourceTile(res.First, res.Second);
Map.Resources[cell] = new ResourceTile(res.Type, res.Index);
if (o != 255 && overlayActors.Contains(redAlertOverlayNames[o]))
{

View File

@@ -15,7 +15,6 @@ using System.IO;
using System.Linq;
using OpenRA.Mods.Common.FileFormats;
using OpenRA.Mods.Common.UtilityCommands;
using OpenRA.Primitives;
namespace OpenRA.Mods.Cnc.UtilityCommands
{
@@ -40,21 +39,21 @@ namespace OpenRA.Mods.Cnc.UtilityCommands
}
}
static Dictionary<string, Pair<byte, byte>> overlayResourceMapping = new Dictionary<string, Pair<byte, byte>>()
static Dictionary<string, (byte Type, byte Index)> overlayResourceMapping = new Dictionary<string, (byte, byte)>()
{
// Tiberium
{ "ti1", new Pair<byte, byte>(1, 0) },
{ "ti2", new Pair<byte, byte>(1, 1) },
{ "ti3", new Pair<byte, byte>(1, 2) },
{ "ti4", new Pair<byte, byte>(1, 3) },
{ "ti5", new Pair<byte, byte>(1, 4) },
{ "ti6", new Pair<byte, byte>(1, 5) },
{ "ti7", new Pair<byte, byte>(1, 6) },
{ "ti8", new Pair<byte, byte>(1, 7) },
{ "ti9", new Pair<byte, byte>(1, 8) },
{ "ti10", new Pair<byte, byte>(1, 9) },
{ "ti11", new Pair<byte, byte>(1, 10) },
{ "ti12", new Pair<byte, byte>(1, 11) },
{ "ti1", (1, 0) },
{ "ti2", (1, 1) },
{ "ti3", (1, 2) },
{ "ti4", (1, 3) },
{ "ti5", (1, 4) },
{ "ti6", (1, 5) },
{ "ti7", (1, 6) },
{ "ti8", (1, 7) },
{ "ti9", (1, 8) },
{ "ti10", (1, 9) },
{ "ti11", (1, 10) },
{ "ti12", (1, 11) },
};
void UnpackTileData(Stream ms)
@@ -93,12 +92,12 @@ namespace OpenRA.Mods.Cnc.UtilityCommands
var loc = Exts.ParseIntegerInvariant(kv.Key);
var cell = new CPos(loc % MapSize, loc / MapSize);
var res = Pair.New((byte)0, (byte)0);
var res = (Type: (byte)0, Index: (byte)0);
var type = kv.Value.ToLowerInvariant();
if (overlayResourceMapping.ContainsKey(type))
res = overlayResourceMapping[type];
Map.Resources[cell] = new ResourceTile(res.First, res.Second);
Map.Resources[cell] = new ResourceTile(res.Type, res.Index);
if (overlayActors.Contains(type))
{
var ar = new ActorReference(type)

View File

@@ -201,16 +201,16 @@ namespace OpenRA.Mods.Common.Activities
if (nextCell == null)
return false;
var firstFacing = self.World.Map.FacingBetween(mobile.FromCell, nextCell.Value.First, mobile.Facing);
var firstFacing = self.World.Map.FacingBetween(mobile.FromCell, nextCell.Value.Cell, mobile.Facing);
if (firstFacing != mobile.Facing)
{
path.Add(nextCell.Value.First);
path.Add(nextCell.Value.Cell);
QueueChild(new Turn(self, firstFacing));
mobile.TurnToMove = true;
return false;
}
mobile.SetLocation(mobile.FromCell, mobile.FromSubCell, nextCell.Value.First, nextCell.Value.Second);
mobile.SetLocation(mobile.FromCell, mobile.FromSubCell, nextCell.Value.Cell, nextCell.Value.SubCell);
var map = self.World.Map;
var from = (mobile.FromCell.Layer == 0 ? map.CenterOfCell(mobile.FromCell) :
@@ -224,7 +224,7 @@ namespace OpenRA.Mods.Common.Activities
return false;
}
Pair<CPos, SubCell>? PopPath(Actor self)
(CPos Cell, SubCell SubCell)? PopPath(Actor self)
{
if (path.Count == 0)
return null;
@@ -310,7 +310,7 @@ namespace OpenRA.Mods.Common.Activities
var newCell = path[path.Count - 1];
path.RemoveAt(path.Count - 1);
return Pair.New(newCell, mobile.GetAvailableSubCell(nextCell, mobile.FromSubCell, ignoreActor));
return (newCell, mobile.GetAvailableSubCell(nextCell, mobile.FromSubCell, ignoreActor));
}
else if (mobile.IsBlocking)
{
@@ -321,7 +321,7 @@ namespace OpenRA.Mods.Common.Activities
if ((nextCell - newCell).Value.LengthSquared > 2)
path.Add(mobile.ToCell);
return Pair.New(newCell.Value, mobile.GetAvailableSubCell(newCell.Value, mobile.FromSubCell, ignoreActor));
return (newCell.Value, mobile.GetAvailableSubCell(newCell.Value, mobile.FromSubCell, ignoreActor));
}
}
@@ -331,7 +331,7 @@ namespace OpenRA.Mods.Common.Activities
hasWaited = false;
path.RemoveAt(path.Count - 1);
return Pair.New(nextCell, mobile.GetAvailableSubCell(nextCell, mobile.FromSubCell, ignoreActor));
return (nextCell, mobile.GetAvailableSubCell(nextCell, mobile.FromSubCell, ignoreActor));
}
protected override void OnLastRun(Actor self)
@@ -518,23 +518,23 @@ namespace OpenRA.Mods.Common.Activities
var nextCell = parent.PopPath(self);
if (nextCell != null)
{
if (!mobile.IsTraitPaused && !mobile.IsTraitDisabled && IsTurn(mobile, nextCell.Value.First, map))
if (!mobile.IsTraitPaused && !mobile.IsTraitDisabled && IsTurn(mobile, nextCell.Value.Cell, map))
{
var nextSubcellOffset = map.Grid.OffsetOfSubCell(nextCell.Value.Second);
var nextSubcellOffset = map.Grid.OffsetOfSubCell(nextCell.Value.SubCell);
var ret = new MoveFirstHalf(
Move,
Util.BetweenCells(self.World, mobile.FromCell, mobile.ToCell) + (fromSubcellOffset + toSubcellOffset) / 2,
Util.BetweenCells(self.World, mobile.ToCell, nextCell.Value.First) + (toSubcellOffset + nextSubcellOffset) / 2,
Util.BetweenCells(self.World, mobile.ToCell, nextCell.Value.Cell) + (toSubcellOffset + nextSubcellOffset) / 2,
mobile.Facing,
map.FacingBetween(mobile.ToCell, nextCell.Value.First, mobile.Facing),
map.FacingBetween(mobile.ToCell, nextCell.Value.Cell, mobile.Facing),
moveFraction - MoveFractionTotal);
mobile.FinishedMoving(self);
mobile.SetLocation(mobile.ToCell, mobile.ToSubCell, nextCell.Value.First, nextCell.Value.Second);
mobile.SetLocation(mobile.ToCell, mobile.ToSubCell, nextCell.Value.Cell, nextCell.Value.SubCell);
return ret;
}
parent.path.Add(nextCell.Value.First);
parent.path.Add(nextCell.Value.Cell);
}
var toPos = mobile.ToCell.Layer == 0 ? map.CenterOfCell(mobile.ToCell) :

View File

@@ -50,15 +50,15 @@ namespace OpenRA.Mods.Common.Activities
this.unloadRange = unloadRange;
}
public Pair<CPos, SubCell>? ChooseExitSubCell(Actor passenger)
public (CPos Cell, SubCell SubCell)? ChooseExitSubCell(Actor passenger)
{
var pos = passenger.Trait<IPositionable>();
return cargo.CurrentAdjacentCells
.Shuffle(self.World.SharedRandom)
.Select(c => Pair.New(c, pos.GetAvailableSubCell(c)))
.Cast<Pair<CPos, SubCell>?>()
.FirstOrDefault(s => s.Value.Second != SubCell.Invalid);
.Select(c => (c, pos.GetAvailableSubCell(c)))
.Cast<(CPos, SubCell SubCell)?>()
.FirstOrDefault(s => s.Value.SubCell != SubCell.Invalid);
}
IEnumerable<CPos> BlockedExitCells(Actor passenger)
@@ -121,7 +121,7 @@ namespace OpenRA.Mods.Common.Activities
var move = actor.Trait<IMove>();
var pos = actor.Trait<IPositionable>();
pos.SetPosition(actor, exitSubCell.Value.First, exitSubCell.Value.Second);
pos.SetPosition(actor, exitSubCell.Value.Cell, exitSubCell.Value.SubCell);
pos.SetVisualPosition(actor, spawn);
actor.CancelActivity();

View File

@@ -116,7 +116,7 @@ namespace OpenRA.Mods.Common.Widgets
var dest = new CellRegion(gridType, source.TopLeft + offset, source.BottomRight + offset);
var previews = new Dictionary<string, ActorReference>();
var tiles = new Dictionary<CPos, Tuple<TerrainTile, ResourceTile, byte>>();
var tiles = new Dictionary<CPos, (TerrainTile, ResourceTile, byte)>();
var copyFilters = getCopyFilters();
foreach (var cell in source)
@@ -124,7 +124,7 @@ namespace OpenRA.Mods.Common.Widgets
if (!mapTiles.Contains(cell) || !mapTiles.Contains(cell + offset))
continue;
tiles.Add(cell + offset, Tuple.Create(mapTiles[cell], mapResources[cell], mapHeight[cell]));
tiles.Add(cell + offset, (mapTiles[cell], mapResources[cell], mapHeight[cell]));
if (copyFilters.HasFlag(MapCopyFilters.Actors))
{
@@ -178,7 +178,7 @@ namespace OpenRA.Mods.Common.Widgets
public string Text { get; private set; }
readonly MapCopyFilters copyFilters;
readonly Dictionary<CPos, Tuple<TerrainTile, ResourceTile, byte>> tiles;
readonly Dictionary<CPos, (TerrainTile Tile, ResourceTile Resource, byte Height)> tiles;
readonly Dictionary<string, ActorReference> previews;
readonly EditorActorLayer editorLayer;
readonly CellRegion dest;
@@ -191,7 +191,7 @@ namespace OpenRA.Mods.Common.Widgets
readonly Queue<EditorActorPreview> addedActorPreviews = new Queue<EditorActorPreview>();
public CopyPasteEditorAction(MapCopyFilters copyFilters, Map map,
Dictionary<CPos, Tuple<TerrainTile, ResourceTile, byte>> tiles, Dictionary<string, ActorReference> previews,
Dictionary<CPos, (TerrainTile, ResourceTile, byte)> tiles, Dictionary<string, ActorReference> previews,
EditorActorLayer editorLayer, CellRegion dest)
{
this.copyFilters = copyFilters;
@@ -219,12 +219,12 @@ namespace OpenRA.Mods.Common.Widgets
undoCopyPastes.Enqueue(new UndoCopyPaste(kv.Key, mapTiles[kv.Key], mapResources[kv.Key], mapHeight[kv.Key]));
if (copyFilters.HasFlag(MapCopyFilters.Terrain))
mapTiles[kv.Key] = kv.Value.Item1;
mapTiles[kv.Key] = kv.Value.Tile;
if (copyFilters.HasFlag(MapCopyFilters.Resources))
mapResources[kv.Key] = kv.Value.Item2;
mapResources[kv.Key] = kv.Value.Resource;
mapHeight[kv.Key] = kv.Value.Item3;
mapHeight[kv.Key] = kv.Value.Height;
}
if (copyFilters.HasFlag(MapCopyFilters.Actors))

View File

@@ -133,7 +133,7 @@ namespace OpenRA.Mods.Common.Graphics
// HACK: We don't have enough texture channels to pass the depth data to the shader
// so for now just offset everything forward so that the back corner is rendered at pos.
pxOrigin -= new float3(0, 0, Screen3DBounds(wr).Second.X);
pxOrigin -= new float3(0, 0, Screen3DBounds(wr).Z.X);
var shadowOrigin = pxOrigin - groundZ * (new float2(renderProxy.ShadowDirection, 1));
@@ -221,10 +221,10 @@ namespace OpenRA.Mods.Common.Graphics
public Rectangle ScreenBounds(WorldRenderer wr)
{
return Screen3DBounds(wr).First;
return Screen3DBounds(wr).Bounds;
}
Pair<Rectangle, float2> Screen3DBounds(WorldRenderer wr)
(Rectangle Bounds, float2 Z) Screen3DBounds(WorldRenderer wr)
{
var pxOrigin = wr.ScreenPosition(model.pos);
var draw = model.models.Where(v => v.IsVisible);
@@ -260,7 +260,7 @@ namespace OpenRA.Mods.Common.Graphics
}
}
return Pair.New(Rectangle.FromLTRB((int)minX, (int)minY, (int)maxX, (int)maxY), new float2(minZ, maxZ));
return (Rectangle.FromLTRB((int)minX, (int)minY, (int)maxX, (int)maxY), new float2(minZ, maxZ));
}
}
}

View File

@@ -106,13 +106,13 @@ namespace OpenRA.Mods.Common.Graphics
public Rectangle ScreenBounds(WorldRenderer wr)
{
return Screen3DBounds(wr).First;
return Screen3DBounds(wr).Bounds;
}
static readonly uint[] CornerXIndex = { 0, 0, 0, 0, 3, 3, 3, 3 };
static readonly uint[] CornerYIndex = { 1, 1, 4, 4, 1, 1, 4, 4 };
static readonly uint[] CornerZIndex = { 2, 5, 2, 5, 2, 5, 2, 5 };
Pair<Rectangle, float2> Screen3DBounds(WorldRenderer wr)
(Rectangle Bounds, float2 Z) Screen3DBounds(WorldRenderer wr)
{
var pxOrigin = model.screenPos;
var draw = model.models.Where(v => v.IsVisible);
@@ -148,7 +148,7 @@ namespace OpenRA.Mods.Common.Graphics
}
}
return Pair.New(Rectangle.FromLTRB((int)minX, (int)minY, (int)maxX, (int)maxY), new float2(minZ, maxZ));
return (Rectangle.FromLTRB((int)minX, (int)minY, (int)maxX, (int)maxY), new float2(minZ, maxZ));
}
}
}

View File

@@ -41,7 +41,7 @@ namespace OpenRA.Mods.Common.Lint
var checkWidgetFields = modData.ObjectCreator.GetTypesImplementing<Widget>()
.SelectMany(w => w.GetFields()
.Where(f => f.FieldType == typeof(HotkeyReference))
.Select(f => Pair.New(w.Name.Substring(0, w.Name.Length - 6), f.Name)))
.Select(f => (w.Name.Substring(0, w.Name.Length - 6), f.Name)))
.ToArray();
var customLintMethods = new Dictionary<string, List<string>>();
@@ -64,7 +64,7 @@ namespace OpenRA.Mods.Common.Lint
}
}
void CheckInner(ModData modData, string[] namedKeys, Pair<string, string>[] checkWidgetFields, Dictionary<string, List<string>> customLintMethods,
void CheckInner(ModData modData, string[] namedKeys, (string Widget, string Field)[] checkWidgetFields, Dictionary<string, List<string>> customLintMethods,
List<MiniYamlNode> nodes, string filename, MiniYamlNode parent, Action<string> emitError, Action<string> emitWarning)
{
foreach (var node in nodes)
@@ -74,19 +74,17 @@ namespace OpenRA.Mods.Common.Lint
foreach (var x in checkWidgetFields)
{
if (node.Key == x.Second && parent != null && parent.Key.StartsWith(x.First, StringComparison.Ordinal))
if (node.Key == x.Field && parent != null && parent.Key.StartsWith(x.Widget, StringComparison.Ordinal))
{
// Keys are valid if they refer to a named key or can be parsed as a regular Hotkey.
Hotkey unused;
if (!namedKeys.Contains(node.Value.Value) && !Hotkey.TryParse(node.Value.Value, out unused))
if (!namedKeys.Contains(node.Value.Value) && !Hotkey.TryParse(node.Value.Value, out var unused))
emitError("{0} refers to a Key named `{1}` that does not exist".F(node.Location, node.Value.Value));
}
}
// Check runtime-defined hotkey names
List<string> checkMethods;
var widgetType = node.Key.Split('@')[0];
if (customLintMethods.TryGetValue(widgetType, out checkMethods))
if (customLintMethods.TryGetValue(widgetType, out var checkMethods))
{
var type = modData.ObjectCreator.FindType(widgetType + "Widget");
var keyNames = checkMethods.SelectMany(m => (IEnumerable<string>)type.GetMethod(m).Invoke(null, new object[] { node, emitError, emitWarning }));
@@ -111,10 +109,9 @@ namespace OpenRA.Mods.Common.Lint
checkArgKeys.AddRange(type.GetCustomAttributes<ChromeLogicArgsHotkeys>(true).SelectMany(x => x.LogicArgKeys));
}
Hotkey unused;
foreach (var n in node.Value.Nodes)
if (checkArgKeys.Contains(n.Key))
if (!namedKeys.Contains(n.Value.Value) && !Hotkey.TryParse(n.Value.Value, out unused))
if (!namedKeys.Contains(n.Value.Value) && !Hotkey.TryParse(n.Value.Value, out var unused))
emitError("{0} {1}:{2} refers to a Key named `{3}` that does not exist".F(filename, node.Value.Value, n.Key, n.Value.Value));
}

View File

@@ -3,7 +3,7 @@
<TargetFramework>net472</TargetFramework>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Optimize>true</Optimize>
<LangVersion>5</LangVersion>
<LangVersion>7.3</LangVersion>
<DebugSymbols>true</DebugSymbols>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<OutputPath>../mods/common</OutputPath>

View File

@@ -262,9 +262,9 @@ namespace OpenRA.Mods.Common.Orders
{
foreach (var t in BuildingUtils.GetLineBuildCells(world, topLeft, actorInfo, buildingInfo, owner))
{
var lineBuildable = world.IsCellBuildable(t.First, actorInfo, buildingInfo);
var lineCloseEnough = buildingInfo.IsCloseEnoughToBase(world, world.LocalPlayer, actorInfo, t.First);
footprint.Add(t.First, MakeCellType(lineBuildable && lineCloseEnough, true));
var lineBuildable = world.IsCellBuildable(t.Cell, actorInfo, buildingInfo);
var lineCloseEnough = buildingInfo.IsCloseEnoughToBase(world, world.LocalPlayer, actorInfo, t.Cell);
footprint.Add(t.Cell, MakeCellType(lineBuildable && lineCloseEnough, true));
}
}

View File

@@ -27,7 +27,7 @@ namespace OpenRA.Mods.Common.Pathfinder
/// <summary>
/// Stores the analyzed nodes by the expand function
/// </summary>
IEnumerable<Pair<CPos, int>> Considered { get; }
IEnumerable<(CPos Cell, int Cost)> Considered { get; }
Player Owner { get; }
@@ -68,7 +68,7 @@ namespace OpenRA.Mods.Common.Pathfinder
protected IPriorityQueue<GraphConnection> OpenQueue { get; private set; }
public abstract IEnumerable<Pair<CPos, int>> Considered { get; }
public abstract IEnumerable<(CPos Cell, int Cost)> Considered { get; }
public Player Owner { get { return Graph.Actor.Owner; } }
public int MaxCost { get; protected set; }

View File

@@ -92,8 +92,8 @@ namespace OpenRA.Mods.Common.Pathfinder
readonly bool checkTerrainHeight;
CellLayer<CellInfo> groundInfo;
readonly Dictionary<byte, Pair<ICustomMovementLayer, CellLayer<CellInfo>>> customLayerInfo =
new Dictionary<byte, Pair<ICustomMovementLayer, CellLayer<CellInfo>>>();
readonly Dictionary<byte, (ICustomMovementLayer Layer, CellLayer<CellInfo> Info)> customLayerInfo =
new Dictionary<byte, (ICustomMovementLayer, CellLayer<CellInfo>)>();
public PathGraph(CellInfoLayerPool layerPool, Locomotor locomotor, Actor actor, World world, BlockedByActor check)
{
@@ -105,7 +105,7 @@ namespace OpenRA.Mods.Common.Pathfinder
.Where(cml => cml.EnabledForActor(actor.Info, locomotorInfo));
foreach (var cml in layers)
customLayerInfo[cml.Index] = Pair.New(cml, pooledLayer.GetLayer());
customLayerInfo[cml.Index] = (cml, pooledLayer.GetLayer());
World = world;
worldMovementInfo = locomotorInfo.GetWorldMovementInfo(world);
@@ -135,7 +135,7 @@ namespace OpenRA.Mods.Common.Pathfinder
public List<GraphConnection> GetConnections(CPos position)
{
var info = position.Layer == 0 ? groundInfo : customLayerInfo[position.Layer].Second;
var info = position.Layer == 0 ? groundInfo : customLayerInfo[position.Layer].Info;
var previousPos = info[position].PreviousPos;
var dx = position.X - previousPos.X;
@@ -156,8 +156,8 @@ namespace OpenRA.Mods.Common.Pathfinder
{
foreach (var cli in customLayerInfo.Values)
{
var layerPosition = new CPos(position.X, position.Y, cli.First.Index);
var entryCost = cli.First.EntryMovementCost(Actor.Info, locomotor.Info, layerPosition);
var layerPosition = new CPos(position.X, position.Y, cli.Layer.Index);
var entryCost = cli.Layer.EntryMovementCost(Actor.Info, locomotor.Info, layerPosition);
if (entryCost != CostForInvalidCell)
validNeighbors.Add(new GraphConnection(layerPosition, entryCost));
}
@@ -165,7 +165,7 @@ namespace OpenRA.Mods.Common.Pathfinder
else
{
var layerPosition = new CPos(position.X, position.Y, 0);
var exitCost = customLayerInfo[position.Layer].First.ExitMovementCost(Actor.Info, locomotor.Info, layerPosition);
var exitCost = customLayerInfo[position.Layer].Layer.ExitMovementCost(Actor.Info, locomotor.Info, layerPosition);
if (exitCost != CostForInvalidCell)
validNeighbors.Add(new GraphConnection(layerPosition, exitCost));
}
@@ -224,8 +224,8 @@ namespace OpenRA.Mods.Common.Pathfinder
public CellInfo this[CPos pos]
{
get { return (pos.Layer == 0 ? groundInfo : customLayerInfo[pos.Layer].Second)[pos]; }
set { (pos.Layer == 0 ? groundInfo : customLayerInfo[pos.Layer].Second)[pos] = value; }
get { return (pos.Layer == 0 ? groundInfo : customLayerInfo[pos.Layer].Info)[pos]; }
set { (pos.Layer == 0 ? groundInfo : customLayerInfo[pos.Layer].Info)[pos] = value; }
}
public void Dispose()

View File

@@ -30,19 +30,19 @@ namespace OpenRA.Mods.Common.Pathfinder
return LayerPoolTable.GetValue(world, CreateLayerPool);
}
public override IEnumerable<Pair<CPos, int>> Considered
public override IEnumerable<(CPos, int)> Considered
{
get { return considered; }
}
LinkedList<Pair<CPos, int>> considered;
LinkedList<(CPos, int)> considered;
#region Constructors
private PathSearch(IGraph<CellInfo> graph)
: base(graph)
{
considered = new LinkedList<Pair<CPos, int>>();
considered = new LinkedList<(CPos, int)>();
}
public static IPathSearch Search(World world, Locomotor locomotor, Actor self, BlockedByActor check, Func<CPos, bool> goalCondition)
@@ -94,7 +94,7 @@ namespace OpenRA.Mods.Common.Pathfinder
var connection = new GraphConnection(location, cost);
OpenQueue.Add(connection);
StartPoints.Add(connection);
considered.AddLast(new Pair<CPos, int>(location, 0));
considered.AddLast((location, 0));
}
#endregion
@@ -146,7 +146,7 @@ namespace OpenRA.Mods.Common.Pathfinder
if (gCost > MaxCost)
MaxCost = gCost;
considered.AddLast(new Pair<CPos, int>(neighborCPos, gCost));
considered.AddLast((neighborCPos, gCost));
}
}

View File

@@ -31,7 +31,7 @@ namespace OpenRA.Mods.Common.Scripting
public Actor[] TargetParatroopers(WPos target, WAngle? facing = null)
{
var actors = pp.SendParatroopers(Self, target, facing);
return actors.First;
return actors.Aircraft;
}
[Desc("Activate the actor's Paratroopers Power. Returns the aircraft that will drop the reinforcements. DEPRECATED! Will be removed.")]
@@ -39,7 +39,7 @@ namespace OpenRA.Mods.Common.Scripting
{
Game.Debug("SendParatroopersFrom is deprecated. Use TargetParatroopers instead.");
var actors = pp.SendParatroopers(Self, target, facing == -1 ? (WAngle?)null : WAngle.FromFacing(facing));
return actors.First;
return actors.Aircraft;
}
}
}

View File

@@ -9,18 +9,17 @@
*/
#endregion
using OpenRA.Primitives;
using OpenRA.Traits;
namespace OpenRA.Mods.Common
{
public static class ShroudExts
{
public static bool AnyExplored(this Shroud shroud, Pair<CPos, SubCell>[] cells)
public static bool AnyExplored(this Shroud shroud, (CPos Cell, SubCell SubCell)[] cells)
{
// PERF: Avoid LINQ.
foreach (var cell in cells)
if (shroud.IsExplored(cell.First))
if (shroud.IsExplored(cell.Cell))
return true;
return false;
@@ -36,11 +35,11 @@ namespace OpenRA.Mods.Common
return false;
}
public static bool AnyVisible(this Shroud shroud, Pair<CPos, SubCell>[] cells)
public static bool AnyVisible(this Shroud shroud, (CPos Cell, SubCell SubCell)[] cells)
{
// PERF: Avoid LINQ.
foreach (var cell in cells)
if (shroud.IsVisible(cell.First))
if (shroud.IsVisible(cell.Cell))
return true;
return false;

View File

@@ -72,7 +72,7 @@ namespace OpenRA.Mods.Common.Traits
{
// PERF: Reuse collection to avoid allocations.
footprint.UnionWith(self.OccupiesSpace.OccupiedCells()
.SelectMany(kv => Shroud.ProjectedCellsInRange(map, map.CenterOfCell(kv.First), minRange, maxRange, Info.MaxHeightDelta)));
.SelectMany(kv => Shroud.ProjectedCellsInRange(map, map.CenterOfCell(kv.Cell), minRange, maxRange, Info.MaxHeightDelta)));
var cells = footprint.ToArray();
footprint.Clear();
return cells;

View File

@@ -211,7 +211,7 @@ namespace OpenRA.Mods.Common.Traits
INotifyAddedToWorld, INotifyRemovedFromWorld, INotifyActorDisposing, INotifyBecomingIdle, ICreationActivity,
IActorPreviewInitModifier, IDeathActorInitModifier, IIssueDeployOrder, IIssueOrder, IResolveOrder, IOrderVoice
{
static readonly Pair<CPos, SubCell>[] NoCells = { };
static readonly (CPos, SubCell)[] NoCells = { };
readonly Actor self;
@@ -597,12 +597,12 @@ namespace OpenRA.Mods.Common.Traits
get { return !IsTraitDisabled && !IsTraitPaused ? Util.ApplyPercentageModifiers(Info.Speed, speedModifiers) : 0; }
}
public Pair<CPos, SubCell>[] OccupiedCells()
public (CPos Cell, SubCell SubCell)[] OccupiedCells()
{
if (!self.IsAtGroundLevel())
return landingCells.Select(c => Pair.New(c, SubCell.FullCell)).ToArray();
return landingCells.Select(c => (c, SubCell.FullCell)).ToArray();
return new[] { Pair.New(TopLeft, SubCell.FullCell) };
return new[] { (TopLeft, SubCell.FullCell) };
}
public WVec FlyStep(WAngle facing)

View File

@@ -26,7 +26,7 @@ namespace OpenRA.Mods.Common.Traits
"Overrides `Color` if both set.")]
public readonly string Terrain = null;
void IMapPreviewSignatureInfo.PopulateMapPreviewSignatureCells(Map map, ActorInfo ai, ActorReference s, List<Pair<MPos, Color>> destinationBuffer)
void IMapPreviewSignatureInfo.PopulateMapPreviewSignatureCells(Map map, ActorInfo ai, ActorReference s, List<(MPos, Color)> destinationBuffer)
{
var tileSet = map.Rules.TileSet;
@@ -50,7 +50,7 @@ namespace OpenRA.Mods.Common.Traits
var ios = ai.TraitInfo<IOccupySpaceInfo>();
var cells = ios.OccupiedCells(ai, s.Get<LocationInit>().Value);
foreach (var cell in cells)
destinationBuffer.Add(new Pair<MPos, Color>(cell.Key.ToMPos(map), color));
destinationBuffer.Add((cell.Key.ToMPos(map), color));
}
}

View File

@@ -127,7 +127,7 @@ namespace OpenRA.Mods.Common.Traits
int currentBarrel;
int barrelCount;
List<Pair<int, Action>> delayedActions = new List<Pair<int, Action>>();
List<(int Ticks, Action Func)> delayedActions = new List<(int, Action)>();
public WDist Recoil;
public int FireDelay { get; protected set; }
@@ -211,12 +211,12 @@ namespace OpenRA.Mods.Common.Traits
for (var i = 0; i < delayedActions.Count; i++)
{
var x = delayedActions[i];
if (--x.First <= 0)
x.Second();
if (--x.Ticks <= 0)
x.Func();
delayedActions[i] = x;
}
delayedActions.RemoveAll(a => a.First <= 0);
delayedActions.RemoveAll(a => a.Ticks <= 0);
}
void ITick.Tick(Actor self)
@@ -228,7 +228,7 @@ namespace OpenRA.Mods.Common.Traits
protected void ScheduleDelayedAction(int t, Action a)
{
if (t > 0)
delayedActions.Add(Pair.New(t, a));
delayedActions.Add((t, a));
else
a();
}

View File

@@ -64,27 +64,27 @@ namespace OpenRA.Mods.Common.Traits
DemolishWeaponInfo = weapon;
}
public IEnumerable<Pair<ushort, int>> Templates
public IEnumerable<(ushort Template, int Health)> Templates
{
get
{
if (Template != 0)
yield return Pair.New(Template, 100);
yield return (Template, 100);
if (DamagedTemplate != 0)
yield return Pair.New(DamagedTemplate, 49);
yield return (DamagedTemplate, 49);
if (DestroyedTemplate != 0)
yield return Pair.New(DestroyedTemplate, 0);
yield return (DestroyedTemplate, 0);
if (DestroyedPlusNorthTemplate != 0)
yield return Pair.New(DestroyedPlusNorthTemplate, 0);
yield return (DestroyedPlusNorthTemplate, 0);
if (DestroyedPlusSouthTemplate != 0)
yield return Pair.New(DestroyedPlusSouthTemplate, 0);
yield return (DestroyedPlusSouthTemplate, 0);
if (DestroyedPlusBothTemplate != 0)
yield return Pair.New(DestroyedPlusBothTemplate, 0);
yield return (DestroyedPlusBothTemplate, 0);
}
}
}
@@ -212,7 +212,7 @@ namespace OpenRA.Mods.Common.Traits
var palette = wr.Palette(TileSet.TerrainPaletteInternalName);
renderables = new Dictionary<ushort, IRenderable[]>();
foreach (var t in info.Templates)
renderables.Add(t.First, TemplateRenderables(wr, palette, t.First));
renderables.Add(t.Template, TemplateRenderables(wr, palette, t.Template));
initialized = true;
}

View File

@@ -13,7 +13,6 @@ using System;
using System.Collections.Generic;
using System.Linq;
using OpenRA.Graphics;
using OpenRA.Primitives;
using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
@@ -268,8 +267,8 @@ namespace OpenRA.Mods.Common.Traits
readonly Actor self;
readonly BuildingInfluence influence;
Pair<CPos, SubCell>[] occupiedCells;
Pair<CPos, SubCell>[] targetableCells;
(CPos, SubCell)[] occupiedCells;
(CPos, SubCell)[] targetableCells;
CPos[] transitOnlyCells;
public CPos TopLeft { get { return topLeft; } }
@@ -283,21 +282,21 @@ namespace OpenRA.Mods.Common.Traits
influence = self.World.WorldActor.Trait<BuildingInfluence>();
occupiedCells = Info.OccupiedTiles(TopLeft)
.Select(c => Pair.New(c, SubCell.FullCell)).ToArray();
.Select(c => (c, SubCell.FullCell)).ToArray();
targetableCells = Info.FootprintTiles(TopLeft, FootprintCellType.Occupied)
.Select(c => Pair.New(c, SubCell.FullCell)).ToArray();
.Select(c => (c, SubCell.FullCell)).ToArray();
transitOnlyCells = Info.TransitOnlyTiles(TopLeft).ToArray();
CenterPosition = init.World.Map.CenterOfCell(topLeft) + Info.CenterOffset(init.World);
}
public Pair<CPos, SubCell>[] OccupiedCells() { return occupiedCells; }
public (CPos, SubCell)[] OccupiedCells() { return occupiedCells; }
public CPos[] TransitOnlyCells() { return transitOnlyCells; }
Pair<CPos, SubCell>[] ITargetableCells.TargetableCells() { return targetableCells; }
(CPos, SubCell)[] ITargetableCells.TargetableCells() { return targetableCells; }
void INotifyAddedToWorld.AddedToWorld(Actor self)
{

View File

@@ -54,13 +54,13 @@ namespace OpenRA.Mods.Common.Traits
world.IsCellBuildable(t, ai, bi, toIgnore));
}
public static IEnumerable<Pair<CPos, Actor>> GetLineBuildCells(World world, CPos cell, ActorInfo ai, BuildingInfo bi, Player owner)
public static IEnumerable<(CPos Cell, Actor Actor)> GetLineBuildCells(World world, CPos cell, ActorInfo ai, BuildingInfo bi, Player owner)
{
var lbi = ai.TraitInfo<LineBuildInfo>();
var topLeft = cell; // 1x1 assumption!
if (world.IsCellBuildable(topLeft, ai, bi))
yield return Pair.New<CPos, Actor>(topLeft, null);
yield return (topLeft, null);
// Start at place location, search outwards
// TODO: First make it work, then make it nice
@@ -91,7 +91,7 @@ namespace OpenRA.Mods.Common.Traits
// Place intermediate-line sections
if (dirs[d] > 0)
for (var i = 1; i < dirs[d]; i++)
yield return Pair.New(topLeft + i * vecs[d], connectors[d]);
yield return (topLeft + i * vecs[d], connectors[d]);
}
}
}

View File

@@ -26,7 +26,7 @@ namespace OpenRA.Mods.Common.Traits
class CapturableProgressBar : ConditionalTrait<CapturableProgressBarInfo>, ISelectionBar, ICaptureProgressWatcher
{
Dictionary<Actor, Pair<int, int>> progress = new Dictionary<Actor, Pair<int, int>>();
Dictionary<Actor, (int Current, int Total)> progress = new Dictionary<Actor, (int, int)>();
public CapturableProgressBar(Actor self, CapturableProgressBarInfo info)
: base(info) { }
@@ -39,7 +39,7 @@ namespace OpenRA.Mods.Common.Traits
if (total == 0)
progress.Remove(captor);
else
progress[captor] = Pair.New(current, total);
progress[captor] = (current, total);
}
float ISelectionBar.GetValue()
@@ -47,7 +47,7 @@ namespace OpenRA.Mods.Common.Traits
if (IsTraitDisabled || !progress.Any())
return 0f;
return progress.Values.Max(p => (float)p.First / p.Second);
return progress.Values.Max(p => (float)p.Current / p.Total);
}
Color ISelectionBar.GetColor() { return Info.Color; }

View File

@@ -155,20 +155,20 @@ namespace OpenRA.Mods.Common.Traits
if (crateActions.Any())
{
var shares = crateActions.Select(a => Pair.New(a, a.GetSelectionSharesOuter(crusher)));
var shares = crateActions.Select(a => (Action: a, Shares: a.GetSelectionSharesOuter(crusher)));
var totalShares = shares.Sum(a => a.Second);
var totalShares = shares.Sum(a => a.Shares);
var n = self.World.SharedRandom.Next(totalShares);
foreach (var s in shares)
{
if (n < s.Second)
if (n < s.Shares)
{
s.First.Activate(crusher);
s.Action.Activate(crusher);
return;
}
n -= s.Second;
n -= s.Shares;
}
}
}
@@ -180,7 +180,7 @@ namespace OpenRA.Mods.Common.Traits
}
public CPos TopLeft { get { return Location; } }
public Pair<CPos, SubCell>[] OccupiedCells() { return new[] { Pair.New(Location, SubCell.FullCell) }; }
public (CPos, SubCell)[] OccupiedCells() { return new[] { (Location, SubCell.FullCell) }; }
public WPos CenterPosition { get; private set; }

View File

@@ -67,7 +67,7 @@ namespace OpenRA.Mods.Common.Traits
foreach (var kv in self.OccupiesSpace.OccupiedCells())
{
totalTiles++;
if (!Info.Terrain.Contains(self.World.Map.GetTerrainInfo(kv.First).Type))
if (!Info.Terrain.Contains(self.World.Map.GetTerrainInfo(kv.Cell).Type))
safeTiles++;
}

View File

@@ -70,7 +70,7 @@ namespace OpenRA.Mods.Common.Traits
if (info.DrawPerimiterCellVectors)
{
var occupiedCells = self.OccupiesSpace.OccupiedCells().Select(p => p.First).ToArray();
var occupiedCells = self.OccupiesSpace.OccupiedCells().Select(p => p.Cell).ToArray();
perimeterCells = Util.ExpandFootprint(occupiedCells, true).Except(occupiedCells).ToArray();
foreach (var perimCell in perimeterCells)

View File

@@ -58,7 +58,7 @@ namespace OpenRA.Mods.Common.Traits
readonly GainsExperienceInfo info;
readonly int initialExperience;
readonly List<Pair<int, string>> nextLevel = new List<Pair<int, string>>();
readonly List<(int RequiredExperience, string Condition)> nextLevel = new List<(int, string)>();
// Stored as a percentage of our value
[Sync]
@@ -83,7 +83,7 @@ namespace OpenRA.Mods.Common.Traits
var valued = self.Info.TraitInfoOrDefault<ValuedInfo>();
var requiredExperience = info.ExperienceModifier < 0 ? (valued != null ? valued.Cost : 1) : info.ExperienceModifier;
foreach (var kv in info.Conditions)
nextLevel.Add(Pair.New(kv.Key * requiredExperience, kv.Value));
nextLevel.Add((kv.Key * requiredExperience, kv.Value));
if (initialExperience > 0)
GiveExperience(initialExperience, info.SuppressLevelupAnimation);
@@ -97,7 +97,7 @@ namespace OpenRA.Mods.Common.Traits
return;
var newLevel = Math.Min(Level + numLevels, MaxLevel);
GiveExperience(nextLevel[newLevel - 1].First - Experience, silent);
GiveExperience(nextLevel[newLevel - 1].RequiredExperience - Experience, silent);
}
public void GiveExperience(int amount, bool silent = false)
@@ -108,11 +108,11 @@ namespace OpenRA.Mods.Common.Traits
if (MaxLevel == 0)
return;
Experience = (Experience + amount).Clamp(0, nextLevel[MaxLevel - 1].First);
Experience = (Experience + amount).Clamp(0, nextLevel[MaxLevel - 1].RequiredExperience);
while (Level < MaxLevel && Experience >= nextLevel[Level].First)
while (Level < MaxLevel && Experience >= nextLevel[Level].RequiredExperience)
{
self.GrantCondition(nextLevel[Level].Second);
self.GrantCondition(nextLevel[Level].Condition);
Level++;

View File

@@ -94,7 +94,7 @@ namespace OpenRA.Mods.Common.Traits
if (Info.UseTargetableCellsOffsets && targetableCells != null)
foreach (var c in targetableCells.TargetableCells())
yield return self.World.Map.CenterOfCell(c.First);
yield return self.World.Map.CenterOfCell(c.Cell);
foreach (var o in Info.TargetableOffsets)
{

View File

@@ -116,7 +116,7 @@ namespace OpenRA.Mods.Common.Traits
return true;
}
public Pair<CPos, SubCell>[] OccupiedCells() { return new[] { Pair.New(TopLeft, SubCell.FullCell) }; }
public (CPos, SubCell)[] OccupiedCells() { return new[] { (TopLeft, SubCell.FullCell) }; }
public bool IsLeavingCell(CPos location, SubCell subCell = SubCell.Any) { return false; }
public SubCell GetValidSubCell(SubCell preferred = SubCell.Any) { return SubCell.FullCell; }
public SubCell GetAvailableSubCell(CPos cell, SubCell preferredSubCell = SubCell.Any, Actor ignoreActor = null, BlockedByActor check = BlockedByActor.All)

View File

@@ -39,7 +39,7 @@ namespace OpenRA.Mods.Common.Traits
[Sync]
readonly WPos position;
readonly Pair<CPos, SubCell>[] occupied;
readonly (CPos, SubCell)[] occupied;
public Immobile(ActorInitializer init, ImmobileInfo info)
{
@@ -47,14 +47,14 @@ namespace OpenRA.Mods.Common.Traits
position = init.World.Map.CenterOfCell(location);
if (info.OccupiesSpace)
occupied = new[] { Pair.New(TopLeft, SubCell.FullCell) };
occupied = new[] { (TopLeft, SubCell.FullCell) };
else
occupied = new Pair<CPos, SubCell>[0];
occupied = new (CPos, SubCell)[0];
}
public CPos TopLeft { get { return location; } }
public WPos CenterPosition { get { return position; } }
public Pair<CPos, SubCell>[] OccupiedCells() { return occupied; }
public (CPos, SubCell)[] OccupiedCells() { return occupied; }
void INotifyAddedToWorld.AddedToWorld(Actor self)
{

View File

@@ -229,16 +229,16 @@ namespace OpenRA.Mods.Common.Traits
public CPos TopLeft { get { return ToCell; } }
public Pair<CPos, SubCell>[] OccupiedCells()
public (CPos, SubCell)[] OccupiedCells()
{
if (FromCell == ToCell)
return new[] { Pair.New(FromCell, FromSubCell) };
return new[] { (FromCell, FromSubCell) };
// HACK: Should be fixed properly, see https://github.com/OpenRA/OpenRA/pull/17292 for an explanation
if (Info.LocomotorInfo.SharesCell)
return new[] { Pair.New(ToCell, ToSubCell) };
return new[] { (ToCell, ToSubCell) };
return new[] { Pair.New(FromCell, FromSubCell), Pair.New(ToCell, ToSubCell) };
return new[] { (FromCell, FromSubCell), (ToCell, ToSubCell) };
}
#endregion

View File

@@ -78,12 +78,12 @@ namespace OpenRA.Mods.Common.Traits
var myTeam = self.World.LobbyInfo.ClientWithIndex(self.Owner.ClientIndex).Team;
var teams = self.World.Players.Where(p => !p.NonCombatant && p.Playable)
.Select(p => new Pair<Player, PlayerStatistics>(p, p.PlayerActor.TraitOrDefault<PlayerStatistics>()))
.OrderByDescending(p => p.Second != null ? p.Second.Experience : 0)
.GroupBy(p => (self.World.LobbyInfo.ClientWithIndex(p.First.ClientIndex) ?? new Session.Client()).Team)
.OrderByDescending(g => g.Sum(gg => gg.Second != null ? gg.Second.Experience : 0));
.Select(p => (Player: p, PlayerStatistics: p.PlayerActor.TraitOrDefault<PlayerStatistics>()))
.OrderByDescending(p => p.PlayerStatistics != null ? p.PlayerStatistics.Experience : 0)
.GroupBy(p => (self.World.LobbyInfo.ClientWithIndex(p.Player.ClientIndex) ?? new Session.Client()).Team)
.OrderByDescending(g => g.Sum(gg => gg.PlayerStatistics != null ? gg.PlayerStatistics.Experience : 0));
if (teams.First().Key == myTeam && (myTeam != 0 || teams.First().First().First == self.Owner))
if (teams.First().Key == myTeam && (myTeam != 0 || teams.First().First().Player == self.Owner))
{
mo.MarkCompleted(self.Owner, objectiveID);
return;

View File

@@ -25,7 +25,7 @@ namespace OpenRA.Mods.Common.Traits
public class GrantConditionOnPrerequisiteManager : ITechTreeElement
{
readonly Actor self;
readonly Dictionary<string, List<Pair<Actor, GrantConditionOnPrerequisite>>> upgradables = new Dictionary<string, List<Pair<Actor, GrantConditionOnPrerequisite>>>();
readonly Dictionary<string, List<(Actor Actor, GrantConditionOnPrerequisite GrantConditionOnPrerequisite)>> upgradables = new Dictionary<string, List<(Actor, GrantConditionOnPrerequisite)>>();
readonly TechTree techTree;
public GrantConditionOnPrerequisiteManager(ActorInitializer init)
@@ -44,11 +44,11 @@ namespace OpenRA.Mods.Common.Traits
var key = MakeKey(prerequisites);
if (!upgradables.ContainsKey(key))
{
upgradables.Add(key, new List<Pair<Actor, GrantConditionOnPrerequisite>>());
upgradables.Add(key, new List<(Actor, GrantConditionOnPrerequisite)>());
techTree.Add(key, prerequisites, 0, this);
}
upgradables[key].Add(Pair.New(actor, u));
upgradables[key].Add((actor, u));
// Notify the current state
u.PrerequisitesUpdated(actor, techTree.HasPrerequisites(prerequisites));
@@ -59,7 +59,7 @@ namespace OpenRA.Mods.Common.Traits
var key = MakeKey(prerequisites);
var list = upgradables[key];
list.RemoveAll(x => x.First == actor && x.Second == u);
list.RemoveAll(x => x.Actor == actor && x.GrantConditionOnPrerequisite == u);
if (!list.Any())
{
upgradables.Remove(key);
@@ -69,22 +69,22 @@ namespace OpenRA.Mods.Common.Traits
public void PrerequisitesAvailable(string key)
{
List<Pair<Actor, GrantConditionOnPrerequisite>> list;
List<(Actor Actor, GrantConditionOnPrerequisite GrantConditionOnPrerequisite)> list;
if (!upgradables.TryGetValue(key, out list))
return;
foreach (var u in list)
u.Second.PrerequisitesUpdated(u.First, true);
u.GrantConditionOnPrerequisite.PrerequisitesUpdated(u.Actor, true);
}
public void PrerequisitesUnavailable(string key)
{
List<Pair<Actor, GrantConditionOnPrerequisite>> list;
List<(Actor Actor, GrantConditionOnPrerequisite GrantConditionOnPrerequisite)> list;
if (!upgradables.TryGetValue(key, out list))
return;
foreach (var u in list)
u.Second.PrerequisitesUpdated(u.First, false);
u.GrantConditionOnPrerequisite.PrerequisitesUpdated(u.Actor, false);
}
public void PrerequisitesItemHidden(string key) { }

View File

@@ -119,16 +119,16 @@ namespace OpenRA.Mods.Common.Traits
foreach (var t in BuildingUtils.GetLineBuildCells(w, targetLocation, actorInfo, buildingInfo, order.Player))
{
if (t.First == targetLocation)
if (t.Cell == targetLocation)
continue;
w.CreateActor(t.First == targetLocation ? actorInfo.Name : segmentType, new TypeDictionary
w.CreateActor(t.Cell == targetLocation ? actorInfo.Name : segmentType, new TypeDictionary
{
new LocationInit(t.First),
new LocationInit(t.Cell),
new OwnerInit(order.Player),
new FactionInit(faction),
new LineBuildDirectionInit(t.First.X == targetLocation.X ? LineBuildDirection.Y : LineBuildDirection.X),
new LineBuildParentInit(new[] { t.Second, placed }),
new LineBuildDirectionInit(t.Cell.X == targetLocation.X ? LineBuildDirection.Y : LineBuildDirection.X),
new LineBuildParentInit(new[] { t.Actor, placed }),
new PlaceBuildingInit()
});
}

View File

@@ -29,7 +29,7 @@ namespace OpenRA.Mods.Common.Traits
public bool IsInitialized { get; private set; }
readonly World world;
CellLayer<Pair<int, int>> terrainColor;
CellLayer<(int, int)> terrainColor;
readonly Shroud shroud;
public event Action<MPos> CellTerrainColorChanged = null;
@@ -67,7 +67,7 @@ namespace OpenRA.Mods.Common.Traits
public void WorldLoaded(World w, WorldRenderer wr)
{
terrainColor = new CellLayer<Pair<int, int>>(w.Map);
terrainColor = new CellLayer<(int, int)>(w.Map);
w.AddFrameEndTask(_ =>
{
@@ -82,22 +82,22 @@ namespace OpenRA.Mods.Common.Traits
});
}
public Pair<int, int> this[MPos uv]
public (int Left, int Right) this[MPos uv]
{
get { return terrainColor[uv]; }
}
public static Pair<int, int> GetColor(Map map, MPos uv)
public static (int Left, int Right) GetColor(Map map, MPos uv)
{
var custom = map.CustomTerrain[uv];
if (custom != byte.MaxValue)
{
var c = map.Rules.TileSet[custom].Color.ToArgb();
return Pair.New(c, c);
return (c, c);
}
var tc = map.GetTerrainColorPair(uv);
return Pair.New(tc.First.ToArgb(), tc.Second.ToArgb());
return (tc.Left.ToArgb(), tc.Right.ToArgb());
}
}
}

View File

@@ -119,12 +119,12 @@ namespace OpenRA.Mods.Common.Traits
var myTeam = self.World.LobbyInfo.ClientWithIndex(self.Owner.ClientIndex).Team;
var teams = self.World.Players.Where(p => !p.NonCombatant && p.Playable)
.Select(p => new Pair<Player, PlayerStatistics>(p, p.PlayerActor.TraitOrDefault<PlayerStatistics>()))
.OrderByDescending(p => p.Second != null ? p.Second.Experience : 0)
.GroupBy(p => (self.World.LobbyInfo.ClientWithIndex(p.First.ClientIndex) ?? new Session.Client()).Team)
.OrderByDescending(g => g.Sum(gg => gg.Second != null ? gg.Second.Experience : 0));
.Select(p => (Player: p, PlayerStatistics: p.PlayerActor.TraitOrDefault<PlayerStatistics>()))
.OrderByDescending(p => p.PlayerStatistics != null ? p.PlayerStatistics.Experience : 0)
.GroupBy(p => (self.World.LobbyInfo.ClientWithIndex(p.Player.ClientIndex) ?? new Session.Client()).Team)
.OrderByDescending(g => g.Sum(gg => gg.PlayerStatistics != null ? gg.PlayerStatistics.Experience : 0));
if (teams.First().Key == myTeam && (myTeam != 0 || teams.First().First().First == self.Owner))
if (teams.First().Key == myTeam && (myTeam != 0 || teams.First().First().Player == self.Owner))
{
mo.MarkCompleted(self.Owner, objectiveID);
return;

View File

@@ -39,7 +39,7 @@ namespace OpenRA.Mods.Common.Traits.Radar
modifier = self.TraitsImplementing<IRadarColorModifier>().FirstOrDefault();
}
public void PopulateRadarSignatureCells(Actor self, List<Pair<CPos, Color>> destinationBuffer)
public void PopulateRadarSignatureCells(Actor self, List<(CPos Cell, Color Color)> destinationBuffer)
{
var viewer = self.World.RenderPlayer ?? self.World.LocalPlayer;
if (IsTraitDisabled || (viewer != null && !Info.ValidStances.HasStance(self.Owner.Stances[viewer])))
@@ -51,12 +51,12 @@ namespace OpenRA.Mods.Common.Traits.Radar
if (Info.UseLocation)
{
destinationBuffer.Add(Pair.New(self.Location, color));
destinationBuffer.Add((self.Location, color));
return;
}
foreach (var cell in self.OccupiesSpace.OccupiedCells())
destinationBuffer.Add(Pair.New(cell.First, color));
destinationBuffer.Add((cell.Cell, color));
}
}
}

View File

@@ -87,12 +87,12 @@ namespace OpenRA.Mods.Common.Traits.Render
public class RenderSprites : IRender, ITick, INotifyOwnerChanged, INotifyEffectiveOwnerChanged, IActorPreviewInitModifier
{
static readonly Pair<DamageState, string>[] DamagePrefixes =
static readonly (DamageState DamageState, string Prefix)[] DamagePrefixes =
{
Pair.New(DamageState.Critical, "critical-"),
Pair.New(DamageState.Heavy, "damaged-"),
Pair.New(DamageState.Medium, "scratched-"),
Pair.New(DamageState.Light, "scuffed-")
(DamageState.Critical, "critical-"),
(DamageState.Heavy, "damaged-"),
(DamageState.Medium, "scratched-"),
(DamageState.Light, "scuffed-")
};
class AnimationWrapper
@@ -251,9 +251,9 @@ namespace OpenRA.Mods.Common.Traits.Render
// Remove existing damage prefix
foreach (var s in DamagePrefixes)
{
if (sequence.StartsWith(s.Second, StringComparison.Ordinal))
if (sequence.StartsWith(s.Prefix, StringComparison.Ordinal))
{
sequence = sequence.Substring(s.Second.Length);
sequence = sequence.Substring(s.Prefix.Length);
break;
}
}
@@ -267,8 +267,8 @@ namespace OpenRA.Mods.Common.Traits.Render
sequence = UnnormalizeSequence(sequence);
foreach (var s in DamagePrefixes)
if (state >= s.First && anim.HasSequence(s.Second + sequence))
return s.Second + sequence;
if (state >= s.DamageState && anim.HasSequence(s.Prefix + sequence))
return s.Prefix + sequence;
return sequence;
}

View File

@@ -97,7 +97,7 @@ namespace OpenRA.Mods.Common.Traits
SendParatroopers(self, order.Target.CenterPosition, facing);
}
public Pair<Actor[], Actor[]> SendParatroopers(Actor self, WPos target, WAngle? facing = null)
public (Actor[] Aircraft, Actor[] Units) SendParatroopers(Actor self, WPos target, WAngle? facing = null)
{
var aircraft = new List<Actor>();
var units = new List<Actor>();
@@ -266,7 +266,7 @@ namespace OpenRA.Mods.Common.Traits
}
});
return Pair.New(aircraft.ToArray(), units.ToArray());
return (aircraft.ToArray(), units.ToArray());
}
void RemoveCamera(Actor camera)

View File

@@ -359,20 +359,20 @@ namespace OpenRA.Mods.Common.Traits
{
foreach (var c in ios.OccupiedCells())
{
var uv = c.First.ToMPos(map);
var uv = c.Cell.ToMPos(map);
if (!influence.Contains(uv))
continue;
var layer = c.First.Layer == 0 ? influence : customInfluence[c.First.Layer];
layer[uv] = new InfluenceNode { Next = layer[uv], SubCell = c.Second, Actor = self };
var layer = c.Cell.Layer == 0 ? influence : customInfluence[c.Cell.Layer];
layer[uv] = new InfluenceNode { Next = layer[uv], SubCell = c.SubCell, Actor = self };
List<CellTrigger> triggers;
if (cellTriggerInfluence.TryGetValue(c.First, out triggers))
if (cellTriggerInfluence.TryGetValue(c.Cell, out triggers))
foreach (var t in triggers)
t.Dirty = true;
if (CellUpdated != null)
CellUpdated(c.First);
CellUpdated(c.Cell);
}
}
@@ -380,22 +380,22 @@ namespace OpenRA.Mods.Common.Traits
{
foreach (var c in ios.OccupiedCells())
{
var uv = c.First.ToMPos(map);
var uv = c.Cell.ToMPos(map);
if (!influence.Contains(uv))
continue;
var layer = c.First.Layer == 0 ? influence : customInfluence[c.First.Layer];
var layer = c.Cell.Layer == 0 ? influence : customInfluence[c.Cell.Layer];
var temp = layer[uv];
RemoveInfluenceInner(ref temp, self);
layer[uv] = temp;
List<CellTrigger> triggers;
if (cellTriggerInfluence.TryGetValue(c.First, out triggers))
if (cellTriggerInfluence.TryGetValue(c.Cell, out triggers))
foreach (var t in triggers)
t.Dirty = true;
if (CellUpdated != null)
CellUpdated(c.First);
CellUpdated(c.Cell);
}
}
@@ -416,7 +416,7 @@ namespace OpenRA.Mods.Common.Traits
return;
foreach (var c in ios.OccupiedCells())
CellUpdated(c.First);
CellUpdated(c.Cell);
}
void ITick.Tick(Actor self)

View File

@@ -315,11 +315,11 @@ namespace OpenRA.Mods.Common.Traits
return nodes;
}
public void PopulateRadarSignatureCells(Actor self, List<Pair<CPos, Color>> destinationBuffer)
public void PopulateRadarSignatureCells(Actor self, List<(CPos Cell, Color Color)> destinationBuffer)
{
foreach (var previewsForCell in cellMap)
foreach (var preview in previewsForCell.Value)
destinationBuffer.Add(Pair.New(previewsForCell.Key, preview.RadarColor));
destinationBuffer.Add((previewsForCell.Key, preview.RadarColor));
}
public EditorActorPreview this[string id]

View File

@@ -28,7 +28,7 @@ namespace OpenRA.Mods.Common.Traits
class LegacyBridgeLayer : IWorldLoaded
{
readonly LegacyBridgeLayerInfo info;
readonly Dictionary<ushort, Pair<string, int>> bridgeTypes = new Dictionary<ushort, Pair<string, int>>();
readonly Dictionary<ushort, (string Template, int Health)> bridgeTypes = new Dictionary<ushort, (string, int)>();
CellLayer<Bridge> bridges;
@@ -46,7 +46,7 @@ namespace OpenRA.Mods.Common.Traits
{
var bi = w.Map.Rules.Actors[bridge].TraitInfo<BridgeInfo>();
foreach (var template in bi.Templates)
bridgeTypes.Add(template.First, Pair.New(bridge, template.Second));
bridgeTypes.Add(template.Template, (bridge, template.Health));
}
// Take all templates to overlay from the map
@@ -73,11 +73,11 @@ namespace OpenRA.Mods.Common.Traits
var nj = cell.Y - index / template.Size.X;
// Create a new actor for this bridge and keep track of which subtiles this bridge includes
var bridge = w.CreateActor(bridgeTypes[tile].First, new TypeDictionary
var bridge = w.CreateActor(bridgeTypes[tile].Template, new TypeDictionary
{
new LocationInit(new CPos(ni, nj)),
new OwnerInit(w.WorldActor.Owner),
new HealthInit(bridgeTypes[tile].Second, true),
new HealthInit(bridgeTypes[tile].Health, true),
}).Trait<Bridge>();
var subTiles = new Dictionary<CPos, byte>();

View File

@@ -133,8 +133,8 @@ namespace OpenRA.Mods.Common.Traits
var n = taken.Count == 0 || !separateTeamSpawns
? world.SharedRandom.Next(available.Count)
: available // pick the most distant spawnpoint from everyone else
.Select((k, i) => Pair.New(k, i))
.MaxBy(a => taken.Sum(t => (t - a.First).LengthSquared)).Second;
.Select((k, i) => (Cell: k, Index: i))
.MaxBy(a => taken.Sum(t => (t - a.Cell).LengthSquared)).Index;
var sp = available[n];
available.RemoveAt(n);

View File

@@ -63,7 +63,7 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Allow resource to spawn on ramp tiles.")]
public readonly bool AllowOnRamps = false;
void IMapPreviewSignatureInfo.PopulateMapPreviewSignatureCells(Map map, ActorInfo ai, ActorReference s, List<Pair<MPos, Color>> destinationBuffer)
void IMapPreviewSignatureInfo.PopulateMapPreviewSignatureCells(Map map, ActorInfo ai, ActorReference s, List<(MPos, Color)> destinationBuffer)
{
var tileSet = map.Rules.TileSet;
var color = tileSet[tileSet.GetTerrainIndex(TerrainType)].Color;
@@ -74,7 +74,7 @@ namespace OpenRA.Mods.Common.Traits
{
var cell = new MPos(i, j);
if (map.Resources[cell].Type == ResourceType)
destinationBuffer.Add(new Pair<MPos, Color>(cell, color));
destinationBuffer.Add((cell, color));
}
}
}

View File

@@ -441,7 +441,7 @@ namespace OpenRA.Mods.Common.Traits
public interface IRadarSignature
{
void PopulateRadarSignatureCells(Actor self, List<Pair<CPos, Color>> destinationBuffer);
void PopulateRadarSignatureCells(Actor self, List<(CPos Cell, Color Color)> destinationBuffer);
}
public interface IRadarColorModifier { Color RadarColorOverride(Actor self, Color color); }
@@ -476,7 +476,7 @@ namespace OpenRA.Mods.Common.Traits
[RequireExplicitImplementation]
public interface ITargetableCells
{
Pair<CPos, SubCell>[] TargetableCells();
(CPos Cell, SubCell SubCell)[] TargetableCells();
}
[RequireExplicitImplementation]

View File

@@ -17,7 +17,7 @@ using OpenRA.FileSystem;
namespace OpenRA.Mods.Common.UpdateRules
{
using YamlFileSet = List<Tuple<IReadWritePackage, string, List<MiniYamlNode>>>;
using YamlFileSet = List<(IReadWritePackage, string, List<MiniYamlNode>)>;
public static class UpdateUtils
{
@@ -37,7 +37,7 @@ namespace OpenRA.Mods.Common.UpdateRules
continue;
}
yaml.Add(Tuple.Create((IReadWritePackage)package, name, MiniYaml.FromStream(package.GetStream(name), name, false)));
yaml.Add(((IReadWritePackage)package, name, MiniYaml.FromStream(package.GetStream(name), name, false)));
}
return yaml;
@@ -62,7 +62,7 @@ namespace OpenRA.Mods.Common.UpdateRules
{
var fileSet = new YamlFileSet()
{
Tuple.Create<IReadWritePackage, string, List<MiniYamlNode>>(null, "map.yaml", yaml.Nodes)
(null, "map.yaml", yaml.Nodes)
};
var files = FieldLoader.GetValue<string[]>("value", yaml.Value);
@@ -70,7 +70,7 @@ namespace OpenRA.Mods.Common.UpdateRules
{
// Ignore any files that aren't in the map bundle
if (!filename.Contains("|") && mapPackage.Contains(filename))
fileSet.Add(Tuple.Create(mapPackage, filename, MiniYaml.FromStream(mapPackage.GetStream(filename), filename, false)));
fileSet.Add((mapPackage, filename, MiniYaml.FromStream(mapPackage.GetStream(filename), filename, false)));
else if (modData.ModFiles.Exists(filename))
externalFilenames.Add(filename);
}
@@ -97,7 +97,7 @@ namespace OpenRA.Mods.Common.UpdateRules
}
var yaml = new MiniYaml(null, MiniYaml.FromStream(mapStream, mapPackage.Name, false));
files = new YamlFileSet() { Tuple.Create(mapPackage, "map.yaml", yaml.Nodes) };
files = new YamlFileSet() { (mapPackage, "map.yaml", yaml.Nodes) };
manualSteps.AddRange(rule.BeforeUpdate(modData));
@@ -106,7 +106,7 @@ namespace OpenRA.Mods.Common.UpdateRules
{
var mapActors = new YamlFileSet()
{
Tuple.Create<IReadWritePackage, string, List<MiniYamlNode>>(null, "map.yaml", mapActorsNode.Value.Nodes)
(null, "map.yaml", mapActorsNode.Value.Nodes)
};
manualSteps.AddRange(ApplyTopLevelTransform(modData, mapActors, rule.UpdateMapActorNode));

View File

@@ -46,24 +46,24 @@ namespace OpenRA.Mods.Common.UtilityCommands
var pr = c.Value.PanelRegion;
if (pr != null && pr.Length == 8)
{
var sides = new[]
var sides = new (PanelSides PanelSides, Rectangle Bounds)[]
{
Pair.New(PanelSides.Top | PanelSides.Left, new Rectangle(pr[0], pr[1], pr[2], pr[3])),
Pair.New(PanelSides.Top, new Rectangle(pr[0] + pr[2], pr[1], pr[4], pr[3])),
Pair.New(PanelSides.Top | PanelSides.Right, new Rectangle(pr[0] + pr[2] + pr[4], pr[1], pr[6], pr[3])),
Pair.New(PanelSides.Left, new Rectangle(pr[0], pr[1] + pr[3], pr[2], pr[5])),
Pair.New(PanelSides.Center, new Rectangle(pr[0] + pr[2], pr[1] + pr[3], pr[4], pr[5])),
Pair.New(PanelSides.Right, new Rectangle(pr[0] + pr[2] + pr[4], pr[1] + pr[3], pr[6], pr[5])),
Pair.New(PanelSides.Bottom | PanelSides.Left, new Rectangle(pr[0], pr[1] + pr[3] + pr[5], pr[2], pr[7])),
Pair.New(PanelSides.Bottom, new Rectangle(pr[0] + pr[2], pr[1] + pr[3] + pr[5], pr[4], pr[7])),
Pair.New(PanelSides.Bottom | PanelSides.Right, new Rectangle(pr[0] + pr[2] + pr[4], pr[1] + pr[3] + pr[5], pr[6], pr[7]))
(PanelSides.Top | PanelSides.Left, new Rectangle(pr[0], pr[1], pr[2], pr[3])),
(PanelSides.Top, new Rectangle(pr[0] + pr[2], pr[1], pr[4], pr[3])),
(PanelSides.Top | PanelSides.Right, new Rectangle(pr[0] + pr[2] + pr[4], pr[1], pr[6], pr[3])),
(PanelSides.Left, new Rectangle(pr[0], pr[1] + pr[3], pr[2], pr[5])),
(PanelSides.Center, new Rectangle(pr[0] + pr[2], pr[1] + pr[3], pr[4], pr[5])),
(PanelSides.Right, new Rectangle(pr[0] + pr[2] + pr[4], pr[1] + pr[3], pr[6], pr[5])),
(PanelSides.Bottom | PanelSides.Left, new Rectangle(pr[0], pr[1] + pr[3] + pr[5], pr[2], pr[7])),
(PanelSides.Bottom, new Rectangle(pr[0] + pr[2], pr[1] + pr[3] + pr[5], pr[4], pr[7])),
(PanelSides.Bottom | PanelSides.Right, new Rectangle(pr[0] + pr[2] + pr[4], pr[1] + pr[3] + pr[5], pr[6], pr[7]))
};
foreach (var s in sides)
{
var r = s.Second;
if (c.Value.PanelSides.HasSide(s.First))
regions.Add("[\"{0}.<{1}>\",{2},{3},{4},{5}]".F(c.Key, s.First, r.X, r.Y, r.Width, r.Height));
var r = s.Bounds;
if (c.Value.PanelSides.HasSide(s.PanelSides))
regions.Add("[\"{0}.<{1}>\",{2},{3},{4},{5}]".F(c.Key, s.PanelSides, r.X, r.Y, r.Width, r.Height));
}
}

View File

@@ -87,7 +87,7 @@ namespace OpenRA.Mods.Common.UtilityCommands
var category = catAttr != null ? catAttr.Category : "Unsorted";
var required = RequiredTraitNames(cg);
return ScriptMemberWrapper.WrappableMembers(cg).Select(mi => Tuple.Create(category, mi, required));
return ScriptMemberWrapper.WrappableMembers(cg).Select(mi => (category, mi, required));
}).GroupBy(g => g.Item1).OrderBy(g => g.Key);
foreach (var kv in actorCategories)
@@ -132,7 +132,7 @@ namespace OpenRA.Mods.Common.UtilityCommands
var category = catAttr != null ? catAttr.Category : "Unsorted";
var required = RequiredTraitNames(cg);
return ScriptMemberWrapper.WrappableMembers(cg).Select(mi => Tuple.Create(category, mi, required));
return ScriptMemberWrapper.WrappableMembers(cg).Select(mi => (category, mi, required));
}).GroupBy(g => g.Item1).OrderBy(g => g.Key);
foreach (var kv in playerCategories)

View File

@@ -251,17 +251,17 @@ namespace OpenRA.Mods.Common.UtilityCommands
var actorCount = Map.ActorDefinitions.Count;
var wps = waypointSection
.Where(kv => Exts.ParseIntegerInvariant(kv.Value) > 0)
.Select(kv => Pair.New(Exts.ParseIntegerInvariant(kv.Key),
LocationFromMapOffset(Exts.ParseIntegerInvariant(kv.Value), MapSize)));
.Select(kv => (WaypointNumber: Exts.ParseIntegerInvariant(kv.Key),
Location: LocationFromMapOffset(Exts.ParseIntegerInvariant(kv.Value), MapSize)));
// Add waypoint actors skipping duplicate entries
foreach (var kv in wps.DistinctBy(location => location.Second))
foreach (var kv in wps.DistinctBy(location => location.Location))
{
if (!singlePlayer && kv.First <= 7)
if (!singlePlayer && kv.WaypointNumber <= 7)
{
var ar = new ActorReference("mpspawn")
{
new LocationInit((CPos)kv.Second),
new LocationInit((CPos)kv.Location),
new OwnerInit("Neutral")
};
@@ -272,11 +272,11 @@ namespace OpenRA.Mods.Common.UtilityCommands
{
var ar = new ActorReference("waypoint")
{
new LocationInit((CPos)kv.Second),
new LocationInit((CPos)kv.Location),
new OwnerInit("Neutral")
};
SaveWaypoint(kv.First, ar);
SaveWaypoint(kv.WaypointNumber, ar);
}
}
}

View File

@@ -18,7 +18,7 @@ using OpenRA.Mods.Common.UpdateRules;
namespace OpenRA.Mods.Common.UtilityCommands
{
using YamlFileSet = List<Tuple<IReadWritePackage, string, List<MiniYamlNode>>>;
using YamlFileSet = List<(IReadWritePackage, string, List<MiniYamlNode>)>;
class UpdateMapCommand : IUtilityCommand
{

View File

@@ -18,7 +18,7 @@ using OpenRA.Mods.Common.UpdateRules;
namespace OpenRA.Mods.Common.UtilityCommands
{
using YamlFileSet = List<Tuple<IReadWritePackage, string, List<MiniYamlNode>>>;
using YamlFileSet = List<(IReadWritePackage, string, List<MiniYamlNode>)>;
class UpdateModCommand : IUtilityCommand
{

View File

@@ -61,18 +61,18 @@ namespace OpenRA.Mods.Common.Warheads
var closestActiveShape = victim.TraitsImplementing<HitShape>()
.Where(Exts.IsTraitEnabled)
.Select(s => Pair.New(s, s.DistanceFromEdge(victim, pos)))
.MinByOrDefault(s => s.Second);
.Select(s => (HitShape: s, Distance: s.DistanceFromEdge(victim, pos)))
.MinByOrDefault(s => s.Distance);
// Cannot be damaged without an active HitShape.
if (closestActiveShape.First == null)
if (closestActiveShape.HitShape == null)
continue;
var falloffDistance = 0;
switch (DamageCalculationType)
{
case DamageCalculationType.HitShape:
falloffDistance = closestActiveShape.Second.Length;
falloffDistance = closestActiveShape.Distance.Length;
break;
case DamageCalculationType.ClosestTargetablePosition:
falloffDistance = victim.GetTargetablePositions().Select(x => (x - pos).Length).Min();
@@ -104,7 +104,7 @@ namespace OpenRA.Mods.Common.Warheads
ImpactOrientation = impactOrientation,
};
InflictDamage(victim, firedBy, closestActiveShape.First, updatedWarheadArgs);
InflictDamage(victim, firedBy, closestActiveShape.HitShape, updatedWarheadArgs);
}
}

View File

@@ -38,18 +38,18 @@ namespace OpenRA.Mods.Common.Warheads
var closestActiveShape = victim.TraitsImplementing<HitShape>()
.Where(Exts.IsTraitEnabled)
.Select(s => Pair.New(s, s.DistanceFromEdge(victim, pos)))
.MinByOrDefault(s => s.Second);
.Select(s => (HitShape: s, Distance: s.DistanceFromEdge(victim, pos)))
.MinByOrDefault(s => s.Distance);
// Cannot be damaged without an active HitShape.
if (closestActiveShape.First == null)
if (closestActiveShape.HitShape == null)
continue;
// Cannot be damaged if HitShape is outside Spread.
if (closestActiveShape.Second > Spread)
if (closestActiveShape.Distance > Spread)
continue;
InflictDamage(victim, firedBy, closestActiveShape.First, args);
InflictDamage(victim, firedBy, closestActiveShape.HitShape, args);
}
}
}

View File

@@ -20,25 +20,25 @@ namespace OpenRA.Mods.Common.Widgets
public class LabelWithHighlightWidget : LabelWidget
{
public Color HighlightColor = ChromeMetrics.Get<Color>("TextHighlightColor");
readonly CachedTransform<string, Pair<string, bool>[]> textComponents;
readonly CachedTransform<string, (string Text, bool Highlighted)[]> textComponents;
[ObjectCreator.UseCtor]
public LabelWithHighlightWidget()
: base()
{
textComponents = new CachedTransform<string, Pair<string, bool>[]>(MakeComponents);
textComponents = new CachedTransform<string, (string, bool)[]>(MakeComponents);
}
protected LabelWithHighlightWidget(LabelWithHighlightWidget other)
: base(other)
{
HighlightColor = other.HighlightColor;
textComponents = new CachedTransform<string, Pair<string, bool>[]>(MakeComponents);
textComponents = new CachedTransform<string, (string, bool)[]>(MakeComponents);
}
Pair<string, bool>[] MakeComponents(string text)
(string, bool)[] MakeComponents(string text)
{
List<Pair<string, bool>> components = new List<Pair<string, bool>>();
var components = new List<(string, bool)>();
foreach (var l in text.Split(new[] { "\\n" }, StringSplitOptions.None))
{
var line = l;
@@ -54,18 +54,18 @@ namespace OpenRA.Mods.Common.Widgets
{
// Normal line segment before highlight
var lineNormal = line.Substring(0, highlightStart);
components.Add(Pair.New(lineNormal, false));
components.Add((lineNormal, false));
}
// Highlight line segment
var lineHighlight = line.Substring(highlightStart + 1, highlightEnd - highlightStart - 1);
components.Add(Pair.New(lineHighlight, true));
components.Add((lineHighlight, true));
line = line.Substring(highlightEnd + 1);
}
else
{
// Final normal line segment
components.Add(Pair.New(line, false));
components.Add((line, false));
break;
}
}
@@ -79,8 +79,8 @@ namespace OpenRA.Mods.Common.Widgets
var advance = 0;
foreach (var c in textComponents.Update(text))
{
base.DrawInner(c.First, font, c.Second ? HighlightColor : color, position + new int2(advance, 0));
advance += font.Measure(c.First).X;
base.DrawInner(c.Text, font, c.Highlighted ? HighlightColor : color, position + new int2(advance, 0));
advance += font.Measure(c.Text).X;
}
}

View File

@@ -66,10 +66,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
playerPanel.RemoveChildren();
var teams = world.Players.Where(p => !p.NonCombatant && p.Playable)
.Select(p => new Pair<Player, PlayerStatistics>(p, p.PlayerActor.TraitOrDefault<PlayerStatistics>()))
.OrderByDescending(p => p.Second != null ? p.Second.Experience : 0)
.GroupBy(p => (world.LobbyInfo.ClientWithIndex(p.First.ClientIndex) ?? new Session.Client()).Team)
.OrderByDescending(g => g.Sum(gg => gg.Second != null ? gg.Second.Experience : 0));
.Select(p => (Player: p, PlayerStatistics: p.PlayerActor.TraitOrDefault<PlayerStatistics>()))
.OrderByDescending(p => p.PlayerStatistics != null ? p.PlayerStatistics.Experience : 0)
.GroupBy(p => (world.LobbyInfo.ClientWithIndex(p.Player.ClientIndex) ?? new Session.Client()).Team)
.OrderByDescending(g => g.Sum(gg => gg.PlayerStatistics != null ? gg.PlayerStatistics.Experience : 0));
foreach (var t in teams)
{
@@ -79,7 +79,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
teamHeader.Get<LabelWidget>("TEAM").GetText = () => t.Key == 0 ? "No Team" : "Team {0}".F(t.Key);
var teamRating = teamHeader.Get<LabelWidget>("TEAM_SCORE");
var scoreCache = new CachedTransform<int, string>(s => s.ToString());
var teamMemberScores = t.Select(tt => tt.Second).Where(s => s != null).ToArray().Select(s => s.Experience);
var teamMemberScores = t.Select(tt => tt.PlayerStatistics).Where(s => s != null).ToArray().Select(s => s.Experience);
teamRating.GetText = () => scoreCache.Update(teamMemberScores.Sum());
playerPanel.AddChild(teamHeader);
@@ -87,7 +87,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
foreach (var p in t.ToList())
{
var pp = p.First;
var pp = p.Player;
var client = world.LobbyInfo.ClientWithIndex(pp.ClientIndex);
var item = playerTemplate.Clone();
LobbyUtils.SetupProfileWidget(item, client, orderManager, worldRenderer);
@@ -110,7 +110,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
}
var scoreCache = new CachedTransform<int, string>(s => s.ToString());
item.Get<LabelWidget>("SCORE").GetText = () => scoreCache.Update(p.Second != null ? p.Second.Experience : 0);
item.Get<LabelWidget>("SCORE").GetText = () => scoreCache.Update(p.PlayerStatistics != null ? p.PlayerStatistics.Experience : 0);
playerPanel.AddChild(item);
}
@@ -133,13 +133,13 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var nameFont = Game.Renderer.Fonts[nameLabel.Font];
var suffixLength = new CachedTransform<string, int>(s => nameFont.Measure(s).X);
var name = new CachedTransform<Pair<string, string>, string>(c =>
WidgetUtils.TruncateText(c.First, nameLabel.Bounds.Width - suffixLength.Update(c.Second), nameFont) + c.Second);
var name = new CachedTransform<(string Name, string Suffix), string>(c =>
WidgetUtils.TruncateText(c.Name, nameLabel.Bounds.Width - suffixLength.Update(c.Suffix), nameFont) + c.Suffix);
nameLabel.GetText = () =>
{
var suffix = client.State == Session.ClientState.Disconnected ? " (Gone)" : "";
return name.Update(Pair.New(client.Name, suffix));
return name.Update((client.Name, suffix));
};
var kickButton = item.Get<ButtonWidget>("KICK");

View File

@@ -442,8 +442,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
if (powerRes != null)
{
var power = template.Get<LabelWidget>("POWER");
var powerText = new CachedTransform<Pair<int, int>, string>(p => p.First + "/" + p.Second);
power.GetText = () => powerText.Update(new Pair<int, int>(powerRes.PowerDrained, powerRes.PowerProvided));
var powerText = new CachedTransform<(int PowerDrained, int PowerProvided), string>(p => p.PowerDrained + "/" + p.PowerProvided);
power.GetText = () => powerText.Update((powerRes.PowerDrained, powerRes.PowerProvided));
power.GetColor = () => GetPowerColor(powerRes.PowerState);
}

View File

@@ -162,15 +162,15 @@ namespace OpenRA.Mods.Common.Widgets.Logic
}
/// <summary>Splits a string into two parts on the first instance of a given token.</summary>
static Pair<string, string> SplitOnFirstToken(string input, string token = "\\n")
static (string First, string Second) SplitOnFirstToken(string input, string token = "\\n")
{
if (string.IsNullOrEmpty(input))
return Pair.New<string, string>(null, null);
return (null, null);
var split = input.IndexOf(token, StringComparison.Ordinal);
var first = split > 0 ? input.Substring(0, split) : input;
var second = split > 0 ? input.Substring(split + token.Length) : null;
return Pair.New(first, second);
return (first, second);
}
public static void ShowFactionDropDown(DropDownButtonWidget dropdown, Session.Client client,
@@ -253,9 +253,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var spawnSize = ChromeProvider.GetImage("lobby-bits", "spawn-unclaimed").Size.XY;
var selectedSpawn = preview.SpawnPoints
.Select((sp, i) => Pair.New(mapPreview.ConvertToPreview(sp, preview.GridType), i))
.Where(a => ((a.First - mi.Location).ToFloat2() / spawnSize * 2).LengthSquared <= 1)
.Select(a => a.Second + 1)
.Select((sp, i) => (SpawnLocation: mapPreview.ConvertToPreview(sp, preview.GridType), Index: i))
.Where(a => ((a.SpawnLocation - mi.Location).ToFloat2() / spawnSize * 2).LengthSquared <= 1)
.Select(a => a.Index + 1)
.FirstOrDefault();
var locals = orderManager.LobbyInfo.Clients.Where(c => c.Index == orderManager.LocalClient.Index || (Game.IsHost && c.Bot != null));

View File

@@ -12,7 +12,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using OpenRA.Primitives;
using OpenRA.Widgets;
namespace OpenRA.Mods.Common.Widgets.Logic
@@ -182,20 +181,20 @@ namespace OpenRA.Mods.Common.Widgets.Logic
// Order categories alphabetically
var categories = categoryDict
.Select(kv => Pair.New(kv.Key, kv.Value))
.OrderBy(p => p.First)
.Select(kv => (Category: kv.Key, Count: kv.Value))
.OrderBy(p => p.Category)
.ToList();
// 'all game types' extra item
categories.Insert(0, Pair.New(null as string, tabMaps[tab].Count()));
categories.Insert(0, (null as string, tabMaps[tab].Count()));
Func<Pair<string, int>, string> showItem = x => "{0} ({1})".F(x.First ?? "All Maps", x.Second);
Func<(string Category, int Count), string> showItem = x => "{0} ({1})".F(x.Category ?? "All Maps", x.Count);
Func<Pair<string, int>, ScrollItemWidget, ScrollItemWidget> setupItem = (ii, template) =>
Func<(string Category, int Count), ScrollItemWidget, ScrollItemWidget> setupItem = (ii, template) =>
{
var item = ScrollItemWidget.Setup(template,
() => category == ii.First,
() => { category = ii.First; EnumerateMaps(tab, itemTemplate); });
() => category == ii.Category,
() => { category = ii.Category; EnumerateMaps(tab, itemTemplate); });
item.Get<LabelWidget>("LABEL").GetText = () => showItem(ii);
return item;
};
@@ -205,9 +204,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic
gameModeDropdown.GetText = () =>
{
var item = categories.FirstOrDefault(m => m.First == category);
if (item == default(Pair<string, int>))
item.First = "No matches";
var item = categories.FirstOrDefault(m => m.Category == category);
if (item == default((string, int)))
item.Category = "No matches";
return showItem(item);
};

View File

@@ -138,25 +138,25 @@ namespace OpenRA.Mods.Common.Widgets.Logic
if (ddb != null)
{
// Using list to maintain the order
var options = new List<Pair<GameType, string>>
var options = new List<(GameType GameType, string Text)>
{
Pair.New(GameType.Any, ddb.GetText()),
Pair.New(GameType.Singleplayer, "Singleplayer"),
Pair.New(GameType.Multiplayer, "Multiplayer")
(GameType.Any, ddb.GetText()),
(GameType.Singleplayer, "Singleplayer"),
(GameType.Multiplayer, "Multiplayer")
};
var lookup = options.ToDictionary(kvp => kvp.First, kvp => kvp.Second);
var lookup = options.ToDictionary(kvp => kvp.GameType, kvp => kvp.Text);
ddb.GetText = () => lookup[filter.Type];
ddb.OnMouseDown = _ =>
{
Func<Pair<GameType, string>, ScrollItemWidget, ScrollItemWidget> setupItem = (option, tpl) =>
Func<(GameType GameType, string Text), ScrollItemWidget, ScrollItemWidget> setupItem = (option, tpl) =>
{
var item = ScrollItemWidget.Setup(
tpl,
() => filter.Type == option.First,
() => { filter.Type = option.First; ApplyFilter(); });
item.Get<LabelWidget>("LABEL").GetText = () => option.Second;
() => filter.Type == option.GameType,
() => { filter.Type = option.GameType; ApplyFilter(); });
item.Get<LabelWidget>("LABEL").GetText = () => option.Text;
return item;
};
@@ -171,28 +171,28 @@ namespace OpenRA.Mods.Common.Widgets.Logic
if (ddb != null)
{
// Using list to maintain the order
var options = new List<Pair<DateType, string>>
var options = new List<(DateType DateType, string Text)>
{
Pair.New(DateType.Any, ddb.GetText()),
Pair.New(DateType.Today, "Today"),
Pair.New(DateType.LastWeek, "Last 7 days"),
Pair.New(DateType.LastFortnight, "Last 14 days"),
Pair.New(DateType.LastMonth, "Last 30 days")
(DateType.Any, ddb.GetText()),
(DateType.Today, "Today"),
(DateType.LastWeek, "Last 7 days"),
(DateType.LastFortnight, "Last 14 days"),
(DateType.LastMonth, "Last 30 days")
};
var lookup = options.ToDictionary(kvp => kvp.First, kvp => kvp.Second);
var lookup = options.ToDictionary(kvp => kvp.DateType, kvp => kvp.Text);
ddb.GetText = () => lookup[filter.Date];
ddb.OnMouseDown = _ =>
{
Func<Pair<DateType, string>, ScrollItemWidget, ScrollItemWidget> setupItem = (option, tpl) =>
Func<(DateType DateType, string Text), ScrollItemWidget, ScrollItemWidget> setupItem = (option, tpl) =>
{
var item = ScrollItemWidget.Setup(
tpl,
() => filter.Date == option.First,
() => { filter.Date = option.First; ApplyFilter(); });
() => filter.Date == option.DateType,
() => { filter.Date = option.DateType; ApplyFilter(); });
item.Get<LabelWidget>("LABEL").GetText = () => option.Second;
item.Get<LabelWidget>("LABEL").GetText = () => option.Text;
return item;
};
@@ -207,27 +207,27 @@ namespace OpenRA.Mods.Common.Widgets.Logic
if (ddb != null)
{
// Using list to maintain the order
var options = new List<Pair<DurationType, string>>
var options = new List<(DurationType DurationType, string Text)>
{
Pair.New(DurationType.Any, ddb.GetText()),
Pair.New(DurationType.VeryShort, "Under 5 min"),
Pair.New(DurationType.Short, "Short (10 min)"),
Pair.New(DurationType.Medium, "Medium (30 min)"),
Pair.New(DurationType.Long, "Long (60+ min)")
(DurationType.Any, ddb.GetText()),
(DurationType.VeryShort, "Under 5 min"),
(DurationType.Short, "Short (10 min)"),
(DurationType.Medium, "Medium (30 min)"),
(DurationType.Long, "Long (60+ min)")
};
var lookup = options.ToDictionary(kvp => kvp.First, kvp => kvp.Second);
var lookup = options.ToDictionary(kvp => kvp.DurationType, kvp => kvp.Text);
ddb.GetText = () => lookup[filter.Duration];
ddb.OnMouseDown = _ =>
{
Func<Pair<DurationType, string>, ScrollItemWidget, ScrollItemWidget> setupItem = (option, tpl) =>
Func<(DurationType DurationType, string Text), ScrollItemWidget, ScrollItemWidget> setupItem = (option, tpl) =>
{
var item = ScrollItemWidget.Setup(
tpl,
() => filter.Duration == option.First,
() => { filter.Duration = option.First; ApplyFilter(); });
item.Get<LabelWidget>("LABEL").GetText = () => option.Second;
() => filter.Duration == option.DurationType,
() => { filter.Duration = option.DurationType; ApplyFilter(); });
item.Get<LabelWidget>("LABEL").GetText = () => option.Text;
return item;
};
@@ -244,25 +244,25 @@ namespace OpenRA.Mods.Common.Widgets.Logic
ddb.IsDisabled = () => string.IsNullOrEmpty(filter.PlayerName);
// Using list to maintain the order
var options = new List<Pair<WinState, string>>
var options = new List<(WinState WinState, string Text)>
{
Pair.New(WinState.Undefined, ddb.GetText()),
Pair.New(WinState.Lost, "Defeat"),
Pair.New(WinState.Won, "Victory")
(WinState.Undefined, ddb.GetText()),
(WinState.Lost, "Defeat"),
(WinState.Won, "Victory")
};
var lookup = options.ToDictionary(kvp => kvp.First, kvp => kvp.Second);
var lookup = options.ToDictionary(kvp => kvp.WinState, kvp => kvp.Text);
ddb.GetText = () => lookup[filter.Outcome];
ddb.OnMouseDown = _ =>
{
Func<Pair<WinState, string>, ScrollItemWidget, ScrollItemWidget> setupItem = (option, tpl) =>
Func<(WinState WinState, string Text), ScrollItemWidget, ScrollItemWidget> setupItem = (option, tpl) =>
{
var item = ScrollItemWidget.Setup(
tpl,
() => filter.Outcome == option.First,
() => { filter.Outcome = option.First; ApplyFilter(); });
item.Get<LabelWidget>("LABEL").GetText = () => option.Second;
() => filter.Outcome == option.WinState,
() => { filter.Outcome = option.WinState; ApplyFilter(); });
item.Get<LabelWidget>("LABEL").GetText = () => option.Text;
return item;
};

View File

@@ -14,7 +14,6 @@ using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq;
using OpenRA.Primitives;
using OpenRA.Widgets;
namespace OpenRA.Mods.Common.Widgets.Logic
@@ -26,22 +25,22 @@ namespace OpenRA.Mods.Common.Widgets.Logic
// Increment the version number when adding new stats
const int SystemInformationVersion = 4;
static Dictionary<string, Pair<string, string>> GetSystemInformation()
static Dictionary<string, (string Label, string Value)> GetSystemInformation()
{
var lang = CultureInfo.InstalledUICulture.TwoLetterISOLanguageName;
return new Dictionary<string, Pair<string, string>>()
return new Dictionary<string, (string, string)>()
{
{ "id", Pair.New("Anonymous ID", Game.Settings.Debug.UUID) },
{ "platform", Pair.New("OS Type", Platform.CurrentPlatform.ToString()) },
{ "os", Pair.New("OS Version", Environment.OSVersion.ToString()) },
{ "x64", Pair.New("OS is 64 bit", Environment.Is64BitOperatingSystem.ToString()) },
{ "x64process", Pair.New("Process is 64 bit", Environment.Is64BitProcess.ToString()) },
{ "runtime", Pair.New(".NET Runtime", Platform.RuntimeVersion) },
{ "gl", Pair.New("OpenGL Version", Game.Renderer.GLVersion) },
{ "windowsize", Pair.New("Window Size", "{0}x{1}".F(Game.Renderer.NativeResolution.Width, Game.Renderer.NativeResolution.Height)) },
{ "windowscale", Pair.New("Window Scale", Game.Renderer.NativeWindowScale.ToString("F2", CultureInfo.InvariantCulture)) },
{ "uiscale", Pair.New("UI Scale", Game.Settings.Graphics.UIScale.ToString("F2", CultureInfo.InvariantCulture)) },
{ "lang", Pair.New("System Language", lang) }
{ "id", ("Anonymous ID", Game.Settings.Debug.UUID) },
{ "platform", ("OS Type", Platform.CurrentPlatform.ToString()) },
{ "os", ("OS Version", Environment.OSVersion.ToString()) },
{ "x64", ("OS is 64 bit", Environment.Is64BitOperatingSystem.ToString()) },
{ "x64process", ("Process is 64 bit", Environment.Is64BitProcess.ToString()) },
{ "runtime", (".NET Runtime", Platform.RuntimeVersion) },
{ "gl", ("OpenGL Version", Game.Renderer.GLVersion) },
{ "windowsize", ("Window Size", "{0}x{1}".F(Game.Renderer.NativeResolution.Width, Game.Renderer.NativeResolution.Height)) },
{ "windowscale", ("Window Scale", Game.Renderer.NativeWindowScale.ToString("F2", CultureInfo.InvariantCulture)) },
{ "uiscale", ("UI Scale", Game.Settings.Graphics.UIScale.ToString("F2", CultureInfo.InvariantCulture)) },
{ "lang", ("System Language", lang) }
};
}
@@ -57,7 +56,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
return "&sysinfoversion={0}&".F(SystemInformationVersion)
+ GetSystemInformation()
.Select(kv => kv.Key + "=" + Uri.EscapeUriString(kv.Value.Second))
.Select(kv => kv.Key + "=" + Uri.EscapeUriString(kv.Value.Value))
.JoinWith("&");
}
@@ -75,7 +74,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
foreach (var info in GetSystemInformation().Values)
{
var label = template.Clone() as LabelWidget;
var text = info.First + ": " + info.Second;
var text = info.Label + ": " + info.Value;
label.GetText = () => text;
sysInfoData.AddChild(label);
}

View File

@@ -206,8 +206,8 @@ namespace OpenRA.Mods.Common.Widgets
void UpdateTerrainColor(MPos uv)
{
var colorPair = playerRadarTerrain != null && playerRadarTerrain.IsInitialized ? playerRadarTerrain[uv] : PlayerRadarTerrain.GetColor(world.Map, uv);
var leftColor = colorPair.First;
var rightColor = colorPair.Second;
var leftColor = colorPair.Left;
var rightColor = colorPair.Right;
var stride = radarSheet.Size.Width;
@@ -386,7 +386,7 @@ namespace OpenRA.Mods.Common.Widgets
var stride = radarSheet.Size.Width;
Array.Clear(radarData, 4 * actorSprite.Bounds.Top * stride, 4 * actorSprite.Bounds.Height * stride);
var cells = new List<Pair<CPos, Color>>();
var cells = new List<(CPos Cell, Color Color)>();
unsafe
{
@@ -403,11 +403,11 @@ namespace OpenRA.Mods.Common.Widgets
t.Trait.PopulateRadarSignatureCells(t.Actor, cells);
foreach (var cell in cells)
{
if (!world.Map.Contains(cell.First))
if (!world.Map.Contains(cell.Cell))
continue;
var uv = cell.First.ToMPos(world.Map.Grid.Type);
var color = cell.Second.ToArgb();
var uv = cell.Cell.ToMPos(world.Map.Grid.Type);
var color = cell.Color.ToArgb();
if (isRectangularIsometric)
{
// Odd rows are shifted right by 1px

View File

@@ -27,7 +27,7 @@ namespace OpenRA.Mods.Common.Widgets
readonly int timestep;
readonly IEnumerable<SupportPowerInstance> powers;
readonly Color bgDark, bgLight;
Pair<string, Color>[] texts;
(string Text, Color Color)[] texts;
[ObjectCreator.UseCtor]
public SupportPowerTimerWidget(World world)
@@ -67,7 +67,7 @@ namespace OpenRA.Mods.Common.Widgets
var color = !p.Ready || Game.LocalTick % 50 < 25 ? playerColor : Color.White;
return Pair.New(text, color);
return (text, color);
}).ToArray();
}
@@ -80,8 +80,8 @@ namespace OpenRA.Mods.Common.Widgets
foreach (var t in texts)
{
var font = Game.Renderer.Fonts[Font];
font.DrawTextWithShadow(t.First, new float2(Bounds.Location) + new float2(0, y), t.Second, bgDark, bgLight, 1);
y += (font.Measure(t.First).Y + 5) * (int)Order;
font.DrawTextWithShadow(t.Text, new float2(Bounds.Location) + new float2(0, y), t.Color, bgDark, bgLight, 1);
y += (font.Measure(t.Text).Y + 5) * (int)Order;
}
}

View File

@@ -337,19 +337,19 @@ namespace OpenRA.Mods.Common.Widgets
{
var client = p.World.LobbyInfo.ClientWithIndex(p.ClientIndex);
var nameFont = Game.Renderer.Fonts[label.Font];
var name = new CachedTransform<Tuple<string, WinState, Session.ClientState>, string>(c =>
var name = new CachedTransform<(string Name, WinState WinState, Session.ClientState ClientState), string>(c =>
{
var suffix = c.Item2 == WinState.Undefined ? "" : " (" + c.Item2 + ")";
if (c.Item3 == Session.ClientState.Disconnected)
var suffix = c.WinState == WinState.Undefined ? "" : " (" + c.Item2 + ")";
if (c.ClientState == Session.ClientState.Disconnected)
suffix = " (Gone)";
return TruncateText(c.Item1, label.Bounds.Width - nameFont.Measure(suffix).X, nameFont) + suffix;
return TruncateText(c.Name, label.Bounds.Width - nameFont.Measure(suffix).X, nameFont) + suffix;
});
label.GetText = () =>
{
var clientState = client != null ? client.State : Session.ClientState.Ready;
return name.Update(Tuple.Create(p.PlayerName, p.WinState, clientState));
return name.Update((p.PlayerName, p.WinState, clientState));
};
}
}

View File

@@ -21,8 +21,8 @@ namespace OpenRA.Mods.D2k.Lint
{
foreach (var actorData in D2kMapImporter.ActorDataByActorCode.Values)
{
if (!rules.Actors.ContainsKey(actorData.First))
emitError("Undefined actor {0} in map import code.".F(actorData.First));
if (!rules.Actors.ContainsKey(actorData.Actor))
emitError("Undefined actor {0} in map import code.".F(actorData.Actor));
}
}
}

View File

@@ -3,7 +3,7 @@
<TargetFramework>net472</TargetFramework>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Optimize>true</Optimize>
<LangVersion>5</LangVersion>
<LangVersion>7.3</LangVersion>
<DebugSymbols>true</DebugSymbols>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<OutputPath>../mods/d2k</OutputPath>

View File

@@ -21,236 +21,236 @@ namespace OpenRA.Mods.D2k.UtilityCommands
{
const int MapCordonWidth = 2;
public static Dictionary<int, Pair<string, string>> ActorDataByActorCode = new Dictionary<int, Pair<string, string>>
public static Dictionary<int, (string Actor, string Owner)> ActorDataByActorCode = new Dictionary<int, (string, string)>
{
{ 20, Pair.New("wormspawner", "Creeps") },
{ 23, Pair.New("mpspawn", "Neutral") },
{ 41, Pair.New("spicebloom.spawnpoint", "Neutral") },
{ 42, Pair.New("spicebloom.spawnpoint", "Neutral") },
{ 43, Pair.New("spicebloom.spawnpoint", "Neutral") },
{ 44, Pair.New("spicebloom.spawnpoint", "Neutral") },
{ 45, Pair.New("spicebloom.spawnpoint", "Neutral") },
{ 20, ("wormspawner", "Creeps") },
{ 23, ("mpspawn", "Neutral") },
{ 41, ("spicebloom.spawnpoint", "Neutral") },
{ 42, ("spicebloom.spawnpoint", "Neutral") },
{ 43, ("spicebloom.spawnpoint", "Neutral") },
{ 44, ("spicebloom.spawnpoint", "Neutral") },
{ 45, ("spicebloom.spawnpoint", "Neutral") },
// Atreides:
{ 4, Pair.New("wall", "Atreides") },
{ 5, Pair.New("wind_trap", "Atreides") },
{ 8, Pair.New("construction_yard", "Atreides") },
{ 11, Pair.New("barracks", "Atreides") },
{ 14, Pair.New("refinery", "Atreides") },
{ 17, Pair.New("outpost", "Atreides") },
{ 63, Pair.New("light_factory", "Atreides") },
{ 69, Pair.New("silo", "Atreides") },
{ 72, Pair.New("heavy_factory", "Atreides") },
{ 75, Pair.New("repair_pad", "Atreides") },
{ 78, Pair.New("medium_gun_turret", "Atreides") },
{ 120, Pair.New("high_tech_factory", "Atreides") },
{ 123, Pair.New("large_gun_turret", "Atreides") },
{ 126, Pair.New("research_centre", "Atreides") },
{ 129, Pair.New("starport", "Atreides") },
{ 132, Pair.New("palace", "Atreides") },
{ 180, Pair.New("light_inf", "Atreides") },
{ 181, Pair.New("trooper", "Atreides") },
{ 182, Pair.New("fremen", "Atreides") },
{ 183, Pair.New("sardaukar", "Atreides") },
{ 184, Pair.New("engineer", "Atreides") },
{ 185, Pair.New("harvester", "Atreides") },
{ 186, Pair.New("mcv", "Atreides") },
{ 187, Pair.New("trike", "Atreides") },
{ 188, Pair.New("quad", "Atreides") },
{ 189, Pair.New("combat_tank_a", "Atreides") },
{ 190, Pair.New("missile_tank", "Atreides") },
{ 191, Pair.New("siege_tank", "Atreides") },
{ 192, Pair.New("carryall", "Atreides") },
{ 194, Pair.New("sonic_tank", "Atreides") },
{ 4, ("wall", "Atreides") },
{ 5, ("wind_trap", "Atreides") },
{ 8, ("construction_yard", "Atreides") },
{ 11, ("barracks", "Atreides") },
{ 14, ("refinery", "Atreides") },
{ 17, ("outpost", "Atreides") },
{ 63, ("light_factory", "Atreides") },
{ 69, ("silo", "Atreides") },
{ 72, ("heavy_factory", "Atreides") },
{ 75, ("repair_pad", "Atreides") },
{ 78, ("medium_gun_turret", "Atreides") },
{ 120, ("high_tech_factory", "Atreides") },
{ 123, ("large_gun_turret", "Atreides") },
{ 126, ("research_centre", "Atreides") },
{ 129, ("starport", "Atreides") },
{ 132, ("palace", "Atreides") },
{ 180, ("light_inf", "Atreides") },
{ 181, ("trooper", "Atreides") },
{ 182, ("fremen", "Atreides") },
{ 183, ("sardaukar", "Atreides") },
{ 184, ("engineer", "Atreides") },
{ 185, ("harvester", "Atreides") },
{ 186, ("mcv", "Atreides") },
{ 187, ("trike", "Atreides") },
{ 188, ("quad", "Atreides") },
{ 189, ("combat_tank_a", "Atreides") },
{ 190, ("missile_tank", "Atreides") },
{ 191, ("siege_tank", "Atreides") },
{ 192, ("carryall", "Atreides") },
{ 194, ("sonic_tank", "Atreides") },
// Harkonnen:
{ 204, Pair.New("wall", "Harkonnen") },
{ 205, Pair.New("wind_trap", "Harkonnen") },
{ 208, Pair.New("construction_yard", "Harkonnen") },
{ 211, Pair.New("barracks", "Harkonnen") },
{ 214, Pair.New("refinery", "Harkonnen") },
{ 217, Pair.New("outpost", "Harkonnen") },
{ 263, Pair.New("light_factory", "Harkonnen") },
{ 269, Pair.New("silo", "Harkonnen") },
{ 272, Pair.New("heavy_factory", "Harkonnen") },
{ 275, Pair.New("repair_pad", "Harkonnen") },
{ 278, Pair.New("medium_gun_turret", "Harkonnen") },
{ 320, Pair.New("high_tech_factory", "Harkonnen") },
{ 323, Pair.New("large_gun_turret", "Harkonnen") },
{ 326, Pair.New("research_centre", "Harkonnen") },
{ 329, Pair.New("starport", "Harkonnen") },
{ 332, Pair.New("palace", "Harkonnen") },
{ 360, Pair.New("light_inf", "Harkonnen") },
{ 361, Pair.New("trooper", "Harkonnen") },
{ 362, Pair.New("fremen", "Harkonnen") },
{ 363, Pair.New("mpsardaukar", "Harkonnen") },
{ 364, Pair.New("engineer", "Harkonnen") },
{ 365, Pair.New("harvester", "Harkonnen") },
{ 366, Pair.New("mcv", "Harkonnen") },
{ 367, Pair.New("trike", "Harkonnen") },
{ 368, Pair.New("quad", "Harkonnen") },
{ 369, Pair.New("combat_tank_h", "Harkonnen") },
{ 370, Pair.New("missile_tank", "Harkonnen") },
{ 371, Pair.New("siege_tank", "Harkonnen") },
{ 372, Pair.New("carryall", "Harkonnen") },
{ 374, Pair.New("devastator", "Harkonnen") },
{ 204, ("wall", "Harkonnen") },
{ 205, ("wind_trap", "Harkonnen") },
{ 208, ("construction_yard", "Harkonnen") },
{ 211, ("barracks", "Harkonnen") },
{ 214, ("refinery", "Harkonnen") },
{ 217, ("outpost", "Harkonnen") },
{ 263, ("light_factory", "Harkonnen") },
{ 269, ("silo", "Harkonnen") },
{ 272, ("heavy_factory", "Harkonnen") },
{ 275, ("repair_pad", "Harkonnen") },
{ 278, ("medium_gun_turret", "Harkonnen") },
{ 320, ("high_tech_factory", "Harkonnen") },
{ 323, ("large_gun_turret", "Harkonnen") },
{ 326, ("research_centre", "Harkonnen") },
{ 329, ("starport", "Harkonnen") },
{ 332, ("palace", "Harkonnen") },
{ 360, ("light_inf", "Harkonnen") },
{ 361, ("trooper", "Harkonnen") },
{ 362, ("fremen", "Harkonnen") },
{ 363, ("mpsardaukar", "Harkonnen") },
{ 364, ("engineer", "Harkonnen") },
{ 365, ("harvester", "Harkonnen") },
{ 366, ("mcv", "Harkonnen") },
{ 367, ("trike", "Harkonnen") },
{ 368, ("quad", "Harkonnen") },
{ 369, ("combat_tank_h", "Harkonnen") },
{ 370, ("missile_tank", "Harkonnen") },
{ 371, ("siege_tank", "Harkonnen") },
{ 372, ("carryall", "Harkonnen") },
{ 374, ("devastator", "Harkonnen") },
// Ordos:
{ 404, Pair.New("wall", "Ordos") },
{ 405, Pair.New("wind_trap", "Ordos") },
{ 408, Pair.New("construction_yard", "Ordos") },
{ 411, Pair.New("barracks", "Ordos") },
{ 414, Pair.New("refinery", "Ordos") },
{ 417, Pair.New("outpost", "Ordos") },
{ 463, Pair.New("light_factory", "Ordos") },
{ 469, Pair.New("silo", "Ordos") },
{ 472, Pair.New("heavy_factory", "Ordos") },
{ 475, Pair.New("repair_pad", "Ordos") },
{ 478, Pair.New("medium_gun_turret", "Ordos") },
{ 520, Pair.New("high_tech_factory", "Ordos") },
{ 523, Pair.New("large_gun_turret", "Ordos") },
{ 526, Pair.New("research_centre", "Ordos") },
{ 529, Pair.New("starport", "Ordos") },
{ 532, Pair.New("palace", "Ordos") },
{ 560, Pair.New("light_inf", "Ordos") },
{ 561, Pair.New("trooper", "Ordos") },
{ 562, Pair.New("saboteur", "Ordos") },
{ 563, Pair.New("sardaukar", "Ordos") },
{ 564, Pair.New("engineer", "Ordos") },
{ 565, Pair.New("harvester", "Ordos") },
{ 566, Pair.New("mcv", "Ordos") },
{ 567, Pair.New("raider", "Ordos") },
{ 568, Pair.New("quad", "Ordos") },
{ 569, Pair.New("combat_tank_o", "Ordos") },
{ 570, Pair.New("missile_tank", "Ordos") },
{ 571, Pair.New("siege_tank", "Ordos") },
{ 572, Pair.New("carryall", "Ordos") },
{ 574, Pair.New("deviator", "Ordos") },
{ 404, ("wall", "Ordos") },
{ 405, ("wind_trap", "Ordos") },
{ 408, ("construction_yard", "Ordos") },
{ 411, ("barracks", "Ordos") },
{ 414, ("refinery", "Ordos") },
{ 417, ("outpost", "Ordos") },
{ 463, ("light_factory", "Ordos") },
{ 469, ("silo", "Ordos") },
{ 472, ("heavy_factory", "Ordos") },
{ 475, ("repair_pad", "Ordos") },
{ 478, ("medium_gun_turret", "Ordos") },
{ 520, ("high_tech_factory", "Ordos") },
{ 523, ("large_gun_turret", "Ordos") },
{ 526, ("research_centre", "Ordos") },
{ 529, ("starport", "Ordos") },
{ 532, ("palace", "Ordos") },
{ 560, ("light_inf", "Ordos") },
{ 561, ("trooper", "Ordos") },
{ 562, ("saboteur", "Ordos") },
{ 563, ("sardaukar", "Ordos") },
{ 564, ("engineer", "Ordos") },
{ 565, ("harvester", "Ordos") },
{ 566, ("mcv", "Ordos") },
{ 567, ("raider", "Ordos") },
{ 568, ("quad", "Ordos") },
{ 569, ("combat_tank_o", "Ordos") },
{ 570, ("missile_tank", "Ordos") },
{ 571, ("siege_tank", "Ordos") },
{ 572, ("carryall", "Ordos") },
{ 574, ("deviator", "Ordos") },
// Corrino:
{ 580, Pair.New("wall", "Corrino") },
{ 581, Pair.New("wind_trap", "Corrino") },
{ 582, Pair.New("construction_yard", "Corrino") },
{ 583, Pair.New("barracks", "Corrino") },
{ 584, Pair.New("refinery", "Corrino") },
{ 585, Pair.New("outpost", "Corrino") },
{ 587, Pair.New("light_factory", "Corrino") },
{ 588, Pair.New("palace", "Corrino") },
{ 589, Pair.New("silo", "Corrino") },
{ 590, Pair.New("heavy_factory", "Corrino") },
{ 591, Pair.New("repair_pad", "Corrino") },
{ 592, Pair.New("medium_gun_turret", "Corrino") },
{ 593, Pair.New("high_tech_factory", "Corrino") },
{ 594, Pair.New("large_gun_turret", "Corrino") },
{ 595, Pair.New("research_centre", "Corrino") },
{ 596, Pair.New("starport", "Corrino") },
{ 597, Pair.New("sietch", "Corrino") },
{ 598, Pair.New("light_inf", "Corrino") },
{ 599, Pair.New("trooper", "Corrino") },
{ 600, Pair.New("sardaukar", "Corrino") },
{ 601, Pair.New("fremen", "Corrino") },
{ 602, Pair.New("engineer", "Corrino") },
{ 603, Pair.New("harvester", "Corrino") },
{ 604, Pair.New("mcv", "Corrino") },
{ 605, Pair.New("trike", "Corrino") },
{ 606, Pair.New("quad", "Corrino") },
{ 607, Pair.New("combat_tank_h", "Corrino") },
{ 608, Pair.New("missile_tank", "Corrino") },
{ 609, Pair.New("siege_tank", "Corrino") },
{ 610, Pair.New("carryall", "Corrino") },
{ 580, ("wall", "Corrino") },
{ 581, ("wind_trap", "Corrino") },
{ 582, ("construction_yard", "Corrino") },
{ 583, ("barracks", "Corrino") },
{ 584, ("refinery", "Corrino") },
{ 585, ("outpost", "Corrino") },
{ 587, ("light_factory", "Corrino") },
{ 588, ("palace", "Corrino") },
{ 589, ("silo", "Corrino") },
{ 590, ("heavy_factory", "Corrino") },
{ 591, ("repair_pad", "Corrino") },
{ 592, ("medium_gun_turret", "Corrino") },
{ 593, ("high_tech_factory", "Corrino") },
{ 594, ("large_gun_turret", "Corrino") },
{ 595, ("research_centre", "Corrino") },
{ 596, ("starport", "Corrino") },
{ 597, ("sietch", "Corrino") },
{ 598, ("light_inf", "Corrino") },
{ 599, ("trooper", "Corrino") },
{ 600, ("sardaukar", "Corrino") },
{ 601, ("fremen", "Corrino") },
{ 602, ("engineer", "Corrino") },
{ 603, ("harvester", "Corrino") },
{ 604, ("mcv", "Corrino") },
{ 605, ("trike", "Corrino") },
{ 606, ("quad", "Corrino") },
{ 607, ("combat_tank_h", "Corrino") },
{ 608, ("missile_tank", "Corrino") },
{ 609, ("siege_tank", "Corrino") },
{ 610, ("carryall", "Corrino") },
// Fremen:
{ 620, Pair.New("wall", "Fremen") },
{ 621, Pair.New("wind_trap", "Fremen") },
{ 622, Pair.New("construction_yard", "Fremen") },
{ 623, Pair.New("barracks", "Fremen") },
{ 624, Pair.New("refinery", "Fremen") },
{ 625, Pair.New("outpost", "Fremen") },
{ 627, Pair.New("light_factory", "Fremen") },
{ 628, Pair.New("palace", "Fremen") },
{ 629, Pair.New("silo", "Fremen") },
{ 630, Pair.New("heavy_factory", "Fremen") },
{ 631, Pair.New("repair_pad", "Fremen") },
{ 632, Pair.New("medium_gun_turret", "Fremen") },
{ 633, Pair.New("high_tech_factory", "Fremen") },
{ 634, Pair.New("large_gun_turret", "Fremen") },
{ 635, Pair.New("research_centre", "Fremen") },
{ 636, Pair.New("starport", "Fremen") },
{ 637, Pair.New("sietch", "Fremen") },
{ 638, Pair.New("light_inf", "Fremen") },
{ 639, Pair.New("trooper", "Fremen") },
{ 640, Pair.New("fremen", "Fremen") },
{ 641, Pair.New("nsfremen", "Fremen") },
{ 642, Pair.New("engineer", "Fremen") },
{ 643, Pair.New("harvester", "Fremen") },
{ 644, Pair.New("mcv", "Fremen") },
{ 645, Pair.New("trike", "Fremen") },
{ 646, Pair.New("quad", "Fremen") },
{ 647, Pair.New("combat_tank_a", "Fremen") },
{ 648, Pair.New("missile_tank", "Fremen") },
{ 649, Pair.New("siege_tank", "Fremen") },
{ 650, Pair.New("carryall", "Fremen") },
{ 652, Pair.New("sonic_tank", "Fremen") },
{ 620, ("wall", "Fremen") },
{ 621, ("wind_trap", "Fremen") },
{ 622, ("construction_yard", "Fremen") },
{ 623, ("barracks", "Fremen") },
{ 624, ("refinery", "Fremen") },
{ 625, ("outpost", "Fremen") },
{ 627, ("light_factory", "Fremen") },
{ 628, ("palace", "Fremen") },
{ 629, ("silo", "Fremen") },
{ 630, ("heavy_factory", "Fremen") },
{ 631, ("repair_pad", "Fremen") },
{ 632, ("medium_gun_turret", "Fremen") },
{ 633, ("high_tech_factory", "Fremen") },
{ 634, ("large_gun_turret", "Fremen") },
{ 635, ("research_centre", "Fremen") },
{ 636, ("starport", "Fremen") },
{ 637, ("sietch", "Fremen") },
{ 638, ("light_inf", "Fremen") },
{ 639, ("trooper", "Fremen") },
{ 640, ("fremen", "Fremen") },
{ 641, ("nsfremen", "Fremen") },
{ 642, ("engineer", "Fremen") },
{ 643, ("harvester", "Fremen") },
{ 644, ("mcv", "Fremen") },
{ 645, ("trike", "Fremen") },
{ 646, ("quad", "Fremen") },
{ 647, ("combat_tank_a", "Fremen") },
{ 648, ("missile_tank", "Fremen") },
{ 649, ("siege_tank", "Fremen") },
{ 650, ("carryall", "Fremen") },
{ 652, ("sonic_tank", "Fremen") },
// Smugglers:
{ 660, Pair.New("wall", "Smugglers") },
{ 661, Pair.New("wind_trap", "Smugglers") },
{ 662, Pair.New("construction_yard", "Smugglers") },
{ 663, Pair.New("barracks", "Smugglers") },
{ 664, Pair.New("refinery", "Smugglers") },
{ 666, Pair.New("outpost", "Smugglers") },
{ 667, Pair.New("light_factory", "Smugglers") },
{ 668, Pair.New("silo", "Smugglers") },
{ 669, Pair.New("heavy_factory", "Smugglers") },
{ 670, Pair.New("repair_pad", "Smugglers") },
{ 671, Pair.New("medium_gun_turret", "Smugglers") },
{ 672, Pair.New("high_tech_factory", "Smugglers") },
{ 673, Pair.New("large_gun_turret", "Smugglers") },
{ 674, Pair.New("research_centre", "Smugglers") },
{ 675, Pair.New("starport", "Smugglers") },
{ 676, Pair.New("palace", "Smugglers") },
{ 677, Pair.New("light_inf", "Smugglers") },
{ 678, Pair.New("trooper", "Smugglers") },
{ 679, Pair.New("saboteur", "Smugglers") },
{ 680, Pair.New("engineer", "Smugglers") },
{ 681, Pair.New("harvester", "Smugglers") },
{ 682, Pair.New("mcv", "Smugglers") },
{ 683, Pair.New("trike", "Smugglers") },
{ 684, Pair.New("quad", "Smugglers") },
{ 685, Pair.New("combat_tank_o", "Smugglers") },
{ 686, Pair.New("missile_tank", "Smugglers") },
{ 687, Pair.New("siege_tank", "Smugglers") },
{ 688, Pair.New("carryall", "Smugglers") },
{ 660, ("wall", "Smugglers") },
{ 661, ("wind_trap", "Smugglers") },
{ 662, ("construction_yard", "Smugglers") },
{ 663, ("barracks", "Smugglers") },
{ 664, ("refinery", "Smugglers") },
{ 666, ("outpost", "Smugglers") },
{ 667, ("light_factory", "Smugglers") },
{ 668, ("silo", "Smugglers") },
{ 669, ("heavy_factory", "Smugglers") },
{ 670, ("repair_pad", "Smugglers") },
{ 671, ("medium_gun_turret", "Smugglers") },
{ 672, ("high_tech_factory", "Smugglers") },
{ 673, ("large_gun_turret", "Smugglers") },
{ 674, ("research_centre", "Smugglers") },
{ 675, ("starport", "Smugglers") },
{ 676, ("palace", "Smugglers") },
{ 677, ("light_inf", "Smugglers") },
{ 678, ("trooper", "Smugglers") },
{ 679, ("saboteur", "Smugglers") },
{ 680, ("engineer", "Smugglers") },
{ 681, ("harvester", "Smugglers") },
{ 682, ("mcv", "Smugglers") },
{ 683, ("trike", "Smugglers") },
{ 684, ("quad", "Smugglers") },
{ 685, ("combat_tank_o", "Smugglers") },
{ 686, ("missile_tank", "Smugglers") },
{ 687, ("siege_tank", "Smugglers") },
{ 688, ("carryall", "Smugglers") },
// Mercenaries:
{ 700, Pair.New("wall", "Mercenaries") },
{ 701, Pair.New("wind_trap", "Mercenaries") },
{ 702, Pair.New("construction_yard", "Mercenaries") },
{ 703, Pair.New("barracks", "Mercenaries") },
{ 704, Pair.New("refinery", "Mercenaries") },
{ 705, Pair.New("outpost", "Mercenaries") },
{ 707, Pair.New("light_factory", "Mercenaries") },
{ 708, Pair.New("silo", "Mercenaries") },
{ 709, Pair.New("heavy_factory", "Mercenaries") },
{ 710, Pair.New("repair_pad", "Mercenaries") },
{ 711, Pair.New("medium_gun_turret", "Mercenaries") },
{ 712, Pair.New("high_tech_factory", "Mercenaries") },
{ 713, Pair.New("large_gun_turret", "Mercenaries") },
{ 714, Pair.New("research_centre", "Mercenaries") },
{ 715, Pair.New("starport", "Mercenaries") },
{ 716, Pair.New("palace", "Mercenaries") },
{ 717, Pair.New("light_inf", "Mercenaries") },
{ 718, Pair.New("trooper", "Mercenaries") },
{ 719, Pair.New("saboteur", "Mercenaries") },
{ 720, Pair.New("harvester", "Mercenaries") },
{ 721, Pair.New("harvester", "Mercenaries") },
{ 722, Pair.New("mcv", "Mercenaries") },
{ 723, Pair.New("trike", "Mercenaries") },
{ 724, Pair.New("quad", "Mercenaries") },
{ 725, Pair.New("combat_tank_o", "Mercenaries") },
{ 726, Pair.New("missile_tank", "Mercenaries") },
{ 727, Pair.New("siege_tank", "Mercenaries") },
{ 728, Pair.New("carryall", "Mercenaries") },
{ 700, ("wall", "Mercenaries") },
{ 701, ("wind_trap", "Mercenaries") },
{ 702, ("construction_yard", "Mercenaries") },
{ 703, ("barracks", "Mercenaries") },
{ 704, ("refinery", "Mercenaries") },
{ 705, ("outpost", "Mercenaries") },
{ 707, ("light_factory", "Mercenaries") },
{ 708, ("silo", "Mercenaries") },
{ 709, ("heavy_factory", "Mercenaries") },
{ 710, ("repair_pad", "Mercenaries") },
{ 711, ("medium_gun_turret", "Mercenaries") },
{ 712, ("high_tech_factory", "Mercenaries") },
{ 713, ("large_gun_turret", "Mercenaries") },
{ 714, ("research_centre", "Mercenaries") },
{ 715, ("starport", "Mercenaries") },
{ 716, ("palace", "Mercenaries") },
{ 717, ("light_inf", "Mercenaries") },
{ 718, ("trooper", "Mercenaries") },
{ 719, ("saboteur", "Mercenaries") },
{ 720, ("harvester", "Mercenaries") },
{ 721, ("harvester", "Mercenaries") },
{ 722, ("mcv", "Mercenaries") },
{ 723, ("trike", "Mercenaries") },
{ 724, ("quad", "Mercenaries") },
{ 725, ("combat_tank_o", "Mercenaries") },
{ 726, ("missile_tank", "Mercenaries") },
{ 727, ("siege_tank", "Mercenaries") },
{ 728, ("carryall", "Mercenaries") },
};
readonly Ruleset rules;
@@ -350,18 +350,18 @@ namespace OpenRA.Mods.D2k.UtilityCommands
if (ActorDataByActorCode.ContainsKey(tileSpecialInfo))
{
var kvp = ActorDataByActorCode[tileSpecialInfo];
if (!rules.Actors.ContainsKey(kvp.First.ToLowerInvariant()))
throw new InvalidOperationException("Actor with name {0} could not be found in the rules YAML file!".F(kvp.First));
if (!rules.Actors.ContainsKey(kvp.Actor.ToLowerInvariant()))
throw new InvalidOperationException("Actor with name {0} could not be found in the rules YAML file!".F(kvp.Actor));
var a = new ActorReference(kvp.First)
var a = new ActorReference(kvp.Actor)
{
new LocationInit(locationOnMap),
new OwnerInit(kvp.Second)
new OwnerInit(kvp.Owner)
};
map.ActorDefinitions.Add(new MiniYamlNode("Actor" + map.ActorDefinitions.Count, a.Save()));
if (kvp.First == "mpspawn")
if (kvp.Actor == "mpspawn")
playerCount++;
}
}

View File

@@ -16,8 +16,8 @@ namespace OpenRA.Platforms.Default
{
static class MultiTapDetection
{
static Cache<Pair<Keycode, Modifiers>, TapHistory> keyHistoryCache =
new Cache<Pair<Keycode, Modifiers>, TapHistory>(_ => new TapHistory(DateTime.Now - TimeSpan.FromSeconds(1)));
static Cache<(Keycode Key, Modifiers Mods), TapHistory> keyHistoryCache =
new Cache<(Keycode, Modifiers), TapHistory>(_ => new TapHistory(DateTime.Now - TimeSpan.FromSeconds(1)));
static Cache<byte, TapHistory> clickHistoryCache =
new Cache<byte, TapHistory>(_ => new TapHistory(DateTime.Now - TimeSpan.FromSeconds(1)));
@@ -33,35 +33,35 @@ namespace OpenRA.Platforms.Default
public static int DetectFromKeyboard(Keycode key, Modifiers mods)
{
return keyHistoryCache[Pair.New(key, mods)].GetTapCount(int2.Zero);
return keyHistoryCache[(key, mods)].GetTapCount(int2.Zero);
}
public static int InfoFromKeyboard(Keycode key, Modifiers mods)
{
return keyHistoryCache[Pair.New(key, mods)].LastTapCount();
return keyHistoryCache[(key, mods)].LastTapCount();
}
}
class TapHistory
{
public Pair<DateTime, int2> FirstRelease, SecondRelease, ThirdRelease;
public (DateTime Time, int2 Location) FirstRelease, SecondRelease, ThirdRelease;
public TapHistory(DateTime now)
{
FirstRelease = SecondRelease = ThirdRelease = Pair.New(now, int2.Zero);
FirstRelease = SecondRelease = ThirdRelease = (now, int2.Zero);
}
static bool CloseEnough(Pair<DateTime, int2> a, Pair<DateTime, int2> b)
static bool CloseEnough((DateTime Time, int2 Location) a, (DateTime Time, int2 Location) b)
{
return a.First - b.First < TimeSpan.FromMilliseconds(250)
&& (a.Second - b.Second).Length < 4;
return a.Time - b.Time < TimeSpan.FromMilliseconds(250)
&& (a.Location - b.Location).Length < 4;
}
public int GetTapCount(int2 xy)
{
FirstRelease = SecondRelease;
SecondRelease = ThirdRelease;
ThirdRelease = Pair.New(DateTime.Now, xy);
ThirdRelease = (DateTime.Now, xy);
if (!CloseEnough(ThirdRelease, SecondRelease))
return 1;

View File

@@ -3,7 +3,7 @@
<TargetFramework>net472</TargetFramework>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Optimize>true</Optimize>
<LangVersion>5</LangVersion>
<LangVersion>7.3</LangVersion>
<DebugSymbols>true</DebugSymbols>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<OutputPath>..</OutputPath>

View File

@@ -89,7 +89,7 @@ namespace OpenRA.Platforms.Default
getCreateFrameBuffer =
tuple =>
{
var t = (Tuple<Size, Color>)tuple;
var t = (ValueTuple<Size, Color>)tuple;
return new ThreadedFrameBuffer(this,
context.CreateFrameBuffer(t.Item1, (ITextureInternal)CreateTexture(), t.Item2));
};
@@ -98,13 +98,13 @@ namespace OpenRA.Platforms.Default
doDrawPrimitives =
tuple =>
{
var t = (Tuple<PrimitiveType, int, int>)tuple;
var t = (ValueTuple<PrimitiveType, int, int>)tuple;
context.DrawPrimitives(t.Item1, t.Item2, t.Item3);
};
doEnableScissor =
tuple =>
{
var t = (Tuple<int, int, int, int>)tuple;
var t = (ValueTuple<int, int, int, int>)tuple;
context.EnableScissor(t.Item1, t.Item2, t.Item3, t.Item4);
};
doSetBlendMode = mode => { context.SetBlendMode((BlendMode)mode); };
@@ -390,12 +390,12 @@ namespace OpenRA.Platforms.Default
public IFrameBuffer CreateFrameBuffer(Size s)
{
return Send(getCreateFrameBuffer, Tuple.Create(s, Color.FromArgb(0)));
return Send(getCreateFrameBuffer, (s, Color.FromArgb(0)));
}
public IFrameBuffer CreateFrameBuffer(Size s, Color clearColor)
{
return Send(getCreateFrameBuffer, Tuple.Create(s, clearColor));
return Send(getCreateFrameBuffer, (s, clearColor));
}
public IShader CreateShader(string name)
@@ -425,7 +425,7 @@ namespace OpenRA.Platforms.Default
public void DrawPrimitives(PrimitiveType type, int firstVertex, int numVertices)
{
Post(doDrawPrimitives, Tuple.Create(type, firstVertex, numVertices));
Post(doDrawPrimitives, (type, firstVertex, numVertices));
}
public void EnableDepthBuffer()
@@ -435,7 +435,7 @@ namespace OpenRA.Platforms.Default
public void EnableScissor(int left, int top, int width, int height)
{
Post(doEnableScissor, Tuple.Create(left, top, width, height));
Post(doEnableScissor, (left, top, width, height));
}
public void Present()
@@ -522,8 +522,8 @@ namespace OpenRA.Platforms.Default
{
this.device = device;
bind = vertexBuffer.Bind;
setData1 = tuple => { var t = (Tuple<Vertex[], int>)tuple; vertexBuffer.SetData(t.Item1, t.Item2); device.ReturnVertices(t.Item1); };
setData2 = tuple => { var t = (Tuple<IntPtr, int, int>)tuple; vertexBuffer.SetData(t.Item1, t.Item2, t.Item3); return null; };
setData1 = tuple => { var t = (ValueTuple<Vertex[], int>)tuple; vertexBuffer.SetData(t.Item1, t.Item2); device.ReturnVertices(t.Item1); };
setData2 = tuple => { var t = (ValueTuple<IntPtr, int, int>)tuple; vertexBuffer.SetData(t.Item1, t.Item2, t.Item3); return null; };
dispose = vertexBuffer.Dispose;
}
@@ -536,20 +536,20 @@ namespace OpenRA.Platforms.Default
{
var buffer = device.GetVertices(length);
Array.Copy(vertices, buffer, length);
device.Post(setData1, Tuple.Create(buffer, length));
device.Post(setData1, (buffer, length));
}
public void SetData(IntPtr data, int start, int length)
{
// We can't return until we are finished with the data, so we must Send here.
device.Send(setData2, Tuple.Create(data, start, length));
device.Send(setData2, (data, start, length));
}
public void SetData(Vertex[] vertices, int start, int length)
{
var buffer = device.GetVertices(length);
Array.Copy(vertices, start, buffer, 0, length);
device.Post(setData1, Tuple.Create(buffer, length));
device.Post(setData1, (buffer, length));
}
public void Dispose()
@@ -578,10 +578,10 @@ namespace OpenRA.Platforms.Default
getScaleFilter = () => texture.ScaleFilter;
setScaleFilter = value => texture.ScaleFilter = (TextureScaleFilter)value;
getSize = () => texture.Size;
setEmpty = tuple => { var t = (Tuple<int, int>)tuple; texture.SetEmpty(t.Item1, t.Item2); };
setEmpty = tuple => { var t = (ValueTuple<int, int>)tuple; texture.SetEmpty(t.Item1, t.Item2); };
getData = () => texture.GetData();
setData1 = colors => { texture.SetData((uint[,])colors); return null; };
setData2 = tuple => { var t = (Tuple<byte[], int, int>)tuple; texture.SetData(t.Item1, t.Item2, t.Item3); };
setData2 = tuple => { var t = (ValueTuple<byte[], int, int>)tuple; texture.SetData(t.Item1, t.Item2, t.Item3); };
dispose = texture.Dispose;
}
@@ -616,7 +616,7 @@ namespace OpenRA.Platforms.Default
public void SetEmpty(int width, int height)
{
device.Post(setEmpty, Tuple.Create(width, height));
device.Post(setEmpty, (width, height));
}
public byte[] GetData()
@@ -636,7 +636,7 @@ namespace OpenRA.Platforms.Default
// but allows us post a message instead of blocking the message queue by sending it.
var temp = new byte[colors.Length];
Array.Copy(colors, temp, temp.Length);
device.Post(setData2, Tuple.Create(temp, width, height));
device.Post(setData2, (temp, width, height));
}
public void Dispose()
@@ -661,13 +661,13 @@ namespace OpenRA.Platforms.Default
{
this.device = device;
prepareRender = shader.PrepareRender;
setBool = tuple => { var t = (Tuple<string, bool>)tuple; shader.SetBool(t.Item1, t.Item2); };
setMatrix = tuple => { var t = (Tuple<string, float[]>)tuple; shader.SetMatrix(t.Item1, t.Item2); };
setTexture = tuple => { var t = (Tuple<string, ITexture>)tuple; shader.SetTexture(t.Item1, t.Item2); };
setVec1 = tuple => { var t = (Tuple<string, float>)tuple; shader.SetVec(t.Item1, t.Item2); };
setVec2 = tuple => { var t = (Tuple<string, float[], int>)tuple; shader.SetVec(t.Item1, t.Item2, t.Item3); };
setVec3 = tuple => { var t = (Tuple<string, float, float>)tuple; shader.SetVec(t.Item1, t.Item2, t.Item3); };
setVec4 = tuple => { var t = (Tuple<string, float, float, float>)tuple; shader.SetVec(t.Item1, t.Item2, t.Item3, t.Item4); };
setBool = tuple => { var t = (ValueTuple<string, bool>)tuple; shader.SetBool(t.Item1, t.Item2); };
setMatrix = tuple => { var t = (ValueTuple<string, float[]>)tuple; shader.SetMatrix(t.Item1, t.Item2); };
setTexture = tuple => { var t = (ValueTuple<string, ITexture>)tuple; shader.SetTexture(t.Item1, t.Item2); };
setVec1 = tuple => { var t = (ValueTuple<string, float>)tuple; shader.SetVec(t.Item1, t.Item2); };
setVec2 = tuple => { var t = (ValueTuple<string, float[], int>)tuple; shader.SetVec(t.Item1, t.Item2, t.Item3); };
setVec3 = tuple => { var t = (ValueTuple<string, float, float>)tuple; shader.SetVec(t.Item1, t.Item2, t.Item3); };
setVec4 = tuple => { var t = (ValueTuple<string, float, float, float>)tuple; shader.SetVec(t.Item1, t.Item2, t.Item3, t.Item4); };
}
public void PrepareRender()
@@ -677,37 +677,37 @@ namespace OpenRA.Platforms.Default
public void SetBool(string name, bool value)
{
device.Post(setBool, Tuple.Create(name, value));
device.Post(setBool, (name, value));
}
public void SetMatrix(string param, float[] mtx)
{
device.Post(setMatrix, Tuple.Create(param, mtx));
device.Post(setMatrix, (param, mtx));
}
public void SetTexture(string param, ITexture texture)
{
device.Post(setTexture, Tuple.Create(param, texture));
device.Post(setTexture, (param, texture));
}
public void SetVec(string name, float x)
{
device.Post(setVec1, Tuple.Create(name, x));
device.Post(setVec1, (name, x));
}
public void SetVec(string name, float[] vec, int length)
{
device.Post(setVec2, Tuple.Create(name, vec, length));
device.Post(setVec2, (name, vec, length));
}
public void SetVec(string name, float x, float y)
{
device.Post(setVec3, Tuple.Create(name, x, y));
device.Post(setVec3, (name, x, y));
}
public void SetVec(string name, float x, float y, float z)
{
device.Post(setVec4, Tuple.Create(name, x, y, z));
device.Post(setVec4, (name, x, y, z));
}
}
}

View File

@@ -7,7 +7,7 @@
<UseVSHostingProcess>false</UseVSHostingProcess>
<OutputPath>..</OutputPath>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<LangVersion>5</LangVersion>
<LangVersion>7.3</LangVersion>
<DebugSymbols>true</DebugSymbols>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<PlatformTarget>AnyCPU</PlatformTarget>

View File

@@ -2,7 +2,7 @@
<PropertyGroup>
<TargetFramework>net472</TargetFramework>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<LangVersion>5</LangVersion>
<LangVersion>7.3</LangVersion>
<DebugSymbols>true</DebugSymbols>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<OutputPath>..</OutputPath>

View File

@@ -7,7 +7,7 @@
<UseVSHostingProcess>false</UseVSHostingProcess>
<OutputPath>..</OutputPath>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<LangVersion>5</LangVersion>
<LangVersion>7.3</LangVersion>
<DebugSymbols>true</DebugSymbols>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<PlatformTarget>AnyCPU</PlatformTarget>