diff --git a/OpenRA.Game/Graphics/ChromeProvider.cs b/OpenRA.Game/Graphics/ChromeProvider.cs index afebe726daee..aceb826bae5c 100644 --- a/OpenRA.Game/Graphics/ChromeProvider.cs +++ b/OpenRA.Game/Graphics/ChromeProvider.cs @@ -54,10 +54,10 @@ public class Collection public static IReadOnlyDictionary Collections { get; private set; } static Dictionary collections; - static Dictionary> cachedSheets; + static Dictionary cachedSheets; static Dictionary> cachedSprites; static Dictionary cachedPanelSprites; - static Dictionary> cachedCollectionSheets; + static Dictionary cachedCollectionSheets; static IReadOnlyFileSystem fileSystem; static float dpiScale = 1; @@ -72,10 +72,10 @@ public static void Initialize(ModData modData) fileSystem = modData.DefaultFileSystem; collections = new Dictionary(); - cachedSheets = new Dictionary>(); + cachedSheets = new Dictionary(); cachedSprites = new Dictionary>(); cachedPanelSprites = new Dictionary(); - cachedCollectionSheets = new Dictionary>(); + cachedCollectionSheets = new Dictionary(); Collections = new ReadOnlyDictionary(collections); @@ -91,7 +91,7 @@ public static void Deinitialize() { if (cachedSheets != null) foreach (var sheet in cachedSheets.Values) - sheet.First.Dispose(); + sheet.Sheet.Dispose(); collections = null; cachedSheets = null; @@ -108,12 +108,10 @@ static void LoadCollection(string name, MiniYaml yaml) collections.Add(name, FieldLoader.Load(yaml)); } - static Pair SheetForCollection(Collection c) + static (Sheet Sheet, int Density) SheetForCollection(Collection c) { - Pair 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 @@ static void LoadCollection(string name, MiniYaml yaml) sheet.GetTexture().ScaleFilter = TextureScaleFilter.Linear; - sheetDensity = Pair.New(sheet, density); + sheetDensity = (sheet, density); cachedSheets.Add(image, sheetDensity); } @@ -153,13 +151,10 @@ public static Sprite GetImage(string collectionName, string imageName) return null; // Cached sprite - Dictionary 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 @@ public static Sprite GetImage(string collectionName, string imageName) 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 @@ public static Sprite[] GetPanelImages(string collectionName) 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 @@ public static Sprite[] GetPanelImages(string collectionName) 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 @@ public static Size GetMinimumPanelSize(string collectionName) 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); diff --git a/OpenRA.Game/Graphics/ModelRenderer.cs b/OpenRA.Game/Graphics/ModelRenderer.cs index 184f6e122cf1..5cb806e26223 100644 --- a/OpenRA.Game/Graphics/ModelRenderer.cs +++ b/OpenRA.Game/Graphics/ModelRenderer.cs @@ -48,7 +48,7 @@ public sealed class ModelRenderer : IDisposable readonly Dictionary mappedBuffers = new Dictionary(); readonly Stack> unmappedBuffers = new Stack>(); - readonly List> doRender = new List>(); + readonly List<(Sheet Sheet, Action Func)> doRender = new List<(Sheet, Action)>(); SheetBuilder sheetBuilderForFrame; bool isInFrame; @@ -180,7 +180,7 @@ public void SetViewportParams(Size screen, int2 scroll) var correctionTransform = Util.MatrixMultiply(translateMtx, FlipMtx); var shadowCorrectionTransform = Util.MatrixMultiply(shadowTranslateMtx, ShadowScaleFlipMtx); - doRender.Add(Pair.New(sprite.Sheet, () => + doRender.Add((sprite.Sheet, () => { foreach (var m in models) { @@ -324,16 +324,16 @@ public void EndFrame() 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) diff --git a/OpenRA.Game/Graphics/PlayerColorRemap.cs b/OpenRA.Game/Graphics/PlayerColorRemap.cs index 4a5e934e5eb4..262ca8e7e443 100644 --- a/OpenRA.Game/Graphics/PlayerColorRemap.cs +++ b/OpenRA.Game/Graphics/PlayerColorRemap.cs @@ -47,8 +47,8 @@ public PlayerColorRemap(int[] ramp, Color c, float rampFraction) 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) diff --git a/OpenRA.Game/Graphics/SpriteFont.cs b/OpenRA.Game/Graphics/SpriteFont.cs index f7dd853ffc8f..a05b6b4eeb9f 100644 --- a/OpenRA.Game/Graphics/SpriteFont.cs +++ b/OpenRA.Game/Graphics/SpriteFont.cs @@ -23,8 +23,8 @@ public sealed class SpriteFont : IDisposable readonly SheetBuilder builder; readonly Func lineWidth; readonly IFont font; - readonly Cache, GlyphInfo> glyphs; - readonly Cache, Sprite> contrastGlyphs; + readonly Cache<(char C, Color Color), GlyphInfo> glyphs; + readonly Cache<(char, Color, int), Sprite> contrastGlyphs; readonly Cache dilationElements; float deviceScale; @@ -40,12 +40,12 @@ public SpriteFont(string name, byte[] data, int size, int ascender, float scale, font = Game.Renderer.CreateFont(data); - glyphs = new Cache, GlyphInfo>(CreateGlyph, Pair.EqualityComparer); - contrastGlyphs = new Cache, Sprite>(CreateContrastGlyph); + glyphs = new Cache<(char, Color), GlyphInfo>(CreateGlyph); + contrastGlyphs = new Cache<(char, Color, int), Sprite>(CreateContrastGlyph); dilationElements = new Cache(CreateCircularWeightMap); // PERF: Cache these delegates for Measure calls. - Func characterWidth = character => glyphs[Pair.New(character, Color.White)].Advance; + Func characterWidth = character => glyphs[(character, Color.White)].Advance; lineWidth = line => line.Sum(characterWidth) / deviceScale; if (size <= 24) @@ -65,7 +65,7 @@ void PrecacheColor(Color c, string name) { 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 @@ void DrawTextContrast(string text, float2 location, Color contrastColor, int con 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 @@ public void DrawText(string text, float2 location, Color c) 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 @@ public void DrawText(string text, float2 location, Color c, float angle) 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 @@ public int2 Measure(string text) return new int2((int)Math.Ceiling(lines.Max(lineWidth)), lines.Length * size); } - GlyphInfo CreateGlyph(Pair 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 @@ GlyphInfo CreateGlyph(Pair c) 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 @@ float[] CreateCircularWeightMap(int r) return elem; } - Sprite CreateContrastGlyph(Tuple 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; diff --git a/OpenRA.Game/InstalledMods.cs b/OpenRA.Game/InstalledMods.cs index 7cb537456ad7..5afc90e5d041 100644 --- a/OpenRA.Game/InstalledMods.cs +++ b/OpenRA.Game/InstalledMods.cs @@ -34,9 +34,9 @@ public InstalledMods(IEnumerable searchPaths, IEnumerable explic mods = GetInstalledMods(searchPaths, explicitPaths); } - static IEnumerable> GetCandidateMods(IEnumerable searchPaths) + static IEnumerable<(string Id, string Path)> GetCandidateMods(IEnumerable searchPaths) { - var mods = new List>(); + var mods = new List<(string, string)>(); foreach (var path in searchPaths) { try @@ -47,7 +47,7 @@ public InstalledMods(IEnumerable searchPaths, IEnumerable explic 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 @@ Manifest LoadMod(string id, string path) { var ret = new Dictionary(); 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; diff --git a/OpenRA.Game/Map/Map.cs b/OpenRA.Game/Map/Map.cs index b85bb89c54a9..374df5ef21f0 100644 --- a/OpenRA.Game/Map/Map.cs +++ b/OpenRA.Game/Map/Map.cs @@ -662,7 +662,7 @@ public byte[] SaveBinaryData() return dataStream.ToArray(); } - public Pair GetTerrainColorPair(MPos uv) + public (Color Left, Color Right) GetTerrainColorPair(MPos uv) { Color left, right; var tileset = Rules.TileSet; @@ -687,7 +687,7 @@ public byte[] SaveBinaryData() else left = right = Color.Black; - return Pair.New(left, right); + return (left, right); } public byte[] SavePreview() @@ -695,7 +695,7 @@ public byte[] SavePreview() var tileset = Rules.TileSet; var actorTypes = Rules.Actors.Values.Where(a => a.HasTraitInfo()); var actors = ActorDefinitions.Where(a => actorTypes.Where(ai => ai.Name == a.Value.Value).Any()); - var positions = new List>(); + 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 @@ public byte[] SavePreview() var stride = bitmapWidth * 4; var pxStride = 4; var minimapData = new byte[stride * height]; - Pair terrainColor = default(Pair); + (Color Left, Color Right) terrainColor = default((Color, Color)); for (var y = 0; y < height; y++) { @@ -737,8 +737,8 @@ public byte[] SavePreview() { 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 @@ public byte[] SavePreview() 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 @@ public byte[] SavePreview() 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 @@ public byte[] SavePreview() 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; diff --git a/OpenRA.Game/Map/MapPreview.cs b/OpenRA.Game/Map/MapPreview.cs index eb294d971cc5..3320384eecbd 100644 --- a/OpenRA.Game/Map/MapPreview.cs +++ b/OpenRA.Game/Map/MapPreview.cs @@ -89,7 +89,7 @@ class InnerData public bool DefinesUnsafeCustomRules { get; private set; } public bool RulesLoaded { get; private set; } - public void SetRulesetGenerator(ModData modData, Func> generator) + public void SetRulesetGenerator(ModData modData, Func<(Ruleset Ruleset, bool DefinesUnsafeCustomRules)> generator) { InvalidCustomRules = false; RulesLoaded = false; @@ -106,8 +106,8 @@ public void SetRulesetGenerator(ModData modData, Func> gener try { var ret = generator(); - DefinesUnsafeCustomRules = ret.Second; - return ret.First; + DefinesUnsafeCustomRules = ret.DefinesUnsafeCustomRules; + return ret.Ruleset; } catch (Exception e) { @@ -318,7 +318,7 @@ public void UpdateFromMap(IReadOnlyPackage p, IReadOnlyPackage parent, MapClassi 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 @@ public void UpdateRemoteSearch(MapStatus status, MiniYaml yaml, Action o.Serialize())); localImmediateOrders.Clear(); - var immediatePackets = new List>(); + var immediatePackets = new List<(int ClientId, byte[] Packet)>(); Connection.Receive( (clientId, packet) => @@ -126,16 +126,16 @@ public void TickImmediate() 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) diff --git a/OpenRA.Game/Network/ReplayConnection.cs b/OpenRA.Game/Network/ReplayConnection.cs index 01c702d86d30..a79eaf810322 100644 --- a/OpenRA.Game/Network/ReplayConnection.cs +++ b/OpenRA.Game/Network/ReplayConnection.cs @@ -14,7 +14,6 @@ using System.IO; using System.Net; using OpenRA.FileFormats; -using OpenRA.Primitives; namespace OpenRA.Network { @@ -23,7 +22,7 @@ public sealed class ReplayConnection : IConnection class Chunk { public int Frame; - public Pair[] Packets; + public (int ClientId, byte[] Packet)[] Packets; } Queue chunks = new Queue(); @@ -55,7 +54,7 @@ public ReplayConnection(string replayFilename) // to avoid issues with all immediate orders being resolved on the first tick. using (var rs = File.OpenRead(replayFilename)) { - var packets = new List>(); + var packets = new List<(int ClientId, byte[] Packet)>(); var chunk = new Chunk(); @@ -67,7 +66,7 @@ public ReplayConnection(string replayFilename) 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 @@ public ReplayConnection(string replayFilename) { 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 @@ public void Receive(Action packetFn) 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() { } diff --git a/OpenRA.Game/Network/SyncReport.cs b/OpenRA.Game/Network/SyncReport.cs index 32fbf42a762e..134e8843fa24 100644 --- a/OpenRA.Game/Network/SyncReport.cs +++ b/OpenRA.Game/Network/SyncReport.cs @@ -29,7 +29,7 @@ class SyncReport readonly Report[] syncReports = new Report[NumSyncReports]; int curIndex = 0; - static Pair DumpSyncTrait(ISync sync) + static (string[] Names, Values Values) DumpSyncTrait(ISync sync) { var type = sync.GetType(); TypeInfo typeInfo; @@ -41,7 +41,7 @@ class SyncReport 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 @@ internal void DumpSyncReport(int frame, IEnumerable order 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 @@ internal void DumpSyncReport(int frame, IEnumerable order 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 @@ struct TraitReport public string Owner; public string Trait; public int Hash; - public Pair NamesValues; + public (string[] Names, Values Values) NamesValues; } struct EffectReport { public string Name; public int Hash; - public Pair NamesValues; + public (string[] Names, Values Values) NamesValues; } struct TypeInfo diff --git a/OpenRA.Game/ObjectCreator.cs b/OpenRA.Game/ObjectCreator.cs index 79cd5ecfb435..8ffb0be52910 100644 --- a/OpenRA.Game/ObjectCreator.cs +++ b/OpenRA.Game/ObjectCreator.cs @@ -26,7 +26,7 @@ public sealed class ObjectCreator : IDisposable readonly Cache typeCache; readonly Cache ctorCache; - readonly Pair[] assemblies; + readonly (Assembly Assembly, string Namespace)[] assemblies; public ObjectCreator(Manifest manifest, InstalledMods mods) { @@ -59,7 +59,7 @@ public ObjectCreator(Manifest manifest, InstalledMods mods) } 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 @@ Assembly ResolveAssembly(object sender, ResolveEventArgs e) 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 @@ public T CreateObject(string className, Dictionary args) 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 @@ public IEnumerable GetTypesImplementing() public IEnumerable GetTypes() { - return assemblies.Select(ma => ma.First).Distinct() + return assemblies.Select(ma => ma.Assembly).Distinct() .SelectMany(ma => ma.GetTypes()); } diff --git a/OpenRA.Game/OpenRA.Game.csproj b/OpenRA.Game/OpenRA.Game.csproj index 6008c90bf5e9..c048102b3caa 100644 --- a/OpenRA.Game/OpenRA.Game.csproj +++ b/OpenRA.Game/OpenRA.Game.csproj @@ -5,7 +5,7 @@ true true false - 5 + 7.3 true true false diff --git a/OpenRA.Game/PlayerDatabase.cs b/OpenRA.Game/PlayerDatabase.cs index eddb91d97f6a..ea0c700b1361 100644 --- a/OpenRA.Game/PlayerDatabase.cs +++ b/OpenRA.Game/PlayerDatabase.cs @@ -32,7 +32,7 @@ public class PlayerDatabase : IGlobalModData SheetBuilder sheetBuilder; [FieldLoader.Ignore] - Cache, Sprite> iconCache; + Cache<(PlayerBadge, int), Sprite> iconCache; Sprite LoadSprite(string url, int density) { @@ -83,15 +83,15 @@ public PlayerBadge LoadBadge(MiniYaml yaml) { sheetBuilder = new SheetBuilder(SheetType.BGRA, CreateSheet); - iconCache = new Cache, 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 @@ public Sprite GetIcon(PlayerBadge badge) { var ws = Game.Renderer.WindowScale; var density = ws > 2 ? 3 : ws > 1 ? 2 : 1; - return iconCache[Pair.New(badge, density)]; + return iconCache[(badge, density)]; } } } diff --git a/OpenRA.Game/Primitives/Pair.cs b/OpenRA.Game/Primitives/Pair.cs deleted file mode 100644 index 8216ba7c64ab..000000000000 --- a/OpenRA.Game/Primitives/Pair.cs +++ /dev/null @@ -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 : IEquatable> - { - public T First; - public U Second; - - public Pair(T first, U second) - { - First = first; - Second = second; - } - - internal static IEqualityComparer Tcomparer = EqualityComparer.Default; - internal static IEqualityComparer Ucomparer = EqualityComparer.Default; - - public static bool operator ==(Pair a, Pair b) - { - return Tcomparer.Equals(a.First, b.First) && Ucomparer.Equals(a.Second, b.Second); - } - - public static bool operator !=(Pair a, Pair b) - { - return !(a == b); - } - - public override int GetHashCode() { return First.GetHashCode() ^ Second.GetHashCode(); } - - public bool Equals(Pair other) { return this == other; } - public override bool Equals(object obj) { return obj is Pair && Equals((Pair)obj); } - - public Pair WithFirst(T t) { return new Pair(t, Second); } - public Pair WithSecond(U u) { return new Pair(First, u); } - - public static T AsFirst(Pair p) { return p.First; } - public static U AsSecond(Pair p) { return p.Second; } - - public override string ToString() - { - return "({0},{1})".F(First, Second); - } - - class PairEqualityComparer : IEqualityComparer> - { - public bool Equals(Pair x, Pair y) { return x == y; } - public int GetHashCode(Pair obj) { return obj.GetHashCode(); } - } - - public static IEqualityComparer> EqualityComparer { get { return new PairEqualityComparer(); } } - } - - public static class Pair - { - public static Pair New(T t, U u) { return new Pair(t, u); } - } -} diff --git a/OpenRA.Game/Traits/TraitsInterfaces.cs b/OpenRA.Game/Traits/TraitsInterfaces.cs index 1c11fba579cb..4af755bfabe1 100644 --- a/OpenRA.Game/Traits/TraitsInterfaces.cs +++ b/OpenRA.Game/Traits/TraitsInterfaces.cs @@ -271,7 +271,7 @@ public interface ISelectionDecorations public interface IMapPreviewSignatureInfo : ITraitInfoInterface { - void PopulateMapPreviewSignatureCells(Map map, ActorInfo ai, ActorReference s, List> destinationBuffer); + void PopulateMapPreviewSignatureCells(Map map, ActorInfo ai, ActorReference s, List<(MPos, Color)> destinationBuffer); } public interface IOccupySpaceInfo : ITraitInfoInterface @@ -284,7 +284,7 @@ public interface IOccupySpace { WPos CenterPosition { get; } CPos TopLeft { get; } - Pair[] OccupiedCells(); + (CPos Cell, SubCell SubCell)[] OccupiedCells(); } public enum SubCell : byte { Invalid = byte.MaxValue, Any = byte.MaxValue - 1, FullCell = 0, First = 1 } diff --git a/OpenRA.Mods.Cnc/Graphics/VoxelLoader.cs b/OpenRA.Mods.Cnc/Graphics/VoxelLoader.cs index f6c3b473e329..47c63f37a6ed 100644 --- a/OpenRA.Mods.Cnc/Graphics/VoxelLoader.cs +++ b/OpenRA.Mods.Cnc/Graphics/VoxelLoader.cs @@ -24,7 +24,7 @@ public sealed class VoxelLoader : IDisposable static readonly float[] ChannelSelect = { 0.75f, 0.25f, -0.25f, -0.75f }; readonly List vertices = new List(); - readonly Cache, Voxel> voxels; + readonly Cache<(string, string), Voxel> voxels; readonly IReadOnlyFileSystem fileSystem; IVertexBuffer vertexBuffer; int totalVertexCount; @@ -49,7 +49,7 @@ static SheetBuilder CreateSheetBuilder() public VoxelLoader(IReadOnlyFileSystem fileSystem) { this.fileSystem = fileSystem; - voxels = new Cache, Voxel>(LoadFile); + voxels = new Cache<(string, string), Voxel>(LoadFile); vertices = new List(); totalVertexCount = 0; cachedVertexCount = 0; @@ -211,20 +211,20 @@ public IVertexBuffer VertexBuffer } } - Voxel LoadFile(Pair 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() diff --git a/OpenRA.Mods.Cnc/OpenRA.Mods.Cnc.csproj b/OpenRA.Mods.Cnc/OpenRA.Mods.Cnc.csproj index 95ab2901495e..d05c8427422e 100644 --- a/OpenRA.Mods.Cnc/OpenRA.Mods.Cnc.csproj +++ b/OpenRA.Mods.Cnc/OpenRA.Mods.Cnc.csproj @@ -3,7 +3,7 @@ net472 true true - 5 + 7.3 true true ../mods/common diff --git a/OpenRA.Mods.Cnc/Traits/TDGunboat.cs b/OpenRA.Mods.Cnc/Traits/TDGunboat.cs index dbaede314059..e9b53ee98ba1 100644 --- a/OpenRA.Mods.Cnc/Traits/TDGunboat.cs +++ b/OpenRA.Mods.Cnc/Traits/TDGunboat.cs @@ -146,7 +146,7 @@ int MovementSpeed get { return OpenRA.Mods.Common.Util.ApplyPercentageModifiers(Info.Speed, speedModifiers); } } - public Pair[] OccupiedCells() { return new[] { Pair.New(TopLeft, SubCell.FullCell) }; } + public (CPos, SubCell)[] OccupiedCells() { return new[] { (TopLeft, SubCell.FullCell) }; } WVec MoveStep(WAngle facing) { diff --git a/OpenRA.Mods.Cnc/UtilityCommands/ImportRedAlertLegacyMapCommand.cs b/OpenRA.Mods.Cnc/UtilityCommands/ImportRedAlertLegacyMapCommand.cs index f9520d34911e..0e3a895435ff 100644 --- a/OpenRA.Mods.Cnc/UtilityCommands/ImportRedAlertLegacyMapCommand.cs +++ b/OpenRA.Mods.Cnc/UtilityCommands/ImportRedAlertLegacyMapCommand.cs @@ -17,7 +17,6 @@ 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 @@ public override void ValidateMapFormat(int format) "fpls", "wcrate", "scrate", "barb", "sbag", }; - static Dictionary> overlayResourceMapping = new Dictionary>() + static Dictionary overlayResourceMapping = new Dictionary() { // RA ore & crystals - { "gold01", new Pair(1, 0) }, - { "gold02", new Pair(1, 1) }, - { "gold03", new Pair(1, 2) }, - { "gold04", new Pair(1, 3) }, - { "gem01", new Pair(2, 0) }, - { "gem02", new Pair(2, 1) }, - { "gem03", new Pair(2, 2) }, - { "gem04", new Pair(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 @@ void UnpackOverlayData(MemoryStream ms) 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])) { diff --git a/OpenRA.Mods.Cnc/UtilityCommands/ImportTiberianDawnLegacyMapCommand.cs b/OpenRA.Mods.Cnc/UtilityCommands/ImportTiberianDawnLegacyMapCommand.cs index 9c8fc0865ee4..d19c783d436e 100644 --- a/OpenRA.Mods.Cnc/UtilityCommands/ImportTiberianDawnLegacyMapCommand.cs +++ b/OpenRA.Mods.Cnc/UtilityCommands/ImportTiberianDawnLegacyMapCommand.cs @@ -15,7 +15,6 @@ 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 @@ public override void ValidateMapFormat(int format) } } - static Dictionary> overlayResourceMapping = new Dictionary>() + static Dictionary overlayResourceMapping = new Dictionary() { // Tiberium - { "ti1", new Pair(1, 0) }, - { "ti2", new Pair(1, 1) }, - { "ti3", new Pair(1, 2) }, - { "ti4", new Pair(1, 3) }, - { "ti5", new Pair(1, 4) }, - { "ti6", new Pair(1, 5) }, - { "ti7", new Pair(1, 6) }, - { "ti8", new Pair(1, 7) }, - { "ti9", new Pair(1, 8) }, - { "ti10", new Pair(1, 9) }, - { "ti11", new Pair(1, 10) }, - { "ti12", new Pair(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 @@ void ReadOverlay(IniFile file) 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) diff --git a/OpenRA.Mods.Common/Activities/Move/Move.cs b/OpenRA.Mods.Common/Activities/Move/Move.cs index 6b08278e9b35..86893e91949f 100644 --- a/OpenRA.Mods.Common/Activities/Move/Move.cs +++ b/OpenRA.Mods.Common/Activities/Move/Move.cs @@ -201,16 +201,16 @@ public override bool Tick(Actor self) 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 @@ public override bool Tick(Actor self) return false; } - Pair? PopPath(Actor self) + (CPos Cell, SubCell SubCell)? PopPath(Actor self) { if (path.Count == 0) return null; @@ -310,7 +310,7 @@ public override bool Tick(Actor self) 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 @@ public override bool Tick(Actor self) 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 @@ public override bool Tick(Actor self) 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 @@ protected override MovePart OnComplete(Actor self, Mobile mobile, Move parent) 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) : diff --git a/OpenRA.Mods.Common/Activities/UnloadCargo.cs b/OpenRA.Mods.Common/Activities/UnloadCargo.cs index af4b1553e1ca..acecfd8d249c 100644 --- a/OpenRA.Mods.Common/Activities/UnloadCargo.cs +++ b/OpenRA.Mods.Common/Activities/UnloadCargo.cs @@ -50,15 +50,15 @@ public UnloadCargo(Actor self, Target destination, WDist unloadRange, bool unloa this.unloadRange = unloadRange; } - public Pair? ChooseExitSubCell(Actor passenger) + public (CPos Cell, SubCell SubCell)? ChooseExitSubCell(Actor passenger) { var pos = passenger.Trait(); return cargo.CurrentAdjacentCells .Shuffle(self.World.SharedRandom) - .Select(c => Pair.New(c, pos.GetAvailableSubCell(c))) - .Cast?>() - .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 BlockedExitCells(Actor passenger) @@ -121,7 +121,7 @@ public override bool Tick(Actor self) var move = actor.Trait(); var pos = actor.Trait(); - pos.SetPosition(actor, exitSubCell.Value.First, exitSubCell.Value.Second); + pos.SetPosition(actor, exitSubCell.Value.Cell, exitSubCell.Value.SubCell); pos.SetVisualPosition(actor, spawn); actor.CancelActivity(); diff --git a/OpenRA.Mods.Common/EditorBrushes/EditorCopyPasteBrush.cs b/OpenRA.Mods.Common/EditorBrushes/EditorCopyPasteBrush.cs index 980de0e4404f..9bb18de6a68d 100644 --- a/OpenRA.Mods.Common/EditorBrushes/EditorCopyPasteBrush.cs +++ b/OpenRA.Mods.Common/EditorBrushes/EditorCopyPasteBrush.cs @@ -116,7 +116,7 @@ void Copy(CellRegion source, CVec offset) var dest = new CellRegion(gridType, source.TopLeft + offset, source.BottomRight + offset); var previews = new Dictionary(); - var tiles = new Dictionary>(); + var tiles = new Dictionary(); var copyFilters = getCopyFilters(); foreach (var cell in source) @@ -124,7 +124,7 @@ void Copy(CellRegion source, CVec offset) 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 @@ class CopyPasteEditorAction : IEditorAction public string Text { get; private set; } readonly MapCopyFilters copyFilters; - readonly Dictionary> tiles; + readonly Dictionary tiles; readonly Dictionary previews; readonly EditorActorLayer editorLayer; readonly CellRegion dest; @@ -191,7 +191,7 @@ class CopyPasteEditorAction : IEditorAction readonly Queue addedActorPreviews = new Queue(); public CopyPasteEditorAction(MapCopyFilters copyFilters, Map map, - Dictionary> tiles, Dictionary previews, + Dictionary tiles, Dictionary previews, EditorActorLayer editorLayer, CellRegion dest) { this.copyFilters = copyFilters; @@ -219,12 +219,12 @@ public void Do() 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)) diff --git a/OpenRA.Mods.Common/Graphics/ModelRenderable.cs b/OpenRA.Mods.Common/Graphics/ModelRenderable.cs index f8ca37d18cf5..5a59f454ea89 100644 --- a/OpenRA.Mods.Common/Graphics/ModelRenderable.cs +++ b/OpenRA.Mods.Common/Graphics/ModelRenderable.cs @@ -133,7 +133,7 @@ public void Render(WorldRenderer wr) // 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 @@ static void DrawBoundsBox(WorldRenderer wr, float3 pxPos, float[] transform, flo public Rectangle ScreenBounds(WorldRenderer wr) { - return Screen3DBounds(wr).First; + return Screen3DBounds(wr).Bounds; } - Pair 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 @@ public Rectangle ScreenBounds(WorldRenderer wr) } } - 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)); } } } diff --git a/OpenRA.Mods.Common/Graphics/UIModelRenderable.cs b/OpenRA.Mods.Common/Graphics/UIModelRenderable.cs index afa75bb848b1..d39b8fad4ca3 100644 --- a/OpenRA.Mods.Common/Graphics/UIModelRenderable.cs +++ b/OpenRA.Mods.Common/Graphics/UIModelRenderable.cs @@ -106,13 +106,13 @@ public void Render(WorldRenderer wr) 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 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 @@ public Rectangle ScreenBounds(WorldRenderer wr) } } - 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)); } } } diff --git a/OpenRA.Mods.Common/Lint/CheckChromeHotkeys.cs b/OpenRA.Mods.Common/Lint/CheckChromeHotkeys.cs index 3a21f8455ed3..4d9817cb869c 100644 --- a/OpenRA.Mods.Common/Lint/CheckChromeHotkeys.cs +++ b/OpenRA.Mods.Common/Lint/CheckChromeHotkeys.cs @@ -41,7 +41,7 @@ public void Run(Action emitError, Action emitWarning, ModData mo var checkWidgetFields = modData.ObjectCreator.GetTypesImplementing() .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>(); @@ -64,7 +64,7 @@ public void Run(Action emitError, Action emitWarning, ModData mo } } - void CheckInner(ModData modData, string[] namedKeys, Pair[] checkWidgetFields, Dictionary> customLintMethods, + void CheckInner(ModData modData, string[] namedKeys, (string Widget, string Field)[] checkWidgetFields, Dictionary> customLintMethods, List nodes, string filename, MiniYamlNode parent, Action emitError, Action emitWarning) { foreach (var node in nodes) @@ -74,19 +74,17 @@ public void Run(Action emitError, Action emitWarning, ModData mo 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 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)type.GetMethod(m).Invoke(null, new object[] { node, emitError, emitWarning })); @@ -111,10 +109,9 @@ public void Run(Action emitError, Action emitWarning, ModData mo checkArgKeys.AddRange(type.GetCustomAttributes(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)); } diff --git a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj index ca73d91a9787..846f16856e76 100644 --- a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj +++ b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj @@ -3,7 +3,7 @@ net472 true true - 5 + 7.3 true true ../mods/common diff --git a/OpenRA.Mods.Common/Orders/PlaceBuildingOrderGenerator.cs b/OpenRA.Mods.Common/Orders/PlaceBuildingOrderGenerator.cs index 07cac1d0262a..341f632bfc22 100644 --- a/OpenRA.Mods.Common/Orders/PlaceBuildingOrderGenerator.cs +++ b/OpenRA.Mods.Common/Orders/PlaceBuildingOrderGenerator.cs @@ -262,9 +262,9 @@ IEnumerable IOrderGenerator.RenderAboveShroud(WorldRenderer wr, Wor { 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)); } } diff --git a/OpenRA.Mods.Common/Pathfinder/BasePathSearch.cs b/OpenRA.Mods.Common/Pathfinder/BasePathSearch.cs index 1b0c9fb81780..b081eb6e155f 100644 --- a/OpenRA.Mods.Common/Pathfinder/BasePathSearch.cs +++ b/OpenRA.Mods.Common/Pathfinder/BasePathSearch.cs @@ -27,7 +27,7 @@ public interface IPathSearch : IDisposable /// /// Stores the analyzed nodes by the expand function /// - IEnumerable> Considered { get; } + IEnumerable<(CPos Cell, int Cost)> Considered { get; } Player Owner { get; } @@ -68,7 +68,7 @@ public abstract class BasePathSearch : IPathSearch protected IPriorityQueue OpenQueue { get; private set; } - public abstract IEnumerable> 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; } diff --git a/OpenRA.Mods.Common/Pathfinder/PathGraph.cs b/OpenRA.Mods.Common/Pathfinder/PathGraph.cs index fb1f2c490fc1..f6937bd38a04 100644 --- a/OpenRA.Mods.Common/Pathfinder/PathGraph.cs +++ b/OpenRA.Mods.Common/Pathfinder/PathGraph.cs @@ -92,8 +92,8 @@ sealed class PathGraph : IGraph readonly bool checkTerrainHeight; CellLayer groundInfo; - readonly Dictionary>> customLayerInfo = - new Dictionary>>(); + readonly Dictionary Info)> customLayerInfo = + new Dictionary)>(); public PathGraph(CellInfoLayerPool layerPool, Locomotor locomotor, Actor actor, World world, BlockedByActor check) { @@ -105,7 +105,7 @@ public PathGraph(CellInfoLayerPool layerPool, Locomotor locomotor, Actor actor, .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 @@ public PathGraph(CellInfoLayerPool layerPool, Locomotor locomotor, Actor actor, public List 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 @@ public List GetConnections(CPos position) { 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 @@ public List GetConnections(CPos position) 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 @@ int CalculateCellCost(CPos neighborCPos, CVec direction, int movementCost) 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() diff --git a/OpenRA.Mods.Common/Pathfinder/PathSearch.cs b/OpenRA.Mods.Common/Pathfinder/PathSearch.cs index 4335b71a4fc1..45d6653894ac 100644 --- a/OpenRA.Mods.Common/Pathfinder/PathSearch.cs +++ b/OpenRA.Mods.Common/Pathfinder/PathSearch.cs @@ -30,19 +30,19 @@ static CellInfoLayerPool LayerPoolForWorld(World world) return LayerPoolTable.GetValue(world, CreateLayerPool); } - public override IEnumerable> Considered + public override IEnumerable<(CPos, int)> Considered { get { return considered; } } - LinkedList> considered; + LinkedList<(CPos, int)> considered; #region Constructors private PathSearch(IGraph graph) : base(graph) { - considered = new LinkedList>(); + considered = new LinkedList<(CPos, int)>(); } public static IPathSearch Search(World world, Locomotor locomotor, Actor self, BlockedByActor check, Func goalCondition) @@ -94,7 +94,7 @@ protected override void AddInitialCell(CPos location) var connection = new GraphConnection(location, cost); OpenQueue.Add(connection); StartPoints.Add(connection); - considered.AddLast(new Pair(location, 0)); + considered.AddLast((location, 0)); } #endregion @@ -146,7 +146,7 @@ public override CPos Expand() if (gCost > MaxCost) MaxCost = gCost; - considered.AddLast(new Pair(neighborCPos, gCost)); + considered.AddLast((neighborCPos, gCost)); } } diff --git a/OpenRA.Mods.Common/Scripting/Properties/ParatroopersProperties.cs b/OpenRA.Mods.Common/Scripting/Properties/ParatroopersProperties.cs index e01bdf277fcf..ace63ba0fa2c 100644 --- a/OpenRA.Mods.Common/Scripting/Properties/ParatroopersProperties.cs +++ b/OpenRA.Mods.Common/Scripting/Properties/ParatroopersProperties.cs @@ -31,7 +31,7 @@ public ParatroopersProperties(ScriptContext context, Actor self) 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 @@ public Actor[] ActivateParatroopers(WPos target, int facing = -1) { 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; } } } diff --git a/OpenRA.Mods.Common/ShroudExts.cs b/OpenRA.Mods.Common/ShroudExts.cs index 816f7aaf8e0e..5a2e74fdc7b7 100644 --- a/OpenRA.Mods.Common/ShroudExts.cs +++ b/OpenRA.Mods.Common/ShroudExts.cs @@ -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[] 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 @@ public static bool AnyExplored(this Shroud shroud, PPos[] puvs) return false; } - public static bool AnyVisible(this Shroud shroud, Pair[] 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; diff --git a/OpenRA.Mods.Common/Traits/AffectsShroud.cs b/OpenRA.Mods.Common/Traits/AffectsShroud.cs index 67bb82b4b76d..cac3031af82c 100644 --- a/OpenRA.Mods.Common/Traits/AffectsShroud.cs +++ b/OpenRA.Mods.Common/Traits/AffectsShroud.cs @@ -72,7 +72,7 @@ PPos[] ProjectedCells(Actor self) { // 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; diff --git a/OpenRA.Mods.Common/Traits/Air/Aircraft.cs b/OpenRA.Mods.Common/Traits/Air/Aircraft.cs index 5638de62e27c..c793b6beee0d 100644 --- a/OpenRA.Mods.Common/Traits/Air/Aircraft.cs +++ b/OpenRA.Mods.Common/Traits/Air/Aircraft.cs @@ -211,7 +211,7 @@ public class Aircraft : PausableConditionalTrait, ITick, ISync, IF INotifyAddedToWorld, INotifyRemovedFromWorld, INotifyActorDisposing, INotifyBecomingIdle, ICreationActivity, IActorPreviewInitModifier, IDeathActorInitModifier, IIssueDeployOrder, IIssueOrder, IResolveOrder, IOrderVoice { - static readonly Pair[] NoCells = { }; + static readonly (CPos, SubCell)[] NoCells = { }; readonly Actor self; @@ -597,12 +597,12 @@ public int MovementSpeed get { return !IsTraitDisabled && !IsTraitPaused ? Util.ApplyPercentageModifiers(Info.Speed, speedModifiers) : 0; } } - public Pair[] 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) diff --git a/OpenRA.Mods.Common/Traits/AppearsOnMapPreview.cs b/OpenRA.Mods.Common/Traits/AppearsOnMapPreview.cs index 383f57e26924..73d83c870bf0 100644 --- a/OpenRA.Mods.Common/Traits/AppearsOnMapPreview.cs +++ b/OpenRA.Mods.Common/Traits/AppearsOnMapPreview.cs @@ -26,7 +26,7 @@ public class AppearsOnMapPreviewInfo : TraitInfo, IMapPrevi "Overrides `Color` if both set.")] public readonly string Terrain = null; - void IMapPreviewSignatureInfo.PopulateMapPreviewSignatureCells(Map map, ActorInfo ai, ActorReference s, List> destinationBuffer) + void IMapPreviewSignatureInfo.PopulateMapPreviewSignatureCells(Map map, ActorInfo ai, ActorReference s, List<(MPos, Color)> destinationBuffer) { var tileSet = map.Rules.TileSet; @@ -50,7 +50,7 @@ void IMapPreviewSignatureInfo.PopulateMapPreviewSignatureCells(Map map, ActorInf var ios = ai.TraitInfo(); var cells = ios.OccupiedCells(ai, s.Get().Value); foreach (var cell in cells) - destinationBuffer.Add(new Pair(cell.Key.ToMPos(map), color)); + destinationBuffer.Add((cell.Key.ToMPos(map), color)); } } diff --git a/OpenRA.Mods.Common/Traits/Armament.cs b/OpenRA.Mods.Common/Traits/Armament.cs index 72357c7dd45d..579008fc15b1 100644 --- a/OpenRA.Mods.Common/Traits/Armament.cs +++ b/OpenRA.Mods.Common/Traits/Armament.cs @@ -127,7 +127,7 @@ public class Armament : PausableConditionalTrait, ITick int currentBarrel; int barrelCount; - List> delayedActions = new List>(); + List<(int Ticks, Action Func)> delayedActions = new List<(int, Action)>(); public WDist Recoil; public int FireDelay { get; protected set; } @@ -211,12 +211,12 @@ protected virtual void Tick(Actor self) 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 @@ void ITick.Tick(Actor self) protected void ScheduleDelayedAction(int t, Action a) { if (t > 0) - delayedActions.Add(Pair.New(t, a)); + delayedActions.Add((t, a)); else a(); } diff --git a/OpenRA.Mods.Common/Traits/Buildings/Bridge.cs b/OpenRA.Mods.Common/Traits/Buildings/Bridge.cs index 7f844c12f324..782436148cb4 100644 --- a/OpenRA.Mods.Common/Traits/Buildings/Bridge.cs +++ b/OpenRA.Mods.Common/Traits/Buildings/Bridge.cs @@ -64,27 +64,27 @@ public void RulesetLoaded(Ruleset rules, ActorInfo ai) DemolishWeaponInfo = weapon; } - public IEnumerable> 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 @@ public IEnumerable Render(Actor self, WorldRenderer wr) var palette = wr.Palette(TileSet.TerrainPaletteInternalName); renderables = new Dictionary(); 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; } diff --git a/OpenRA.Mods.Common/Traits/Buildings/Building.cs b/OpenRA.Mods.Common/Traits/Buildings/Building.cs index 2d78c4c320a1..7403cc41abd0 100644 --- a/OpenRA.Mods.Common/Traits/Buildings/Building.cs +++ b/OpenRA.Mods.Common/Traits/Buildings/Building.cs @@ -13,7 +13,6 @@ 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 @@ public class Building : IOccupySpace, ITargetableCells, INotifySold, INotifyTran readonly Actor self; readonly BuildingInfluence influence; - Pair[] occupiedCells; - Pair[] targetableCells; + (CPos, SubCell)[] occupiedCells; + (CPos, SubCell)[] targetableCells; CPos[] transitOnlyCells; public CPos TopLeft { get { return topLeft; } } @@ -283,21 +282,21 @@ public Building(ActorInitializer init, BuildingInfo info) influence = self.World.WorldActor.Trait(); 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[] OccupiedCells() { return occupiedCells; } + public (CPos, SubCell)[] OccupiedCells() { return occupiedCells; } public CPos[] TransitOnlyCells() { return transitOnlyCells; } - Pair[] ITargetableCells.TargetableCells() { return targetableCells; } + (CPos, SubCell)[] ITargetableCells.TargetableCells() { return targetableCells; } void INotifyAddedToWorld.AddedToWorld(Actor self) { diff --git a/OpenRA.Mods.Common/Traits/Buildings/BuildingUtils.cs b/OpenRA.Mods.Common/Traits/Buildings/BuildingUtils.cs index 80479c33a6b8..6e5e18e81dd3 100644 --- a/OpenRA.Mods.Common/Traits/Buildings/BuildingUtils.cs +++ b/OpenRA.Mods.Common/Traits/Buildings/BuildingUtils.cs @@ -54,13 +54,13 @@ public static bool CanPlaceBuilding(this World world, CPos cell, ActorInfo ai, B world.IsCellBuildable(t, ai, bi, toIgnore)); } - public static IEnumerable> 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(); var topLeft = cell; // 1x1 assumption! if (world.IsCellBuildable(topLeft, ai, bi)) - yield return Pair.New(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 @@ public static bool CanPlaceBuilding(this World world, CPos cell, ActorInfo ai, B // 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]); } } } diff --git a/OpenRA.Mods.Common/Traits/CapturableProgressBar.cs b/OpenRA.Mods.Common/Traits/CapturableProgressBar.cs index 4ea2585c4a56..f2a4ef2c6f7f 100644 --- a/OpenRA.Mods.Common/Traits/CapturableProgressBar.cs +++ b/OpenRA.Mods.Common/Traits/CapturableProgressBar.cs @@ -26,7 +26,7 @@ class CapturableProgressBarInfo : ConditionalTraitInfo, Requires class CapturableProgressBar : ConditionalTrait, ISelectionBar, ICaptureProgressWatcher { - Dictionary> progress = new Dictionary>(); + Dictionary progress = new Dictionary(); public CapturableProgressBar(Actor self, CapturableProgressBarInfo info) : base(info) { } @@ -39,7 +39,7 @@ void ICaptureProgressWatcher.Update(Actor self, Actor captor, Actor target, int if (total == 0) progress.Remove(captor); else - progress[captor] = Pair.New(current, total); + progress[captor] = (current, total); } float ISelectionBar.GetValue() @@ -47,7 +47,7 @@ float ISelectionBar.GetValue() 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; } diff --git a/OpenRA.Mods.Common/Traits/Crates/Crate.cs b/OpenRA.Mods.Common/Traits/Crates/Crate.cs index 84bc140a9f08..d299a5c38f38 100644 --- a/OpenRA.Mods.Common/Traits/Crates/Crate.cs +++ b/OpenRA.Mods.Common/Traits/Crates/Crate.cs @@ -155,20 +155,20 @@ void OnCrushInner(Actor crusher) 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 @@ void ITick.Tick(Actor self) } public CPos TopLeft { get { return Location; } } - public Pair[] OccupiedCells() { return new[] { Pair.New(Location, SubCell.FullCell) }; } + public (CPos, SubCell)[] OccupiedCells() { return new[] { (Location, SubCell.FullCell) }; } public WPos CenterPosition { get; private set; } diff --git a/OpenRA.Mods.Common/Traits/DamagedByTerrain.cs b/OpenRA.Mods.Common/Traits/DamagedByTerrain.cs index 74a861688cf6..fd15f2444abc 100644 --- a/OpenRA.Mods.Common/Traits/DamagedByTerrain.cs +++ b/OpenRA.Mods.Common/Traits/DamagedByTerrain.cs @@ -67,7 +67,7 @@ void INotifyAddedToWorld.AddedToWorld(Actor self) 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++; } diff --git a/OpenRA.Mods.Common/Traits/ExitsDebugOverlay.cs b/OpenRA.Mods.Common/Traits/ExitsDebugOverlay.cs index a52ebdc92b9b..b8e76f49eedb 100644 --- a/OpenRA.Mods.Common/Traits/ExitsDebugOverlay.cs +++ b/OpenRA.Mods.Common/Traits/ExitsDebugOverlay.cs @@ -70,7 +70,7 @@ IEnumerable IRenderAnnotationsWhenSelected.RenderAnnotations(Actor 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) diff --git a/OpenRA.Mods.Common/Traits/GainsExperience.cs b/OpenRA.Mods.Common/Traits/GainsExperience.cs index 6d1882dbef5a..7e177709db6c 100644 --- a/OpenRA.Mods.Common/Traits/GainsExperience.cs +++ b/OpenRA.Mods.Common/Traits/GainsExperience.cs @@ -58,7 +58,7 @@ public class GainsExperience : INotifyCreated, ISync, IResolveOrder, ITransformA readonly GainsExperienceInfo info; readonly int initialExperience; - readonly List> nextLevel = new List>(); + readonly List<(int RequiredExperience, string Condition)> nextLevel = new List<(int, string)>(); // Stored as a percentage of our value [Sync] @@ -83,7 +83,7 @@ void INotifyCreated.Created(Actor self) var valued = self.Info.TraitInfoOrDefault(); 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 @@ public void GiveLevels(int numLevels, bool silent = false) 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 @@ public void GiveExperience(int amount, bool silent = false) 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++; diff --git a/OpenRA.Mods.Common/Traits/HitShape.cs b/OpenRA.Mods.Common/Traits/HitShape.cs index ce0034222b49..c232f4fbf22f 100644 --- a/OpenRA.Mods.Common/Traits/HitShape.cs +++ b/OpenRA.Mods.Common/Traits/HitShape.cs @@ -94,7 +94,7 @@ IEnumerable ITargetablePositions.TargetablePositions(Actor self) 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) { diff --git a/OpenRA.Mods.Common/Traits/Husk.cs b/OpenRA.Mods.Common/Traits/Husk.cs index 75cb6809c57d..60b6ae69e7f6 100644 --- a/OpenRA.Mods.Common/Traits/Husk.cs +++ b/OpenRA.Mods.Common/Traits/Husk.cs @@ -116,7 +116,7 @@ public bool CanExistInCell(CPos cell) return true; } - public Pair[] 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) diff --git a/OpenRA.Mods.Common/Traits/Immobile.cs b/OpenRA.Mods.Common/Traits/Immobile.cs index 8c21fde1c472..1d9692c98430 100644 --- a/OpenRA.Mods.Common/Traits/Immobile.cs +++ b/OpenRA.Mods.Common/Traits/Immobile.cs @@ -39,7 +39,7 @@ class Immobile : IOccupySpace, ISync, INotifyAddedToWorld, INotifyRemovedFromWor [Sync] readonly WPos position; - readonly Pair[] occupied; + readonly (CPos, SubCell)[] occupied; public Immobile(ActorInitializer init, ImmobileInfo info) { @@ -47,14 +47,14 @@ public Immobile(ActorInitializer init, ImmobileInfo info) 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[0]; + occupied = new (CPos, SubCell)[0]; } public CPos TopLeft { get { return location; } } public WPos CenterPosition { get { return position; } } - public Pair[] OccupiedCells() { return occupied; } + public (CPos, SubCell)[] OccupiedCells() { return occupied; } void INotifyAddedToWorld.AddedToWorld(Actor self) { diff --git a/OpenRA.Mods.Common/Traits/Mobile.cs b/OpenRA.Mods.Common/Traits/Mobile.cs index e0b4fac3e8fe..1fc451c28de1 100644 --- a/OpenRA.Mods.Common/Traits/Mobile.cs +++ b/OpenRA.Mods.Common/Traits/Mobile.cs @@ -229,16 +229,16 @@ public WAngle Facing public CPos TopLeft { get { return ToCell; } } - public Pair[] 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 diff --git a/OpenRA.Mods.Common/Traits/Player/ConquestVictoryConditions.cs b/OpenRA.Mods.Common/Traits/Player/ConquestVictoryConditions.cs index 71f291659651..9f98b4e98890 100644 --- a/OpenRA.Mods.Common/Traits/Player/ConquestVictoryConditions.cs +++ b/OpenRA.Mods.Common/Traits/Player/ConquestVictoryConditions.cs @@ -78,12 +78,12 @@ void INotifyTimeLimit.NotifyTimerExpired(Actor self) 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(p, p.PlayerActor.TraitOrDefault())) - .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())) + .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; diff --git a/OpenRA.Mods.Common/Traits/Player/GrantConditionOnPrerequisiteManager.cs b/OpenRA.Mods.Common/Traits/Player/GrantConditionOnPrerequisiteManager.cs index 30bd2a72e51e..c3cfb1f83cb5 100644 --- a/OpenRA.Mods.Common/Traits/Player/GrantConditionOnPrerequisiteManager.cs +++ b/OpenRA.Mods.Common/Traits/Player/GrantConditionOnPrerequisiteManager.cs @@ -25,7 +25,7 @@ public class GrantConditionOnPrerequisiteManagerInfo : TraitInfo, Requires>> upgradables = new Dictionary>>(); + readonly Dictionary> upgradables = new Dictionary>(); readonly TechTree techTree; public GrantConditionOnPrerequisiteManager(ActorInitializer init) @@ -44,11 +44,11 @@ public void Register(Actor actor, GrantConditionOnPrerequisite u, string[] prere var key = MakeKey(prerequisites); if (!upgradables.ContainsKey(key)) { - upgradables.Add(key, new List>()); + 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 @@ public void Unregister(Actor actor, GrantConditionOnPrerequisite u, string[] pre 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 @@ public void Unregister(Actor actor, GrantConditionOnPrerequisite u, string[] pre public void PrerequisitesAvailable(string key) { - List> 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> 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) { } diff --git a/OpenRA.Mods.Common/Traits/Player/PlaceBuilding.cs b/OpenRA.Mods.Common/Traits/Player/PlaceBuilding.cs index 601d9b2f6117..9dfd31ee76d2 100644 --- a/OpenRA.Mods.Common/Traits/Player/PlaceBuilding.cs +++ b/OpenRA.Mods.Common/Traits/Player/PlaceBuilding.cs @@ -119,16 +119,16 @@ void IResolveOrder.ResolveOrder(Actor self, Order order) 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() }); } diff --git a/OpenRA.Mods.Common/Traits/Player/PlayerRadarTerrain.cs b/OpenRA.Mods.Common/Traits/Player/PlayerRadarTerrain.cs index 85e20cdf1ed2..de374dff5d38 100644 --- a/OpenRA.Mods.Common/Traits/Player/PlayerRadarTerrain.cs +++ b/OpenRA.Mods.Common/Traits/Player/PlayerRadarTerrain.cs @@ -29,7 +29,7 @@ public class PlayerRadarTerrain : IWorldLoaded public bool IsInitialized { get; private set; } readonly World world; - CellLayer> terrainColor; + CellLayer<(int, int)> terrainColor; readonly Shroud shroud; public event Action CellTerrainColorChanged = null; @@ -67,7 +67,7 @@ void UpdateTerrainCellColor(MPos uv) public void WorldLoaded(World w, WorldRenderer wr) { - terrainColor = new CellLayer>(w.Map); + terrainColor = new CellLayer<(int, int)>(w.Map); w.AddFrameEndTask(_ => { @@ -82,22 +82,22 @@ public void WorldLoaded(World w, WorldRenderer wr) }); } - public Pair this[MPos uv] + public (int Left, int Right) this[MPos uv] { get { return terrainColor[uv]; } } - public static Pair 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()); } } } diff --git a/OpenRA.Mods.Common/Traits/Player/StrategicVictoryConditions.cs b/OpenRA.Mods.Common/Traits/Player/StrategicVictoryConditions.cs index cbcac294fccf..dfd6bafafa49 100644 --- a/OpenRA.Mods.Common/Traits/Player/StrategicVictoryConditions.cs +++ b/OpenRA.Mods.Common/Traits/Player/StrategicVictoryConditions.cs @@ -119,12 +119,12 @@ void INotifyTimeLimit.NotifyTimerExpired(Actor self) 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(p, p.PlayerActor.TraitOrDefault())) - .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())) + .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; diff --git a/OpenRA.Mods.Common/Traits/Radar/AppearsOnRadar.cs b/OpenRA.Mods.Common/Traits/Radar/AppearsOnRadar.cs index 71e2503d38cf..0e62dc732e86 100644 --- a/OpenRA.Mods.Common/Traits/Radar/AppearsOnRadar.cs +++ b/OpenRA.Mods.Common/Traits/Radar/AppearsOnRadar.cs @@ -39,7 +39,7 @@ protected override void Created(Actor self) modifier = self.TraitsImplementing().FirstOrDefault(); } - public void PopulateRadarSignatureCells(Actor self, List> 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 @@ public void PopulateRadarSignatureCells(Actor self, List> dest 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)); } } } diff --git a/OpenRA.Mods.Common/Traits/Render/RenderSprites.cs b/OpenRA.Mods.Common/Traits/Render/RenderSprites.cs index fdc2fa84f39d..ded56db26fa3 100644 --- a/OpenRA.Mods.Common/Traits/Render/RenderSprites.cs +++ b/OpenRA.Mods.Common/Traits/Render/RenderSprites.cs @@ -87,12 +87,12 @@ public string GetImage(ActorInfo actor, SequenceProvider sequenceProvider, strin public class RenderSprites : IRender, ITick, INotifyOwnerChanged, INotifyEffectiveOwnerChanged, IActorPreviewInitModifier { - static readonly Pair[] 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 @@ public static string UnnormalizeSequence(string sequence) // 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 @@ public static string NormalizeSequence(Animation anim, DamageState state, string 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; } diff --git a/OpenRA.Mods.Common/Traits/SupportPowers/ParatroopersPower.cs b/OpenRA.Mods.Common/Traits/SupportPowers/ParatroopersPower.cs index 138a44a213c2..918e4e3d3778 100644 --- a/OpenRA.Mods.Common/Traits/SupportPowers/ParatroopersPower.cs +++ b/OpenRA.Mods.Common/Traits/SupportPowers/ParatroopersPower.cs @@ -97,7 +97,7 @@ public override void Activate(Actor self, Order order, SupportPowerManager manag SendParatroopers(self, order.Target.CenterPosition, facing); } - public Pair 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(); var units = new List(); @@ -266,7 +266,7 @@ public override void Activate(Actor self, Order order, SupportPowerManager manag } }); - return Pair.New(aircraft.ToArray(), units.ToArray()); + return (aircraft.ToArray(), units.ToArray()); } void RemoveCamera(Actor camera) diff --git a/OpenRA.Mods.Common/Traits/World/ActorMap.cs b/OpenRA.Mods.Common/Traits/World/ActorMap.cs index acef8ea4ce33..238fb1bb24bb 100644 --- a/OpenRA.Mods.Common/Traits/World/ActorMap.cs +++ b/OpenRA.Mods.Common/Traits/World/ActorMap.cs @@ -359,20 +359,20 @@ public void AddInfluence(Actor self, IOccupySpace ios) { 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 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 @@ public void RemoveInfluence(Actor self, IOccupySpace ios) { 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 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 @@ public void UpdateOccupiedCells(IOccupySpace ios) return; foreach (var c in ios.OccupiedCells()) - CellUpdated(c.First); + CellUpdated(c.Cell); } void ITick.Tick(Actor self) diff --git a/OpenRA.Mods.Common/Traits/World/EditorActorLayer.cs b/OpenRA.Mods.Common/Traits/World/EditorActorLayer.cs index f175ce72d087..0b98b80ef388 100644 --- a/OpenRA.Mods.Common/Traits/World/EditorActorLayer.cs +++ b/OpenRA.Mods.Common/Traits/World/EditorActorLayer.cs @@ -315,11 +315,11 @@ public List Save() return nodes; } - public void PopulateRadarSignatureCells(Actor self, List> 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] diff --git a/OpenRA.Mods.Common/Traits/World/LegacyBridgeLayer.cs b/OpenRA.Mods.Common/Traits/World/LegacyBridgeLayer.cs index 2e6ef3700cb4..1d36dcc2acdb 100644 --- a/OpenRA.Mods.Common/Traits/World/LegacyBridgeLayer.cs +++ b/OpenRA.Mods.Common/Traits/World/LegacyBridgeLayer.cs @@ -28,7 +28,7 @@ class LegacyBridgeLayerInfo : TraitInfo class LegacyBridgeLayer : IWorldLoaded { readonly LegacyBridgeLayerInfo info; - readonly Dictionary> bridgeTypes = new Dictionary>(); + readonly Dictionary bridgeTypes = new Dictionary(); CellLayer bridges; @@ -46,7 +46,7 @@ public void WorldLoaded(World w, WorldRenderer wr) { var bi = w.Map.Rules.Actors[bridge].TraitInfo(); 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 @@ void ConvertBridgeToActor(World w, CPos cell) 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(); var subTiles = new Dictionary(); diff --git a/OpenRA.Mods.Common/Traits/World/MPStartLocations.cs b/OpenRA.Mods.Common/Traits/World/MPStartLocations.cs index 32d55d2824a0..7d98bc22a449 100644 --- a/OpenRA.Mods.Common/Traits/World/MPStartLocations.cs +++ b/OpenRA.Mods.Common/Traits/World/MPStartLocations.cs @@ -133,8 +133,8 @@ CPos ChooseSpawnPoint(World world, List available, List taken) 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); diff --git a/OpenRA.Mods.Common/Traits/World/ResourceType.cs b/OpenRA.Mods.Common/Traits/World/ResourceType.cs index 7a46f39ab30f..51fc8b23c7ab 100644 --- a/OpenRA.Mods.Common/Traits/World/ResourceType.cs +++ b/OpenRA.Mods.Common/Traits/World/ResourceType.cs @@ -63,7 +63,7 @@ public class ResourceTypeInfo : TraitInfo, IMapPreviewSignatureInfo [Desc("Allow resource to spawn on ramp tiles.")] public readonly bool AllowOnRamps = false; - void IMapPreviewSignatureInfo.PopulateMapPreviewSignatureCells(Map map, ActorInfo ai, ActorReference s, List> 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 @@ void IMapPreviewSignatureInfo.PopulateMapPreviewSignatureCells(Map map, ActorInf { var cell = new MPos(i, j); if (map.Resources[cell].Type == ResourceType) - destinationBuffer.Add(new Pair(cell, color)); + destinationBuffer.Add((cell, color)); } } } diff --git a/OpenRA.Mods.Common/TraitsInterfaces.cs b/OpenRA.Mods.Common/TraitsInterfaces.cs index ab6793d3c0dc..3e758e7688b8 100644 --- a/OpenRA.Mods.Common/TraitsInterfaces.cs +++ b/OpenRA.Mods.Common/TraitsInterfaces.cs @@ -441,7 +441,7 @@ public interface IOverrideAircraftLanding public interface IRadarSignature { - void PopulateRadarSignatureCells(Actor self, List> destinationBuffer); + void PopulateRadarSignatureCells(Actor self, List<(CPos Cell, Color Color)> destinationBuffer); } public interface IRadarColorModifier { Color RadarColorOverride(Actor self, Color color); } @@ -476,7 +476,7 @@ public interface INotifyCashTransfer [RequireExplicitImplementation] public interface ITargetableCells { - Pair[] TargetableCells(); + (CPos Cell, SubCell SubCell)[] TargetableCells(); } [RequireExplicitImplementation] diff --git a/OpenRA.Mods.Common/UpdateRules/UpdateUtils.cs b/OpenRA.Mods.Common/UpdateRules/UpdateUtils.cs index 93c9120810b1..e8f242443103 100644 --- a/OpenRA.Mods.Common/UpdateRules/UpdateUtils.cs +++ b/OpenRA.Mods.Common/UpdateRules/UpdateUtils.cs @@ -17,7 +17,7 @@ namespace OpenRA.Mods.Common.UpdateRules { - using YamlFileSet = List>>; + using YamlFileSet = List<(IReadWritePackage, string, List)>; public static class UpdateUtils { @@ -37,7 +37,7 @@ static YamlFileSet LoadModYaml(ModData modData, IEnumerable files) 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 @@ static YamlFileSet LoadInternalMapYaml(ModData modData, IReadWritePackage mapPac { var fileSet = new YamlFileSet() { - Tuple.Create>(null, "map.yaml", yaml.Nodes) + (null, "map.yaml", yaml.Nodes) }; var files = FieldLoader.GetValue("value", yaml.Value); @@ -70,7 +70,7 @@ static YamlFileSet LoadInternalMapYaml(ModData modData, IReadWritePackage mapPac { // 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 @@ public static List UpdateMap(ModData modData, IReadWritePackage mapPacka } 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 @@ public static List UpdateMap(ModData modData, IReadWritePackage mapPacka { var mapActors = new YamlFileSet() { - Tuple.Create>(null, "map.yaml", mapActorsNode.Value.Nodes) + (null, "map.yaml", mapActorsNode.Value.Nodes) }; manualSteps.AddRange(ApplyTopLevelTransform(modData, mapActors, rule.UpdateMapActorNode)); diff --git a/OpenRA.Mods.Common/UtilityCommands/DebugChromeRegions.cs b/OpenRA.Mods.Common/UtilityCommands/DebugChromeRegions.cs index e4ff73bc6ccb..a25f4e2ca101 100644 --- a/OpenRA.Mods.Common/UtilityCommands/DebugChromeRegions.cs +++ b/OpenRA.Mods.Common/UtilityCommands/DebugChromeRegions.cs @@ -46,24 +46,24 @@ void IUtilityCommand.Run(Utility utility, string[] args) 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)); } } diff --git a/OpenRA.Mods.Common/UtilityCommands/ExtractLuaDocsCommand.cs b/OpenRA.Mods.Common/UtilityCommands/ExtractLuaDocsCommand.cs index de03d49a855b..3a9130485ab2 100644 --- a/OpenRA.Mods.Common/UtilityCommands/ExtractLuaDocsCommand.cs +++ b/OpenRA.Mods.Common/UtilityCommands/ExtractLuaDocsCommand.cs @@ -87,7 +87,7 @@ void IUtilityCommand.Run(Utility utility, string[] args) 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 @@ void IUtilityCommand.Run(Utility utility, string[] args) 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) diff --git a/OpenRA.Mods.Common/UtilityCommands/ImportLegacyMapCommand.cs b/OpenRA.Mods.Common/UtilityCommands/ImportLegacyMapCommand.cs index c905910738d6..a7c6cd3e7eda 100644 --- a/OpenRA.Mods.Common/UtilityCommands/ImportLegacyMapCommand.cs +++ b/OpenRA.Mods.Common/UtilityCommands/ImportLegacyMapCommand.cs @@ -251,17 +251,17 @@ void LoadWaypoints(IniSection waypointSection) 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 @@ void LoadWaypoints(IniSection waypointSection) { 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); } } } diff --git a/OpenRA.Mods.Common/UtilityCommands/UpdateMapCommand.cs b/OpenRA.Mods.Common/UtilityCommands/UpdateMapCommand.cs index 8428a9306fb5..25db7eee15bd 100644 --- a/OpenRA.Mods.Common/UtilityCommands/UpdateMapCommand.cs +++ b/OpenRA.Mods.Common/UtilityCommands/UpdateMapCommand.cs @@ -18,7 +18,7 @@ namespace OpenRA.Mods.Common.UtilityCommands { - using YamlFileSet = List>>; + using YamlFileSet = List<(IReadWritePackage, string, List)>; class UpdateMapCommand : IUtilityCommand { diff --git a/OpenRA.Mods.Common/UtilityCommands/UpdateModCommand.cs b/OpenRA.Mods.Common/UtilityCommands/UpdateModCommand.cs index c68350814ae9..03e2bffb5d26 100644 --- a/OpenRA.Mods.Common/UtilityCommands/UpdateModCommand.cs +++ b/OpenRA.Mods.Common/UtilityCommands/UpdateModCommand.cs @@ -18,7 +18,7 @@ namespace OpenRA.Mods.Common.UtilityCommands { - using YamlFileSet = List>>; + using YamlFileSet = List<(IReadWritePackage, string, List)>; class UpdateModCommand : IUtilityCommand { diff --git a/OpenRA.Mods.Common/Warheads/SpreadDamageWarhead.cs b/OpenRA.Mods.Common/Warheads/SpreadDamageWarhead.cs index 29ef61f00866..b87a5ed73e03 100644 --- a/OpenRA.Mods.Common/Warheads/SpreadDamageWarhead.cs +++ b/OpenRA.Mods.Common/Warheads/SpreadDamageWarhead.cs @@ -61,18 +61,18 @@ protected override void DoImpact(WPos pos, Actor firedBy, WarheadArgs args) var closestActiveShape = victim.TraitsImplementing() .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 @@ protected override void DoImpact(WPos pos, Actor firedBy, WarheadArgs args) ImpactOrientation = impactOrientation, }; - InflictDamage(victim, firedBy, closestActiveShape.First, updatedWarheadArgs); + InflictDamage(victim, firedBy, closestActiveShape.HitShape, updatedWarheadArgs); } } diff --git a/OpenRA.Mods.Common/Warheads/TargetDamageWarhead.cs b/OpenRA.Mods.Common/Warheads/TargetDamageWarhead.cs index b1f136517ca7..11e2c883480b 100644 --- a/OpenRA.Mods.Common/Warheads/TargetDamageWarhead.cs +++ b/OpenRA.Mods.Common/Warheads/TargetDamageWarhead.cs @@ -38,18 +38,18 @@ protected override void DoImpact(WPos pos, Actor firedBy, WarheadArgs args) var closestActiveShape = victim.TraitsImplementing() .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); } } } diff --git a/OpenRA.Mods.Common/Widgets/LabelWithHighlightWidget.cs b/OpenRA.Mods.Common/Widgets/LabelWithHighlightWidget.cs index 4ddd38efa650..f437e4f28aec 100644 --- a/OpenRA.Mods.Common/Widgets/LabelWithHighlightWidget.cs +++ b/OpenRA.Mods.Common/Widgets/LabelWithHighlightWidget.cs @@ -20,25 +20,25 @@ namespace OpenRA.Mods.Common.Widgets public class LabelWithHighlightWidget : LabelWidget { public Color HighlightColor = ChromeMetrics.Get("TextHighlightColor"); - readonly CachedTransform[]> textComponents; + readonly CachedTransform textComponents; [ObjectCreator.UseCtor] public LabelWithHighlightWidget() : base() { - textComponents = new CachedTransform[]>(MakeComponents); + textComponents = new CachedTransform(MakeComponents); } protected LabelWithHighlightWidget(LabelWithHighlightWidget other) : base(other) { HighlightColor = other.HighlightColor; - textComponents = new CachedTransform[]>(MakeComponents); + textComponents = new CachedTransform(MakeComponents); } - Pair[] MakeComponents(string text) + (string, bool)[] MakeComponents(string text) { - List> components = new List>(); + var components = new List<(string, bool)>(); foreach (var l in text.Split(new[] { "\\n" }, StringSplitOptions.None)) { var line = l; @@ -54,18 +54,18 @@ protected LabelWithHighlightWidget(LabelWithHighlightWidget other) { // 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 @@ protected override void DrawInner(string text, SpriteFont font, Color color, int 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; } } diff --git a/OpenRA.Mods.Common/Widgets/Logic/Ingame/GameInfoStatsLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Ingame/GameInfoStatsLogic.cs index 69098611e8b4..06aa96e84185 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Ingame/GameInfoStatsLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Ingame/GameInfoStatsLogic.cs @@ -66,10 +66,10 @@ public GameInfoStatsLogic(Widget widget, World world, OrderManager orderManager, playerPanel.RemoveChildren(); var teams = world.Players.Where(p => !p.NonCombatant && p.Playable) - .Select(p => new Pair(p, p.PlayerActor.TraitOrDefault())) - .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())) + .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 @@ public GameInfoStatsLogic(Widget widget, World world, OrderManager orderManager, teamHeader.Get("TEAM").GetText = () => t.Key == 0 ? "No Team" : "Team {0}".F(t.Key); var teamRating = teamHeader.Get("TEAM_SCORE"); var scoreCache = new CachedTransform(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 @@ public GameInfoStatsLogic(Widget widget, World world, OrderManager orderManager, 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 @@ public GameInfoStatsLogic(Widget widget, World world, OrderManager orderManager, } var scoreCache = new CachedTransform(s => s.ToString()); - item.Get("SCORE").GetText = () => scoreCache.Update(p.Second != null ? p.Second.Experience : 0); + item.Get("SCORE").GetText = () => scoreCache.Update(p.PlayerStatistics != null ? p.PlayerStatistics.Experience : 0); playerPanel.AddChild(item); } @@ -133,13 +133,13 @@ public GameInfoStatsLogic(Widget widget, World world, OrderManager orderManager, var nameFont = Game.Renderer.Fonts[nameLabel.Font]; var suffixLength = new CachedTransform(s => nameFont.Measure(s).X); - var name = new CachedTransform, 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("KICK"); diff --git a/OpenRA.Mods.Common/Widgets/Logic/Ingame/ObserverStatsLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Ingame/ObserverStatsLogic.cs index 0f62bafeda8f..d901f9abee65 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Ingame/ObserverStatsLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Ingame/ObserverStatsLogic.cs @@ -442,8 +442,8 @@ ScrollItemWidget BasicStats(Player player) if (powerRes != null) { var power = template.Get("POWER"); - var powerText = new CachedTransform, string>(p => p.First + "/" + p.Second); - power.GetText = () => powerText.Update(new Pair(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); } diff --git a/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyUtils.cs b/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyUtils.cs index 90b6489eafa1..a0c817d6ede6 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyUtils.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyUtils.cs @@ -162,15 +162,15 @@ public SlotDropDownOption(string title, string order, Func selected) } /// Splits a string into two parts on the first instance of a given token. - static Pair SplitOnFirstToken(string input, string token = "\\n") + static (string First, string Second) SplitOnFirstToken(string input, string token = "\\n") { if (string.IsNullOrEmpty(input)) - return Pair.New(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 @@ public static void SelectSpawnPoint(OrderManager orderManager, MapPreviewWidget 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)); diff --git a/OpenRA.Mods.Common/Widgets/Logic/MapChooserLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/MapChooserLogic.cs index 1cdc5b70c224..ad10d21c3950 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/MapChooserLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/MapChooserLogic.cs @@ -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 @@ void SetupGameModeDropdown(MapClassification tab, DropDownButtonWidget gameModeD // 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, 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, 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("LABEL").GetText = () => showItem(ii); return item; }; @@ -205,9 +204,9 @@ void SetupGameModeDropdown(MapClassification tab, DropDownButtonWidget gameModeD gameModeDropdown.GetText = () => { - var item = categories.FirstOrDefault(m => m.First == category); - if (item == default(Pair)) - item.First = "No matches"; + var item = categories.FirstOrDefault(m => m.Category == category); + if (item == default((string, int))) + item.Category = "No matches"; return showItem(item); }; diff --git a/OpenRA.Mods.Common/Widgets/Logic/ReplayBrowserLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/ReplayBrowserLogic.cs index dceb1ff60508..7e1a96ca3b7a 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/ReplayBrowserLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/ReplayBrowserLogic.cs @@ -138,25 +138,25 @@ void SetupFilters() if (ddb != null) { // Using list to maintain the order - var options = new List> + 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, 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("LABEL").GetText = () => option.Second; + () => filter.Type == option.GameType, + () => { filter.Type = option.GameType; ApplyFilter(); }); + item.Get("LABEL").GetText = () => option.Text; return item; }; @@ -171,28 +171,28 @@ void SetupFilters() if (ddb != null) { // Using list to maintain the order - var options = new List> + 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, 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("LABEL").GetText = () => option.Second; + item.Get("LABEL").GetText = () => option.Text; return item; }; @@ -207,27 +207,27 @@ void SetupFilters() if (ddb != null) { // Using list to maintain the order - var options = new List> + 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, 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("LABEL").GetText = () => option.Second; + () => filter.Duration == option.DurationType, + () => { filter.Duration = option.DurationType; ApplyFilter(); }); + item.Get("LABEL").GetText = () => option.Text; return item; }; @@ -244,25 +244,25 @@ void SetupFilters() ddb.IsDisabled = () => string.IsNullOrEmpty(filter.PlayerName); // Using list to maintain the order - var options = new List> + 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, 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("LABEL").GetText = () => option.Second; + () => filter.Outcome == option.WinState, + () => { filter.Outcome = option.WinState; ApplyFilter(); }); + item.Get("LABEL").GetText = () => option.Text; return item; }; diff --git a/OpenRA.Mods.Common/Widgets/Logic/SystemInfoPromptLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/SystemInfoPromptLogic.cs index 12f8aa3a8e8f..d24da961a8ed 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/SystemInfoPromptLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/SystemInfoPromptLogic.cs @@ -14,7 +14,6 @@ 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 @@ public class SystemInfoPromptLogic : ChromeLogic // Increment the version number when adding new stats const int SystemInformationVersion = 4; - static Dictionary> GetSystemInformation() + static Dictionary GetSystemInformation() { var lang = CultureInfo.InstalledUICulture.TwoLetterISOLanguageName; - return new Dictionary>() + return new Dictionary() { - { "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 @@ public static string CreateParameterString() 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 @@ public SystemInfoPromptLogic(Widget widget, Action onComplete) 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); } diff --git a/OpenRA.Mods.Common/Widgets/RadarWidget.cs b/OpenRA.Mods.Common/Widgets/RadarWidget.cs index 5958879f0b9f..607936c24dcf 100644 --- a/OpenRA.Mods.Common/Widgets/RadarWidget.cs +++ b/OpenRA.Mods.Common/Widgets/RadarWidget.cs @@ -206,8 +206,8 @@ void MapBoundsChanged() 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 @@ public override void Tick() var stride = radarSheet.Size.Width; Array.Clear(radarData, 4 * actorSprite.Bounds.Top * stride, 4 * actorSprite.Bounds.Height * stride); - var cells = new List>(); + var cells = new List<(CPos Cell, Color Color)>(); unsafe { @@ -403,11 +403,11 @@ public override void Tick() 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 diff --git a/OpenRA.Mods.Common/Widgets/SupportPowerTimerWidget.cs b/OpenRA.Mods.Common/Widgets/SupportPowerTimerWidget.cs index 88a4980243f0..831601ed2541 100644 --- a/OpenRA.Mods.Common/Widgets/SupportPowerTimerWidget.cs +++ b/OpenRA.Mods.Common/Widgets/SupportPowerTimerWidget.cs @@ -27,7 +27,7 @@ public class SupportPowerTimerWidget : Widget readonly int timestep; readonly IEnumerable powers; readonly Color bgDark, bgLight; - Pair[] texts; + (string Text, Color Color)[] texts; [ObjectCreator.UseCtor] public SupportPowerTimerWidget(World world) @@ -67,7 +67,7 @@ public override void Tick() var color = !p.Ready || Game.LocalTick % 50 < 25 ? playerColor : Color.White; - return Pair.New(text, color); + return (text, color); }).ToArray(); } @@ -80,8 +80,8 @@ public override void Draw() 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; } } diff --git a/OpenRA.Mods.Common/Widgets/WidgetUtils.cs b/OpenRA.Mods.Common/Widgets/WidgetUtils.cs index 05b845645b19..97500108abbc 100644 --- a/OpenRA.Mods.Common/Widgets/WidgetUtils.cs +++ b/OpenRA.Mods.Common/Widgets/WidgetUtils.cs @@ -337,19 +337,19 @@ public static void BindPlayerNameAndStatus(LabelWidget label, Player p) { var client = p.World.LobbyInfo.ClientWithIndex(p.ClientIndex); var nameFont = Game.Renderer.Fonts[label.Font]; - var name = new CachedTransform, 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)); }; } } diff --git a/OpenRA.Mods.D2k/Lint/CheckImportActors.cs b/OpenRA.Mods.D2k/Lint/CheckImportActors.cs index 8a2b2b72bb88..6692b6e3e561 100644 --- a/OpenRA.Mods.D2k/Lint/CheckImportActors.cs +++ b/OpenRA.Mods.D2k/Lint/CheckImportActors.cs @@ -21,8 +21,8 @@ public void Run(Action emitError, Action emitWarning, Ruleset ru { 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)); } } } diff --git a/OpenRA.Mods.D2k/OpenRA.Mods.D2k.csproj b/OpenRA.Mods.D2k/OpenRA.Mods.D2k.csproj index d8578219ceaf..d7db47d52465 100644 --- a/OpenRA.Mods.D2k/OpenRA.Mods.D2k.csproj +++ b/OpenRA.Mods.D2k/OpenRA.Mods.D2k.csproj @@ -3,7 +3,7 @@ net472 true true - 5 + 7.3 true true ../mods/d2k diff --git a/OpenRA.Mods.D2k/UtilityCommands/D2kMapImporter.cs b/OpenRA.Mods.D2k/UtilityCommands/D2kMapImporter.cs index c190fd4900b7..e25a03bb0259 100644 --- a/OpenRA.Mods.D2k/UtilityCommands/D2kMapImporter.cs +++ b/OpenRA.Mods.D2k/UtilityCommands/D2kMapImporter.cs @@ -21,236 +21,236 @@ public class D2kMapImporter { const int MapCordonWidth = 2; - public static Dictionary> ActorDataByActorCode = new Dictionary> + public static Dictionary ActorDataByActorCode = new Dictionary { - { 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 @@ void FillMap() 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++; } } diff --git a/OpenRA.Platforms.Default/MultiTapDetection.cs b/OpenRA.Platforms.Default/MultiTapDetection.cs index 03ab8e748fc7..3199c9d84999 100644 --- a/OpenRA.Platforms.Default/MultiTapDetection.cs +++ b/OpenRA.Platforms.Default/MultiTapDetection.cs @@ -16,8 +16,8 @@ namespace OpenRA.Platforms.Default { static class MultiTapDetection { - static Cache, TapHistory> keyHistoryCache = - new Cache, 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 clickHistoryCache = new Cache(_ => new TapHistory(DateTime.Now - TimeSpan.FromSeconds(1))); @@ -33,35 +33,35 @@ public static int InfoFromMouse(byte button) 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 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 a, Pair 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; diff --git a/OpenRA.Platforms.Default/OpenRA.Platforms.Default.csproj b/OpenRA.Platforms.Default/OpenRA.Platforms.Default.csproj index 21860b456a0c..250e32cd4b81 100644 --- a/OpenRA.Platforms.Default/OpenRA.Platforms.Default.csproj +++ b/OpenRA.Platforms.Default/OpenRA.Platforms.Default.csproj @@ -3,7 +3,7 @@ net472 true true - 5 + 7.3 true true .. diff --git a/OpenRA.Platforms.Default/ThreadedGraphicsContext.cs b/OpenRA.Platforms.Default/ThreadedGraphicsContext.cs index 4c438aa413e6..fc04bb63da7e 100644 --- a/OpenRA.Platforms.Default/ThreadedGraphicsContext.cs +++ b/OpenRA.Platforms.Default/ThreadedGraphicsContext.cs @@ -89,7 +89,7 @@ void RenderThread(object contextObject) getCreateFrameBuffer = tuple => { - var t = (Tuple)tuple; + var t = (ValueTuple)tuple; return new ThreadedFrameBuffer(this, context.CreateFrameBuffer(t.Item1, (ITextureInternal)CreateTexture(), t.Item2)); }; @@ -98,13 +98,13 @@ void RenderThread(object contextObject) doDrawPrimitives = tuple => { - var t = (Tuple)tuple; + var t = (ValueTuple)tuple; context.DrawPrimitives(t.Item1, t.Item2, t.Item3); }; doEnableScissor = tuple => { - var t = (Tuple)tuple; + var t = (ValueTuple)tuple; context.EnableScissor(t.Item1, t.Item2, t.Item3, t.Item4); }; doSetBlendMode = mode => { context.SetBlendMode((BlendMode)mode); }; @@ -390,12 +390,12 @@ public void ClearDepthBuffer() 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 @@ public void DisableScissor() 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 @@ public void EnableDepthBuffer() 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 @@ public ThreadedVertexBuffer(ThreadedGraphicsContext device, IVertexBuffer { var t = (Tuple)tuple; vertexBuffer.SetData(t.Item1, t.Item2); device.ReturnVertices(t.Item1); }; - setData2 = tuple => { var t = (Tuple)tuple; vertexBuffer.SetData(t.Item1, t.Item2, t.Item3); return null; }; + setData1 = tuple => { var t = (ValueTuple)tuple; vertexBuffer.SetData(t.Item1, t.Item2); device.ReturnVertices(t.Item1); }; + setData2 = tuple => { var t = (ValueTuple)tuple; vertexBuffer.SetData(t.Item1, t.Item2, t.Item3); return null; }; dispose = vertexBuffer.Dispose; } @@ -536,20 +536,20 @@ public void SetData(Vertex[] vertices, int length) { 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 @@ public ThreadedTexture(ThreadedGraphicsContext device, ITextureInternal texture) getScaleFilter = () => texture.ScaleFilter; setScaleFilter = value => texture.ScaleFilter = (TextureScaleFilter)value; getSize = () => texture.Size; - setEmpty = tuple => { var t = (Tuple)tuple; texture.SetEmpty(t.Item1, t.Item2); }; + setEmpty = tuple => { var t = (ValueTuple)tuple; texture.SetEmpty(t.Item1, t.Item2); }; getData = () => texture.GetData(); setData1 = colors => { texture.SetData((uint[,])colors); return null; }; - setData2 = tuple => { var t = (Tuple)tuple; texture.SetData(t.Item1, t.Item2, t.Item3); }; + setData2 = tuple => { var t = (ValueTuple)tuple; texture.SetData(t.Item1, t.Item2, t.Item3); }; dispose = texture.Dispose; } @@ -616,7 +616,7 @@ public Size Size 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 @@ public void SetData(byte[] colors, int width, int height) // 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 @@ public ThreadedShader(ThreadedGraphicsContext device, IShader shader) { this.device = device; prepareRender = shader.PrepareRender; - setBool = tuple => { var t = (Tuple)tuple; shader.SetBool(t.Item1, t.Item2); }; - setMatrix = tuple => { var t = (Tuple)tuple; shader.SetMatrix(t.Item1, t.Item2); }; - setTexture = tuple => { var t = (Tuple)tuple; shader.SetTexture(t.Item1, t.Item2); }; - setVec1 = tuple => { var t = (Tuple)tuple; shader.SetVec(t.Item1, t.Item2); }; - setVec2 = tuple => { var t = (Tuple)tuple; shader.SetVec(t.Item1, t.Item2, t.Item3); }; - setVec3 = tuple => { var t = (Tuple)tuple; shader.SetVec(t.Item1, t.Item2, t.Item3); }; - setVec4 = tuple => { var t = (Tuple)tuple; shader.SetVec(t.Item1, t.Item2, t.Item3, t.Item4); }; + setBool = tuple => { var t = (ValueTuple)tuple; shader.SetBool(t.Item1, t.Item2); }; + setMatrix = tuple => { var t = (ValueTuple)tuple; shader.SetMatrix(t.Item1, t.Item2); }; + setTexture = tuple => { var t = (ValueTuple)tuple; shader.SetTexture(t.Item1, t.Item2); }; + setVec1 = tuple => { var t = (ValueTuple)tuple; shader.SetVec(t.Item1, t.Item2); }; + setVec2 = tuple => { var t = (ValueTuple)tuple; shader.SetVec(t.Item1, t.Item2, t.Item3); }; + setVec3 = tuple => { var t = (ValueTuple)tuple; shader.SetVec(t.Item1, t.Item2, t.Item3); }; + setVec4 = tuple => { var t = (ValueTuple)tuple; shader.SetVec(t.Item1, t.Item2, t.Item3, t.Item4); }; } public void PrepareRender() @@ -677,37 +677,37 @@ public void PrepareRender() 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)); } } } diff --git a/OpenRA.Server/OpenRA.Server.csproj b/OpenRA.Server/OpenRA.Server.csproj index e3aba014d036..2459a23cc11c 100644 --- a/OpenRA.Server/OpenRA.Server.csproj +++ b/OpenRA.Server/OpenRA.Server.csproj @@ -7,7 +7,7 @@ false .. false - 5 + 7.3 true true AnyCPU diff --git a/OpenRA.Test/OpenRA.Test.csproj b/OpenRA.Test/OpenRA.Test.csproj index 86f923948253..12c2a542e527 100644 --- a/OpenRA.Test/OpenRA.Test.csproj +++ b/OpenRA.Test/OpenRA.Test.csproj @@ -2,7 +2,7 @@ net472 true - 5 + 7.3 true true .. diff --git a/OpenRA.Utility/OpenRA.Utility.csproj b/OpenRA.Utility/OpenRA.Utility.csproj index e3aba014d036..2459a23cc11c 100644 --- a/OpenRA.Utility/OpenRA.Utility.csproj +++ b/OpenRA.Utility/OpenRA.Utility.csproj @@ -7,7 +7,7 @@ false .. false - 5 + 7.3 true true AnyCPU