Change classes that use FieldLoader to use read-only collections.
This commit is contained in:
committed by
Paul Chote
parent
797c71e500
commit
649e7e8c28
@@ -12,6 +12,7 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using OpenRA.FileFormats;
|
||||
@@ -28,7 +29,7 @@ namespace OpenRA
|
||||
public readonly string Id;
|
||||
public readonly string Version;
|
||||
public readonly string LaunchPath;
|
||||
public readonly string[] LaunchArgs;
|
||||
public readonly ImmutableArray<string> LaunchArgs;
|
||||
public Sprite Icon { get; internal set; }
|
||||
public Sprite Icon2x { get; internal set; }
|
||||
public Sprite Icon3x { get; internal set; }
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
@@ -78,7 +79,7 @@ namespace OpenRA
|
||||
return Math.Sign((v1.X - v0.X) * (p.Y - v0.Y) - (p.X - v0.X) * (v1.Y - v0.Y));
|
||||
}
|
||||
|
||||
public static bool PolygonContains(this int2[] polygon, int2 p)
|
||||
public static bool PolygonContains(this ImmutableArray<int2> polygon, int2 p)
|
||||
{
|
||||
var windingNumber = 0;
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using Linguini.Bundle;
|
||||
@@ -87,19 +88,19 @@ namespace OpenRA
|
||||
{
|
||||
readonly Linguini.Bundle.FluentBundle bundle;
|
||||
|
||||
public FluentBundle(string culture, string[] paths, IReadOnlyFileSystem fileSystem)
|
||||
public FluentBundle(string culture, ImmutableArray<string> paths, IReadOnlyFileSystem fileSystem)
|
||||
: this(culture, paths, fileSystem, error => Log.Write("debug", error.Message)) { }
|
||||
|
||||
public FluentBundle(string culture, string[] paths, IReadOnlyFileSystem fileSystem, string text)
|
||||
public FluentBundle(string culture, ImmutableArray<string> paths, IReadOnlyFileSystem fileSystem, string text)
|
||||
: this(culture, paths, fileSystem, text, error => Log.Write("debug", error.Message)) { }
|
||||
|
||||
public FluentBundle(string culture, string[] paths, IReadOnlyFileSystem fileSystem, Action<ParseError> onError)
|
||||
public FluentBundle(string culture, ImmutableArray<string> paths, IReadOnlyFileSystem fileSystem, Action<ParseError> onError)
|
||||
: this(culture, paths, fileSystem, null, onError) { }
|
||||
|
||||
public FluentBundle(string culture, string text, Action<ParseError> onError)
|
||||
: this(culture, null, null, text, onError) { }
|
||||
: this(culture, default, null, text, onError) { }
|
||||
|
||||
public FluentBundle(string culture, string[] paths, IReadOnlyFileSystem fileSystem, string text, Action<ParseError> onError)
|
||||
public FluentBundle(string culture, ImmutableArray<string> paths, IReadOnlyFileSystem fileSystem, string text, Action<ParseError> onError)
|
||||
{
|
||||
bundle = LinguiniBuilder.Builder()
|
||||
.CultureInfo(new CultureInfo(culture))
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Immutable;
|
||||
using System.Text;
|
||||
using OpenRA.FileSystem;
|
||||
|
||||
@@ -29,9 +30,9 @@ namespace OpenRA
|
||||
modFluentBundle = new FluentBundle(modData.Manifest.FluentCulture, modData.Manifest.FluentMessages, fileSystem);
|
||||
if (fileSystem is Map map && map.FluentMessageDefinitions != null)
|
||||
{
|
||||
var files = Array.Empty<string>();
|
||||
var files = ImmutableArray<string>.Empty;
|
||||
if (map.FluentMessageDefinitions.Value != null)
|
||||
files = FieldLoader.GetValue<string[]>("value", map.FluentMessageDefinitions.Value);
|
||||
files = FieldLoader.GetValue<ImmutableArray<string>>("value", map.FluentMessageDefinitions.Value);
|
||||
|
||||
string text = null;
|
||||
if (map.FluentMessageDefinitions.Nodes.Length > 0)
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Frozen;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace OpenRA
|
||||
@@ -23,15 +24,15 @@ namespace OpenRA
|
||||
public class Fonts : IGlobalModData
|
||||
{
|
||||
[FieldLoader.LoadUsing(nameof(LoadFonts))]
|
||||
public readonly Dictionary<string, FontData> FontList;
|
||||
public readonly FrozenDictionary<string, FontData> FontList;
|
||||
|
||||
static object LoadFonts(MiniYaml y)
|
||||
{
|
||||
var ret = new Dictionary<string, FontData>();
|
||||
var ret = new Dictionary<string, FontData>(y.Nodes.Length);
|
||||
foreach (var node in y.Nodes)
|
||||
ret.Add(node.Key, FieldLoader.Load<FontData>(node.Value));
|
||||
|
||||
return ret;
|
||||
return ret.ToFrozenDictionary();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
@@ -415,7 +416,7 @@ namespace OpenRA
|
||||
|
||||
var modSearchArg = args.GetValue("Engine.ModSearchPaths", null);
|
||||
var modSearchPaths = modSearchArg != null ?
|
||||
FieldLoader.GetValue<string[]>("Engine.ModsPath", modSearchArg) :
|
||||
FieldLoader.GetValue<ImmutableArray<string>>("Engine.ModsPath", modSearchArg) :
|
||||
[Path.Combine(Platform.EngineDir, "mods")];
|
||||
|
||||
Mods = new InstalledMods(modSearchPaths, explicitModPaths);
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Frozen;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.FileSystem;
|
||||
@@ -41,7 +42,7 @@ namespace OpenRA
|
||||
public TimeSpan Duration => EndTimeUtc > StartTimeUtc ? EndTimeUtc - StartTimeUtc : TimeSpan.Zero;
|
||||
|
||||
public IList<Player> Players { get; }
|
||||
public HashSet<int> DisabledSpawnPoints = [];
|
||||
public FrozenSet<int> DisabledSpawnPoints = FrozenSet<int>.Empty;
|
||||
|
||||
public MapPreview MapPreview
|
||||
{
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using OpenRA.FileSystem;
|
||||
@@ -268,7 +269,7 @@ namespace OpenRA
|
||||
|
||||
if (mapRules.Value != null)
|
||||
{
|
||||
var mapFiles = FieldLoader.GetValue<string[]>("value", mapRules.Value);
|
||||
var mapFiles = FieldLoader.GetValue<ImmutableArray<string>>("value", mapRules.Value);
|
||||
foreach (var f in mapFiles)
|
||||
if (AnyFlaggedTraits(modData, MiniYaml.FromStream(fileSystem.Open(f), f)))
|
||||
return true;
|
||||
|
||||
@@ -10,37 +10,38 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Frozen;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Collections.Immutable;
|
||||
|
||||
namespace OpenRA.GameRules
|
||||
{
|
||||
public class SoundInfo
|
||||
{
|
||||
public readonly Dictionary<string, string[]> Variants = [];
|
||||
public readonly Dictionary<string, string[]> Prefixes = [];
|
||||
public readonly Dictionary<string, string[]> Voices = [];
|
||||
public readonly Dictionary<string, string[]> Notifications = [];
|
||||
public readonly FrozenDictionary<string, ImmutableArray<string>> Variants = FrozenDictionary<string, ImmutableArray<string>>.Empty;
|
||||
public readonly FrozenDictionary<string, ImmutableArray<string>> Prefixes = FrozenDictionary<string, ImmutableArray<string>>.Empty;
|
||||
public readonly FrozenDictionary<string, ImmutableArray<string>> Voices = FrozenDictionary<string, ImmutableArray<string>>.Empty;
|
||||
public readonly FrozenDictionary<string, ImmutableArray<string>> Notifications = FrozenDictionary<string, ImmutableArray<string>>.Empty;
|
||||
public readonly string DefaultVariant = ".aud";
|
||||
public readonly string DefaultPrefix = "";
|
||||
public readonly HashSet<string> DisableVariants = [];
|
||||
public readonly HashSet<string> DisablePrefixes = [];
|
||||
public readonly FrozenSet<string> DisableVariants = FrozenSet<string>.Empty;
|
||||
public readonly FrozenSet<string> DisablePrefixes = FrozenSet<string>.Empty;
|
||||
|
||||
public readonly Lazy<Dictionary<string, SoundPool>> VoicePools;
|
||||
public readonly Lazy<Dictionary<string, SoundPool>> NotificationsPools;
|
||||
public readonly Lazy<FrozenDictionary<string, SoundPool>> VoicePools;
|
||||
public readonly Lazy<FrozenDictionary<string, SoundPool>> NotificationsPools;
|
||||
|
||||
public SoundInfo(MiniYaml y)
|
||||
{
|
||||
FieldLoader.Load(this, y);
|
||||
|
||||
VoicePools = Exts.Lazy(() => Voices.ToDictionary(a => a.Key, a => new SoundPool(1f, SoundPool.DefaultInterruptType, a.Value)));
|
||||
VoicePools = Exts.Lazy(() => Voices.ToFrozenDictionary(a => a.Key, a => new SoundPool(1f, SoundPool.DefaultInterruptType, a.Value)));
|
||||
NotificationsPools = Exts.Lazy(() => ParseSoundPool(y, "Notifications"));
|
||||
}
|
||||
|
||||
static Dictionary<string, SoundPool> ParseSoundPool(MiniYaml y, string key)
|
||||
static FrozenDictionary<string, SoundPool> ParseSoundPool(MiniYaml y, string key)
|
||||
{
|
||||
var ret = new Dictionary<string, SoundPool>();
|
||||
var classifiction = y.NodeWithKey(key);
|
||||
var ret = new Dictionary<string, SoundPool>(classifiction.Value.Nodes.Length);
|
||||
foreach (var t in classifiction.Value.Nodes)
|
||||
{
|
||||
var volumeModifier = 1f;
|
||||
@@ -53,12 +54,12 @@ namespace OpenRA.GameRules
|
||||
if (interruptTypeNode != null)
|
||||
interruptType = FieldLoader.GetValue<SoundPool.InterruptType>(interruptTypeNode.Key, interruptTypeNode.Value.Value);
|
||||
|
||||
var names = FieldLoader.GetValue<string[]>(t.Key, t.Value.Value);
|
||||
var names = FieldLoader.GetValue<ImmutableArray<string>>(t.Key, t.Value.Value);
|
||||
var sp = new SoundPool(volumeModifier, interruptType, names);
|
||||
ret.Add(t.Key, sp);
|
||||
}
|
||||
|
||||
return ret;
|
||||
return ret.ToFrozenDictionary();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,10 +69,10 @@ namespace OpenRA.GameRules
|
||||
public const InterruptType DefaultInterruptType = InterruptType.DoNotPlay;
|
||||
public readonly float VolumeModifier;
|
||||
public readonly InterruptType Type;
|
||||
readonly string[] clips;
|
||||
readonly ImmutableArray<string> clips;
|
||||
readonly List<string> liveclips = [];
|
||||
|
||||
public SoundPool(float volumeModifier, InterruptType interruptType, params string[] clips)
|
||||
public SoundPool(float volumeModifier, InterruptType interruptType, ImmutableArray<string> clips)
|
||||
{
|
||||
VolumeModifier = volumeModifier;
|
||||
Type = interruptType;
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using OpenRA.Effects;
|
||||
using OpenRA.Primitives;
|
||||
@@ -82,13 +83,13 @@ namespace OpenRA.GameRules
|
||||
public readonly WVec FollowingBurstTargetOffset = WVec.Zero;
|
||||
|
||||
[Desc("The sound played each time the weapon is fired.")]
|
||||
public readonly string[] Report = null;
|
||||
public readonly ImmutableArray<string> Report = default;
|
||||
|
||||
[Desc("Sound played only on first burst in a salvo.")]
|
||||
public readonly string[] StartBurstReport = null;
|
||||
public readonly ImmutableArray<string> StartBurstReport = default;
|
||||
|
||||
[Desc("The sound played when the weapon is reloaded.")]
|
||||
public readonly string[] AfterFireSound = null;
|
||||
public readonly ImmutableArray<string> AfterFireSound = default;
|
||||
|
||||
[Desc("Delay in ticks to play reloading sound.")]
|
||||
public readonly int AfterFireSoundDelay = 0;
|
||||
@@ -116,7 +117,7 @@ namespace OpenRA.GameRules
|
||||
|
||||
[Desc("Delay in ticks between firing shots from the same ammo magazine. If one entry, it will be used for all bursts.",
|
||||
"If multiple entries, their number needs to match Burst - 1.")]
|
||||
public readonly int[] BurstDelays = [5];
|
||||
public readonly ImmutableArray<int> BurstDelays = [5];
|
||||
|
||||
[Desc("The minimum range the weapon can fire.")]
|
||||
public readonly WDist MinRange = WDist.Zero;
|
||||
@@ -128,7 +129,7 @@ namespace OpenRA.GameRules
|
||||
public readonly IProjectileInfo Projectile;
|
||||
|
||||
[FieldLoader.LoadUsing(nameof(LoadWarheads))]
|
||||
public readonly List<IWarhead> Warheads = [];
|
||||
public readonly ImmutableArray<IWarhead> Warheads = [];
|
||||
|
||||
/// <summary>
|
||||
/// This constructor is used solely for documentation generation.
|
||||
@@ -170,7 +171,7 @@ namespace OpenRA.GameRules
|
||||
retList.Add(ret);
|
||||
}
|
||||
|
||||
return retList;
|
||||
return retList.ToImmutableArray();
|
||||
}
|
||||
|
||||
public bool IsValidTarget(BitSet<TargetableType> targetTypes)
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using OpenRA.Primitives;
|
||||
using OpenRA.Support;
|
||||
@@ -250,7 +251,7 @@ namespace OpenRA.Graphics
|
||||
return sequences.GetSequence(Name, sequenceName);
|
||||
}
|
||||
|
||||
public string GetRandomExistingSequence(string[] sequences, MersenneTwister random)
|
||||
public string GetRandomExistingSequence(ImmutableArray<string> sequences, MersenneTwister random)
|
||||
{
|
||||
return sequences.Where(HasSequence).RandomOrDefault(random);
|
||||
}
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Frozen;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using OpenRA.FileSystem;
|
||||
using OpenRA.Primitives;
|
||||
@@ -47,9 +49,9 @@ namespace OpenRA.Graphics
|
||||
public readonly string Image2x = null;
|
||||
public readonly string Image3x = null;
|
||||
|
||||
public readonly int[] PanelRegion = null;
|
||||
public readonly ImmutableArray<int> PanelRegion = default;
|
||||
public readonly PanelSides PanelSides = PanelSides.All;
|
||||
public readonly Dictionary<string, Rectangle> Regions = [];
|
||||
public readonly FrozenDictionary<string, Rectangle> Regions = FrozenDictionary<string, Rectangle>.Empty;
|
||||
}
|
||||
|
||||
public static IReadOnlyDictionary<string, Collection> Collections => collections;
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.IO;
|
||||
using OpenRA.Primitives;
|
||||
|
||||
@@ -64,18 +65,18 @@ namespace OpenRA.Graphics
|
||||
Buffer.BlockCopy(colors, 0, destination, destinationOffset * 4, Palette.Size * 4);
|
||||
}
|
||||
|
||||
public ImmutablePalette(string filename, int[] remapTransparent, int[] remap)
|
||||
public ImmutablePalette(string filename, ImmutableArray<int> remapTransparent, ImmutableArray<int> remap)
|
||||
{
|
||||
using (var s = File.OpenRead(filename))
|
||||
LoadFromStream(s, remapTransparent, remap);
|
||||
}
|
||||
|
||||
public ImmutablePalette(Stream s, int[] remapTransparent, int[] remapShadow)
|
||||
public ImmutablePalette(Stream s, ImmutableArray<int> remapTransparent, ImmutableArray<int> remapShadow)
|
||||
{
|
||||
LoadFromStream(s, remapTransparent, remapShadow);
|
||||
}
|
||||
|
||||
void LoadFromStream(Stream s, int[] remapTransparent, int[] remapShadow)
|
||||
void LoadFromStream(Stream s, ImmutableArray<int> remapTransparent, ImmutableArray<int> remapShadow)
|
||||
{
|
||||
using (var reader = new BinaryReader(s))
|
||||
for (var i = 0; i < Palette.Size; i++)
|
||||
|
||||
@@ -135,7 +135,7 @@ namespace OpenRA
|
||||
void SetVec(string name, float x);
|
||||
void SetVec(string name, float x, float y);
|
||||
void SetVec(string name, float x, float y, float z);
|
||||
void SetVec(string name, float[] vec, int length);
|
||||
void SetVec(string name, ReadOnlyMemory<float> vec, int length);
|
||||
void SetTexture(string param, ITexture texture);
|
||||
void SetMatrix(string param, float[] mtx);
|
||||
void PrepareRender();
|
||||
|
||||
@@ -10,19 +10,19 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Immutable;
|
||||
using OpenRA.Primitives;
|
||||
|
||||
namespace OpenRA.Graphics
|
||||
{
|
||||
public class PlayerColorRemap : IPaletteRemap
|
||||
{
|
||||
readonly int[] remapIndices;
|
||||
readonly ImmutableArray<int> remapIndices;
|
||||
readonly float hue;
|
||||
readonly float saturation;
|
||||
readonly float value;
|
||||
|
||||
public PlayerColorRemap(int[] remapIndices, Color color)
|
||||
public PlayerColorRemap(ImmutableArray<int> remapIndices, Color color)
|
||||
{
|
||||
this.remapIndices = remapIndices;
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using OpenRA.FileSystem;
|
||||
@@ -27,7 +28,7 @@ namespace OpenRA.Graphics
|
||||
|
||||
readonly Dictionary<
|
||||
int,
|
||||
(int[] Frames, MiniYamlNode.SourceLocation Location, AdjustFrame AdjustFrame, bool Premultiplied)> spriteReservations = [];
|
||||
(ImmutableArray<int> Frames, MiniYamlNode.SourceLocation Location, AdjustFrame AdjustFrame, bool Premultiplied)> spriteReservations = [];
|
||||
readonly Dictionary<string, List<int>> reservationsByFilename = [];
|
||||
|
||||
readonly Dictionary<int, Sprite[]> resolvedSprites = [];
|
||||
@@ -49,11 +50,11 @@ namespace OpenRA.Graphics
|
||||
this.loaders = loaders;
|
||||
}
|
||||
|
||||
public int ReserveSprites(string filename, IEnumerable<int> frames, MiniYamlNode.SourceLocation location,
|
||||
public int ReserveSprites(string filename, ImmutableArray<int> frames, MiniYamlNode.SourceLocation location,
|
||||
AdjustFrame adjustFrame = null, bool premultiplied = false)
|
||||
{
|
||||
var token = nextReservationToken++;
|
||||
spriteReservations[token] = (frames?.ToArray(), location, adjustFrame, premultiplied);
|
||||
spriteReservations[token] = (frames, location, adjustFrame, premultiplied);
|
||||
reservationsByFilename.GetOrAdd(filename, _ => []).Add(token);
|
||||
return token;
|
||||
}
|
||||
@@ -103,8 +104,8 @@ namespace OpenRA.Graphics
|
||||
throw new InvalidOperationException($"{rs.Location}: {filename} does not contain frames: " +
|
||||
string.Join(',', rs.Frames.Where(f => f >= loadedFrames.Length)));
|
||||
|
||||
var frames = rs.Frames ?? Enumerable.Range(0, loadedFrames.Length);
|
||||
var total = rs.Frames?.Length ?? loadedFrames.Length;
|
||||
var frames = rs.Frames != null ? rs.Frames : Enumerable.Range(0, loadedFrames.Length);
|
||||
var total = rs.Frames != null ? rs.Frames.Length : loadedFrames.Length;
|
||||
|
||||
var j = 0;
|
||||
foreach (var i in frames)
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using OpenRA.Primitives;
|
||||
|
||||
@@ -268,7 +269,7 @@ namespace OpenRA.Graphics
|
||||
{
|
||||
var ramp = map.Grid.Ramps[map.Ramp.Contains(uv) ? map.Ramp[uv] : 0];
|
||||
var pos = map.CenterOfCell(uv.ToCPos(map)) - new WVec(0, 0, ramp.CenterHeightOffset);
|
||||
var screen = ramp.Corners.Select(c => worldRenderer.ScreenPxPosition(pos + c)).ToArray();
|
||||
var screen = ramp.Corners.Select(c => worldRenderer.ScreenPxPosition(pos + c)).ToImmutableArray();
|
||||
if (screen.PolygonContains(world))
|
||||
return uv.ToCPos(map);
|
||||
}
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Frozen;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
|
||||
namespace OpenRA
|
||||
@@ -24,10 +25,10 @@ namespace OpenRA
|
||||
[FluentReference]
|
||||
public readonly string Description = "";
|
||||
|
||||
public readonly HashSet<string> Types = [];
|
||||
public readonly FrozenSet<string> Types = FrozenSet<string>.Empty;
|
||||
|
||||
[FluentReference]
|
||||
public readonly HashSet<string> Contexts = [];
|
||||
public readonly FrozenSet<string> Contexts = FrozenSet<string>.Empty;
|
||||
|
||||
public readonly bool Readonly = false;
|
||||
public bool HasDuplicates { get; internal set; }
|
||||
@@ -45,11 +46,11 @@ namespace OpenRA
|
||||
Description = descriptionYaml.Value;
|
||||
|
||||
if (nodeDict.TryGetValue("Types", out var typesYaml))
|
||||
Types = FieldLoader.GetValue<HashSet<string>>("Types", typesYaml.Value);
|
||||
Types = FieldLoader.GetValue<FrozenSet<string>>("Types", typesYaml.Value);
|
||||
|
||||
if (nodeDict.TryGetValue("Contexts", out var contextYaml))
|
||||
Contexts = FieldLoader.GetValue<HashSet<string>>("Contexts", contextYaml.Value)
|
||||
.Select(c => ContextFluentPrefix + "." + c).ToHashSet();
|
||||
Contexts = FieldLoader.GetValue<ImmutableArray<string>>("Contexts", contextYaml.Value)
|
||||
.Select(c => ContextFluentPrefix + "." + c).ToFrozenSet();
|
||||
|
||||
if (nodeDict.TryGetValue("Platform", out var platformYaml))
|
||||
{
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Frozen;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
@@ -68,22 +70,22 @@ namespace OpenRA
|
||||
public readonly string Id;
|
||||
public readonly IReadOnlyPackage Package;
|
||||
public readonly ModMetadata Metadata;
|
||||
public readonly string[]
|
||||
public readonly ImmutableArray<string>
|
||||
Rules, ServerTraits,
|
||||
Sequences, ModelSequences, Cursors, Chrome, ChromeLayout,
|
||||
Weapons, Voices, Notifications, Music, FluentMessages, TileSets,
|
||||
ChromeMetrics, MapCompatibility, Missions, Hotkeys;
|
||||
|
||||
public readonly IReadOnlyDictionary<string, string> MapFolders;
|
||||
public readonly FrozenDictionary<string, string> MapFolders;
|
||||
public readonly MiniYaml FileSystem;
|
||||
public readonly MiniYaml LoadScreen;
|
||||
public readonly string DefaultOrderGenerator;
|
||||
|
||||
public readonly string[] Assemblies = [];
|
||||
public readonly string[] SoundFormats = [];
|
||||
public readonly string[] SpriteFormats = [];
|
||||
public readonly string[] PackageFormats = [];
|
||||
public readonly string[] VideoFormats = [];
|
||||
public readonly ImmutableArray<string> Assemblies = [];
|
||||
public readonly ImmutableArray<string> SoundFormats = [];
|
||||
public readonly ImmutableArray<string> SpriteFormats = [];
|
||||
public readonly ImmutableArray<string> PackageFormats = [];
|
||||
public readonly ImmutableArray<string> VideoFormats = [];
|
||||
public readonly int FontSheetSize = 512;
|
||||
public readonly int CursorSheetSize = 512;
|
||||
|
||||
@@ -91,14 +93,14 @@ namespace OpenRA
|
||||
public readonly string FluentCulture = "en";
|
||||
public readonly bool AllowUnusedFluentMessagesInExternalPackages = true;
|
||||
|
||||
readonly string[] reservedModuleNames =
|
||||
[
|
||||
static readonly FrozenSet<string> ReservedModuleNames = new HashSet<string>
|
||||
{
|
||||
"Include", "Metadata", "FileSystem", "MapFolders", "Rules",
|
||||
"Sequences", "ModelSequences", "Cursors", "Chrome", "Assemblies", "ChromeLayout", "Weapons",
|
||||
"Voices", "Notifications", "Music", "FluentMessages", "TileSets", "ChromeMetrics", "Missions", "Hotkeys",
|
||||
"ServerTraits", "LoadScreen", "DefaultOrderGenerator", "SupportsMapsFrom", "SoundFormats", "SpriteFormats", "VideoFormats",
|
||||
"RequiresMods", "PackageFormats", "AllowUnusedFluentMessagesInExternalPackages", "FontSheetSize", "CursorSheetSize"
|
||||
];
|
||||
}.ToFrozenSet();
|
||||
|
||||
readonly TypeDictionary modules = [];
|
||||
readonly Dictionary<string, MiniYaml> yaml;
|
||||
@@ -165,25 +167,25 @@ namespace OpenRA
|
||||
if (yaml.TryGetValue("SupportsMapsFrom", out var entry))
|
||||
compat.AddRange(entry.Value.Split(',').Select(c => c.Trim()));
|
||||
|
||||
MapCompatibility = compat.ToArray();
|
||||
MapCompatibility = compat.ToImmutableArray();
|
||||
|
||||
if (yaml.TryGetValue("DefaultOrderGenerator", out entry))
|
||||
DefaultOrderGenerator = entry.Value;
|
||||
|
||||
if (yaml.TryGetValue("Assemblies", out entry))
|
||||
Assemblies = FieldLoader.GetValue<string[]>("Assemblies", entry.Value);
|
||||
Assemblies = FieldLoader.GetValue<ImmutableArray<string>>("Assemblies", entry.Value);
|
||||
|
||||
if (yaml.TryGetValue("PackageFormats", out entry))
|
||||
PackageFormats = FieldLoader.GetValue<string[]>("PackageFormats", entry.Value);
|
||||
PackageFormats = FieldLoader.GetValue<ImmutableArray<string>>("PackageFormats", entry.Value);
|
||||
|
||||
if (yaml.TryGetValue("SoundFormats", out entry))
|
||||
SoundFormats = FieldLoader.GetValue<string[]>("SoundFormats", entry.Value);
|
||||
SoundFormats = FieldLoader.GetValue<ImmutableArray<string>>("SoundFormats", entry.Value);
|
||||
|
||||
if (yaml.TryGetValue("SpriteFormats", out entry))
|
||||
SpriteFormats = FieldLoader.GetValue<string[]>("SpriteFormats", entry.Value);
|
||||
SpriteFormats = FieldLoader.GetValue<ImmutableArray<string>>("SpriteFormats", entry.Value);
|
||||
|
||||
if (yaml.TryGetValue("VideoFormats", out entry))
|
||||
VideoFormats = FieldLoader.GetValue<string[]>("VideoFormats", entry.Value);
|
||||
VideoFormats = FieldLoader.GetValue<ImmutableArray<string>>("VideoFormats", entry.Value);
|
||||
|
||||
if (yaml.TryGetValue("AllowUnusedFluentMessagesInExternalPackages", out entry))
|
||||
AllowUnusedFluentMessagesInExternalPackages =
|
||||
@@ -200,7 +202,7 @@ namespace OpenRA
|
||||
{
|
||||
foreach (var kv in yaml)
|
||||
{
|
||||
if (reservedModuleNames.Contains(kv.Key))
|
||||
if (ReservedModuleNames.Contains(kv.Key))
|
||||
continue;
|
||||
|
||||
var t = oc.FindType(kv.Key);
|
||||
@@ -227,20 +229,20 @@ namespace OpenRA
|
||||
customDataLoaded = true;
|
||||
}
|
||||
|
||||
static string[] YamlList(Dictionary<string, MiniYaml> yaml, string key)
|
||||
static ImmutableArray<string> YamlList(Dictionary<string, MiniYaml> yaml, string key)
|
||||
{
|
||||
if (!yaml.TryGetValue(key, out var value))
|
||||
return [];
|
||||
|
||||
return value.Nodes.Select(n => n.Key).ToArray();
|
||||
return value.Nodes.Select(n => n.Key).ToImmutableArray();
|
||||
}
|
||||
|
||||
static IReadOnlyDictionary<string, string> YamlDictionary(Dictionary<string, MiniYaml> yaml, string key)
|
||||
static FrozenDictionary<string, string> YamlDictionary(Dictionary<string, MiniYaml> yaml, string key)
|
||||
{
|
||||
if (!yaml.TryGetValue(key, out var value))
|
||||
return new Dictionary<string, string>();
|
||||
return FrozenDictionary<string, string>.Empty;
|
||||
|
||||
return value.ToDictionary(my => my.Value);
|
||||
return value.ToDictionary(my => my.Value).ToFrozenDictionary();
|
||||
}
|
||||
|
||||
public bool Contains<T>() where T : IGlobalModData
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
@@ -192,7 +193,7 @@ namespace OpenRA
|
||||
public bool LockPreview;
|
||||
public Rectangle Bounds;
|
||||
public MapVisibility Visibility = MapVisibility.Lobby;
|
||||
public string[] Categories = ["Conquest"];
|
||||
public ImmutableArray<string> Categories = ["Conquest"];
|
||||
|
||||
public Size MapSize { get; private set; }
|
||||
|
||||
|
||||
@@ -117,7 +117,7 @@ namespace OpenRA
|
||||
|
||||
public readonly bool EnableDepthBuffer = false;
|
||||
|
||||
public readonly WVec[] SubCellOffsets =
|
||||
public readonly ImmutableArray<WVec> SubCellOffsets =
|
||||
[
|
||||
new(0, 0, 0), // full cell - index 0
|
||||
new(-299, -256, 0), // top left - index 1
|
||||
@@ -127,9 +127,9 @@ namespace OpenRA
|
||||
new(256, 256, 0), // bottom right - index 5
|
||||
];
|
||||
|
||||
public CellRamp[] Ramps { get; }
|
||||
public ImmutableArray<CellRamp> Ramps { get; }
|
||||
|
||||
internal readonly CVec[][] TilesByDistance;
|
||||
internal readonly ImmutableArray<ImmutableArray<CVec>> TilesByDistance;
|
||||
|
||||
public int TileScale { get; }
|
||||
|
||||
@@ -202,7 +202,7 @@ namespace OpenRA
|
||||
TilesByDistance = CreateTilesByDistance();
|
||||
}
|
||||
|
||||
CVec[][] CreateTilesByDistance()
|
||||
ImmutableArray<ImmutableArray<CVec>> CreateTilesByDistance()
|
||||
{
|
||||
var ts = new List<CVec>[MaximumTileSearchRange + 1];
|
||||
for (var i = 0; i < MaximumTileSearchRange + 1; i++)
|
||||
@@ -238,7 +238,7 @@ namespace OpenRA
|
||||
});
|
||||
}
|
||||
|
||||
return ts.Select(list => list.ToArray()).ToArray();
|
||||
return ts.Select(list => list.ToImmutableArray()).ToImmutableArray();
|
||||
}
|
||||
|
||||
public WVec OffsetOfSubCell(SubCell subCell)
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using OpenRA.Traits;
|
||||
|
||||
@@ -54,7 +55,7 @@ namespace OpenRA
|
||||
Name = "Creeps",
|
||||
Faction = firstFaction,
|
||||
NonCombatant = true,
|
||||
Enemies = Exts.MakeArray(playerCount, i => $"Multi{i}")
|
||||
Enemies = Exts.MakeArray(playerCount, i => $"Multi{i}").ToImmutableArray()
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
@@ -49,10 +50,10 @@ namespace OpenRA
|
||||
{
|
||||
public readonly string title;
|
||||
public readonly string author;
|
||||
public readonly string[] categories;
|
||||
public readonly ImmutableArray<string> categories;
|
||||
public readonly int players;
|
||||
public readonly Rectangle bounds;
|
||||
public readonly short[] spawnpoints = [];
|
||||
public readonly ImmutableArray<short> spawnpoints = [];
|
||||
public readonly MapGridType map_grid_type;
|
||||
public readonly string minimap;
|
||||
public readonly bool downloading;
|
||||
@@ -70,12 +71,12 @@ namespace OpenRA
|
||||
{
|
||||
public int MapFormat;
|
||||
public string Title;
|
||||
public string[] Categories;
|
||||
public ImmutableArray<string> Categories;
|
||||
public string Author;
|
||||
public string TileSet;
|
||||
public MapPlayers Players;
|
||||
public int PlayerCount;
|
||||
public CPos[] SpawnPoints;
|
||||
public ImmutableArray<CPos> SpawnPoints;
|
||||
public MapGridType GridType;
|
||||
public Rectangle Bounds;
|
||||
public Png Preview;
|
||||
@@ -129,9 +130,9 @@ namespace OpenRA
|
||||
{
|
||||
if (FluentMessageDefinitions != null)
|
||||
{
|
||||
var files = Array.Empty<string>();
|
||||
var files = ImmutableArray<string>.Empty;
|
||||
if (FluentMessageDefinitions.Value != null)
|
||||
files = FieldLoader.GetValue<string[]>("value", FluentMessageDefinitions.Value);
|
||||
files = FieldLoader.GetValue<ImmutableArray<string>>("value", FluentMessageDefinitions.Value);
|
||||
|
||||
string text = null;
|
||||
if (FluentMessageDefinitions.Nodes.Length > 0)
|
||||
@@ -157,8 +158,8 @@ namespace OpenRA
|
||||
var files = Enumerable.Empty<string>();
|
||||
if (RuleDefinitions.Value != null)
|
||||
{
|
||||
var mapFiles = FieldLoader.GetValue<string[]>("value", RuleDefinitions.Value);
|
||||
files = files.Append(mapFiles);
|
||||
var mapFiles = FieldLoader.GetValue<ImmutableArray<string>>("value", RuleDefinitions.Value);
|
||||
files = files.Concat(mapFiles);
|
||||
}
|
||||
|
||||
var stringPool = new HashSet<string>(); // Reuse common strings in YAML
|
||||
@@ -196,7 +197,6 @@ namespace OpenRA
|
||||
}
|
||||
}
|
||||
|
||||
static readonly CPos[] NoSpawns = [];
|
||||
readonly object syncRoot = new();
|
||||
readonly MapCache cache;
|
||||
readonly ModData modData;
|
||||
@@ -238,12 +238,12 @@ namespace OpenRA
|
||||
|
||||
public int MapFormat => innerData.MapFormat;
|
||||
public string Title => innerData.Title;
|
||||
public string[] Categories => innerData.Categories;
|
||||
public ImmutableArray<string> Categories => innerData.Categories;
|
||||
public string Author => innerData.Author;
|
||||
public string TileSet => innerData.TileSet;
|
||||
public MapPlayers Players => innerData.Players;
|
||||
public int PlayerCount => innerData.PlayerCount;
|
||||
public CPos[] SpawnPoints => innerData.SpawnPoints;
|
||||
public ImmutableArray<CPos> SpawnPoints => innerData.SpawnPoints;
|
||||
public MapGridType GridType => innerData.GridType;
|
||||
public Rectangle Bounds => innerData.Bounds;
|
||||
public Png Preview => innerData.Preview;
|
||||
@@ -341,7 +341,7 @@ namespace OpenRA
|
||||
TileSet = "unknown",
|
||||
Players = null,
|
||||
PlayerCount = 0,
|
||||
SpawnPoints = NoSpawns,
|
||||
SpawnPoints = [],
|
||||
GridType = gridType,
|
||||
Bounds = Rectangle.Empty,
|
||||
Preview = null,
|
||||
@@ -397,7 +397,7 @@ namespace OpenRA
|
||||
newData.Title = temp.Value;
|
||||
|
||||
if (yaml.TryGetValue("Categories", out temp))
|
||||
newData.Categories = FieldLoader.GetValue<string[]>("Categories", temp.Value);
|
||||
newData.Categories = FieldLoader.GetValue<ImmutableArray<string>>("Categories", temp.Value);
|
||||
|
||||
if (yaml.TryGetValue("Tileset", out temp))
|
||||
newData.TileSet = temp.Value;
|
||||
@@ -433,7 +433,7 @@ namespace OpenRA
|
||||
spawns.Add(s.Get<LocationInit>().Value);
|
||||
}
|
||||
|
||||
newData.SpawnPoints = spawns.ToArray();
|
||||
newData.SpawnPoints = spawns.ToImmutableArray();
|
||||
}
|
||||
else
|
||||
newData.SpawnPoints = [];
|
||||
@@ -526,7 +526,7 @@ namespace OpenRA
|
||||
var spawns = new CPos[r.spawnpoints.Length / 2];
|
||||
for (var j = 0; j < r.spawnpoints.Length; j += 2)
|
||||
spawns[j / 2] = new CPos(r.spawnpoints[j], r.spawnpoints[j + 1]);
|
||||
newData.SpawnPoints = spawns;
|
||||
newData.SpawnPoints = spawns.ToImmutableArray();
|
||||
newData.GridType = r.map_grid_type;
|
||||
if (cache.LoadPreviewImages)
|
||||
{
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Immutable;
|
||||
using OpenRA.Primitives;
|
||||
|
||||
namespace OpenRA
|
||||
@@ -53,8 +54,8 @@ namespace OpenRA
|
||||
public bool LockHandicap = false;
|
||||
public int Handicap = 0;
|
||||
|
||||
public string[] Allies = [];
|
||||
public string[] Enemies = [];
|
||||
public ImmutableArray<string> Allies = [];
|
||||
public ImmutableArray<string> Enemies = [];
|
||||
|
||||
public PlayerReference() { }
|
||||
public PlayerReference(MiniYaml my) { FieldLoader.Load(this, my); }
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using OpenRA.FileSystem;
|
||||
using OpenRA.Primitives;
|
||||
using OpenRA.Support;
|
||||
@@ -27,14 +28,14 @@ namespace OpenRA
|
||||
string Id { get; }
|
||||
string Name { get; }
|
||||
Size TileSize { get; }
|
||||
TerrainTypeInfo[] TerrainTypes { get; }
|
||||
ImmutableArray<TerrainTypeInfo> TerrainTypes { get; }
|
||||
TerrainTileInfo GetTerrainInfo(TerrainTile r);
|
||||
bool TryGetTerrainInfo(TerrainTile r, out TerrainTileInfo info);
|
||||
byte GetTerrainIndex(string type);
|
||||
byte GetTerrainIndex(TerrainTile r);
|
||||
TerrainTile DefaultTerrainTile { get; }
|
||||
|
||||
Color[] HeightDebugColors { get; }
|
||||
ImmutableArray<Color> HeightDebugColors { get; }
|
||||
IEnumerable<Color> RestrictedPlayerColors { get; }
|
||||
float MinHeightColorBrightness { get; }
|
||||
float MaxHeightColorBrightness { get; }
|
||||
@@ -62,7 +63,7 @@ namespace OpenRA
|
||||
{
|
||||
public readonly string Type;
|
||||
public readonly BitSet<TargetableType> TargetTypes;
|
||||
public readonly HashSet<string> AcceptsSmudgeType = [];
|
||||
public readonly ImmutableArray<string> AcceptsSmudgeType = [];
|
||||
public readonly Color Color;
|
||||
public readonly bool RestrictPlayerColor = false;
|
||||
|
||||
|
||||
@@ -678,8 +678,8 @@ namespace OpenRA
|
||||
{
|
||||
if (mapRules != null && mapRules.Value != null)
|
||||
{
|
||||
var mapFiles = FieldLoader.GetValue<string[]>("value", mapRules.Value);
|
||||
files = files.Append(mapFiles);
|
||||
var mapFiles = FieldLoader.GetValue<ImmutableArray<string>>("value", mapRules.Value);
|
||||
files = files.Concat(mapFiles);
|
||||
}
|
||||
|
||||
var stringPool = new HashSet<string>(); // Reuse common strings in YAML
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using Linguini.Shared.Types.Bundle;
|
||||
|
||||
namespace OpenRA.Network
|
||||
@@ -55,31 +56,32 @@ namespace OpenRA.Network
|
||||
public readonly string Key = string.Empty;
|
||||
|
||||
[FieldLoader.LoadUsing(nameof(LoadArguments))]
|
||||
public readonly object[] Arguments;
|
||||
public readonly ImmutableArray<object> Arguments;
|
||||
|
||||
static object LoadArguments(MiniYaml yaml)
|
||||
{
|
||||
var arguments = new List<object>();
|
||||
var argumentsNode = yaml.NodeWithKeyOrDefault("Arguments");
|
||||
if (argumentsNode != null)
|
||||
{
|
||||
foreach (var argumentNode in argumentsNode.Value.Nodes)
|
||||
{
|
||||
var argument = FieldLoader.Load<FluentArgument>(argumentNode.Value);
|
||||
arguments.Add(argument.Key);
|
||||
if (argument.Type == FluentArgument.FluentArgumentType.Number)
|
||||
{
|
||||
if (!double.TryParse(argument.Value, out var number))
|
||||
Log.Write("debug", $"Failed to parse {argument.Value}");
|
||||
|
||||
arguments.Add(number);
|
||||
}
|
||||
else
|
||||
arguments.Add(argument.Value);
|
||||
if (argumentsNode == null)
|
||||
return ImmutableArray<object>.Empty;
|
||||
|
||||
var arguments = new List<object>(argumentsNode.Value.Nodes.Length * 2);
|
||||
foreach (var argumentNode in argumentsNode.Value.Nodes)
|
||||
{
|
||||
var argument = FieldLoader.Load<FluentArgument>(argumentNode.Value);
|
||||
arguments.Add(argument.Key);
|
||||
if (argument.Type == FluentArgument.FluentArgumentType.Number)
|
||||
{
|
||||
if (!double.TryParse(argument.Value, out var number))
|
||||
Log.Write("debug", $"Failed to parse {argument.Value}");
|
||||
|
||||
arguments.Add(number);
|
||||
}
|
||||
else
|
||||
arguments.Add(argument.Value);
|
||||
}
|
||||
|
||||
return arguments.ToArray();
|
||||
return arguments.ToImmutableArray();
|
||||
}
|
||||
|
||||
public FluentMessage(MiniYaml yaml)
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Frozen;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using OpenRA.Primitives;
|
||||
@@ -47,7 +49,7 @@ namespace OpenRA.Network
|
||||
|
||||
public class GameServer
|
||||
{
|
||||
static readonly string[] SerializeFields =
|
||||
static readonly ImmutableArray<string> SerializeFields =
|
||||
[
|
||||
|
||||
// Server information
|
||||
@@ -131,10 +133,10 @@ namespace OpenRA.Network
|
||||
public readonly bool IsJoinable = false;
|
||||
|
||||
[FieldLoader.LoadUsing(nameof(LoadClients))]
|
||||
public readonly GameClient[] Clients;
|
||||
public readonly ImmutableArray<GameClient> Clients;
|
||||
|
||||
/// <summary>The list of spawnpoints that are disabled for this game.</summary>
|
||||
public readonly int[] DisabledSpawnPoints = [];
|
||||
public readonly FrozenSet<int> DisabledSpawnPoints = FrozenSet<int>.Empty;
|
||||
|
||||
public string ModLabel => $"{ModTitle} ({Version})";
|
||||
|
||||
@@ -150,7 +152,7 @@ namespace OpenRA.Network
|
||||
clients.Add(FieldLoader.Load<GameClient>(client.Value));
|
||||
}
|
||||
|
||||
return clients.ToArray();
|
||||
return clients.ToImmutableArray();
|
||||
}
|
||||
|
||||
public GameServer(MiniYaml yaml)
|
||||
@@ -227,9 +229,9 @@ namespace OpenRA.Network
|
||||
ModWebsite = manifest.Metadata.Website;
|
||||
ModIcon32 = manifest.Metadata.WebIcon32;
|
||||
Protected = !string.IsNullOrEmpty(server.Settings.Password);
|
||||
Authentication = server.Settings.RequireAuthentication || server.Settings.ProfileIDWhitelist.Length > 0;
|
||||
Clients = server.LobbyInfo.Clients.Select(c => new GameClient(c)).ToArray();
|
||||
DisabledSpawnPoints = server.LobbyInfo.DisabledSpawnPoints?.ToArray() ?? [];
|
||||
Authentication = server.Settings.RequireAuthentication || server.Settings.ProfileIDWhitelist.Count > 0;
|
||||
Clients = server.LobbyInfo.Clients.Select(c => new GameClient(c)).ToImmutableArray();
|
||||
DisabledSpawnPoints = server.LobbyInfo.DisabledSpawnPoints?.ToFrozenSet() ?? FrozenSet<int>.Empty;
|
||||
}
|
||||
|
||||
public string ToPOSTData(bool lanGame)
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Frozen;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
@@ -40,7 +41,7 @@ namespace OpenRA.Network
|
||||
public bool AuthenticationFailed = false;
|
||||
|
||||
// The default null means "no map restriction" while an empty set means "all maps restricted"
|
||||
public HashSet<string> ServerMapPool = null;
|
||||
public FrozenSet<string> ServerMapPool = null;
|
||||
|
||||
public int NetFrameNumber { get; private set; }
|
||||
public int LocalFrameNumber;
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Frozen;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.Server;
|
||||
@@ -67,11 +68,11 @@ namespace OpenRA.Network
|
||||
{
|
||||
var message = new FluentMessage(node.Value);
|
||||
if (message.Key == Joined)
|
||||
TextNotificationsManager.AddPlayerJoinedLine(message.Key, message.Arguments);
|
||||
TextNotificationsManager.AddPlayerJoinedLine(message.Key, message.Arguments.ToArray());
|
||||
else if (message.Key == Left)
|
||||
TextNotificationsManager.AddPlayerLeftLine(message.Key, message.Arguments);
|
||||
TextNotificationsManager.AddPlayerLeftLine(message.Key, message.Arguments.ToArray());
|
||||
else
|
||||
TextNotificationsManager.AddSystemLine(message.Key, message.Arguments);
|
||||
TextNotificationsManager.AddSystemLine(message.Key, message.Arguments.ToArray());
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -385,7 +386,7 @@ namespace OpenRA.Network
|
||||
|
||||
case "SyncMapPool":
|
||||
{
|
||||
orderManager.ServerMapPool = FieldLoader.GetValue<HashSet<string>>("SyncMapPool", order.TargetString);
|
||||
orderManager.ServerMapPool = FieldLoader.GetValue<FrozenSet<string>>("SyncMapPool", order.TargetString);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
|
||||
namespace OpenRA.Primitives
|
||||
@@ -19,7 +20,7 @@ namespace OpenRA.Primitives
|
||||
public static readonly Polygon Empty = new(Rectangle.Empty);
|
||||
|
||||
public readonly Rectangle BoundingRect;
|
||||
public readonly int2[] Vertices;
|
||||
public readonly ImmutableArray<int2> Vertices;
|
||||
readonly bool isRectangle;
|
||||
|
||||
public Polygon(Rectangle bounds)
|
||||
@@ -29,7 +30,7 @@ namespace OpenRA.Primitives
|
||||
isRectangle = true;
|
||||
}
|
||||
|
||||
public Polygon(int2[] vertices)
|
||||
public Polygon(ImmutableArray<int2> vertices)
|
||||
{
|
||||
if (vertices != null && vertices.Length > 0)
|
||||
{
|
||||
@@ -53,7 +54,7 @@ namespace OpenRA.Primitives
|
||||
{
|
||||
isRectangle = true;
|
||||
BoundingRect = Rectangle.Empty;
|
||||
Vertices = Exts.MakeArray(4, _ => int2.Zero);
|
||||
Vertices = Exts.MakeArray(4, _ => int2.Zero).ToImmutableArray();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Frozen;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
@@ -132,7 +133,7 @@ namespace OpenRA.Server
|
||||
public MapPreview Map;
|
||||
public readonly MapStatusCache MapStatusCache;
|
||||
public GameSave GameSave;
|
||||
public HashSet<string> MapPool;
|
||||
public FrozenSet<string> MapPool;
|
||||
|
||||
// Default to the next frame for ServerType.Local - MP servers take the value from the selected GameSpeed.
|
||||
public int OrderLatency = 1;
|
||||
@@ -661,9 +662,9 @@ namespace OpenRA.Server
|
||||
|
||||
events.Add(new CallbackEvent(() =>
|
||||
{
|
||||
var notAuthenticated = Type == ServerType.Dedicated && profile == null && (Settings.RequireAuthentication || Settings.ProfileIDWhitelist.Length > 0);
|
||||
var notAuthenticated = Type == ServerType.Dedicated && profile == null && (Settings.RequireAuthentication || Settings.ProfileIDWhitelist.Count > 0);
|
||||
var blacklisted = Type == ServerType.Dedicated && profile != null && Settings.ProfileIDBlacklist.Contains(profile.ProfileID);
|
||||
var notWhitelisted = Type == ServerType.Dedicated && Settings.ProfileIDWhitelist.Length > 0 &&
|
||||
var notWhitelisted = Type == ServerType.Dedicated && Settings.ProfileIDWhitelist.Count > 0 &&
|
||||
(profile == null || !Settings.ProfileIDWhitelist.Contains(profile.ProfileID));
|
||||
|
||||
if (notAuthenticated)
|
||||
@@ -689,7 +690,7 @@ namespace OpenRA.Server
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Type == ServerType.Dedicated && (Settings.RequireAuthentication || Settings.ProfileIDWhitelist.Length > 0))
|
||||
if (Type == ServerType.Dedicated && (Settings.RequireAuthentication || Settings.ProfileIDWhitelist.Count > 0))
|
||||
{
|
||||
Log.Write("server", $"Rejected connection from {newConn.EndPoint}; Not authenticated.");
|
||||
SendOrderTo(newConn, "ServerError", RequiresAuthentication);
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Frozen;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using OpenRA.Primitives;
|
||||
@@ -69,16 +71,16 @@ namespace OpenRA
|
||||
public string Map = null;
|
||||
|
||||
[Desc("Takes a comma separated list of IP addresses that are not allowed to join.")]
|
||||
public string[] Ban = [];
|
||||
public FrozenSet<string> Ban = FrozenSet<string>.Empty;
|
||||
|
||||
[Desc("For dedicated servers only, allow anonymous clients to join.")]
|
||||
public bool RequireAuthentication = false;
|
||||
|
||||
[Desc("For dedicated servers only, if non-empty, only allow authenticated players with these profile IDs to join.")]
|
||||
public int[] ProfileIDWhitelist = [];
|
||||
public FrozenSet<int> ProfileIDWhitelist = FrozenSet<int>.Empty;
|
||||
|
||||
[Desc("For dedicated servers only, if non-empty, always reject players with these user IDs from joining.")]
|
||||
public int[] ProfileIDBlacklist = [];
|
||||
public FrozenSet<int> ProfileIDBlacklist = FrozenSet<int>.Empty;
|
||||
|
||||
[Desc("For dedicated servers only, controls whether a game can be started with just one human player in the lobby.")]
|
||||
public bool EnableSingleplayer = false;
|
||||
@@ -105,7 +107,7 @@ namespace OpenRA
|
||||
public bool EnableLintChecks = true;
|
||||
|
||||
[Desc("For dedicated servers only, a comma separated list of map uids that are allowed to be used.")]
|
||||
public string[] MapPool = [];
|
||||
public FrozenSet<string> MapPool = FrozenSet<string>.Empty;
|
||||
|
||||
[Desc("Delay in milliseconds before newly joined players can send chat messages.")]
|
||||
public int FloodLimitJoinCooldown = 5000;
|
||||
@@ -251,7 +253,7 @@ namespace OpenRA
|
||||
public string Name = "Commander";
|
||||
public Color Color = Color.FromArgb(200, 32, 32);
|
||||
public string LastServer = "localhost:1234";
|
||||
public Color[] CustomColors = [];
|
||||
public ImmutableArray<Color> CustomColors = [];
|
||||
}
|
||||
|
||||
public class SinglePlayerGameSettings
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.IO;
|
||||
using OpenRA.FileSystem;
|
||||
using OpenRA.GameRules;
|
||||
@@ -165,12 +166,12 @@ namespace OpenRA
|
||||
public ISound PlayLooped(SoundType type, string name) { return Play(type, null, name, true, WPos.Zero, 1f, true); }
|
||||
public ISound PlayLooped(SoundType type, string name, WPos pos) { return Play(type, null, name, false, pos, 1f, true); }
|
||||
|
||||
public ISound Play(SoundType type, string[] names, World world, Player player = null, float volumeModifier = 1f)
|
||||
public ISound Play(SoundType type, ImmutableArray<string> names, World world, Player player = null, float volumeModifier = 1f)
|
||||
{
|
||||
return Play(type, player, names.Random(world.LocalRandom), true, WPos.Zero, volumeModifier);
|
||||
}
|
||||
|
||||
public ISound Play(SoundType type, string[] names, World world, WPos pos, Player player = null, float volumeModifier = 1f)
|
||||
public ISound Play(SoundType type, ImmutableArray<string> names, World world, WPos pos, Player player = null, float volumeModifier = 1f)
|
||||
{
|
||||
return Play(type, player, names.Random(world.LocalRandom), false, pos, volumeModifier);
|
||||
}
|
||||
@@ -399,9 +400,9 @@ namespace OpenRA
|
||||
if (variant != null)
|
||||
{
|
||||
if (rules.Variants.TryGetValue(variant, out var v) && !rules.DisableVariants.Contains(definition))
|
||||
suffix = v[id % v.Length];
|
||||
suffix = v[(int)(id % v.Length)];
|
||||
if (rules.Prefixes.TryGetValue(variant, out var p) && !rules.DisablePrefixes.Contains(definition))
|
||||
prefix = p[id % p.Length];
|
||||
prefix = p[(int)(id % p.Length)];
|
||||
}
|
||||
|
||||
var name = prefix + clip + suffix;
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
@@ -175,7 +176,7 @@ namespace OpenRA.Traits
|
||||
[RequireExplicitImplementation]
|
||||
public interface IStoresResourcesInfo : ITraitInfoInterface
|
||||
{
|
||||
string[] ResourceTypes { get; }
|
||||
ImmutableArray<string> ResourceTypes { get; }
|
||||
}
|
||||
|
||||
public interface IStoresResources
|
||||
@@ -505,12 +506,12 @@ namespace OpenRA.Traits
|
||||
|
||||
public interface IControlGroupsInfo : ITraitInfoInterface
|
||||
{
|
||||
string[] Groups { get; }
|
||||
ImmutableArray<string> Groups { get; }
|
||||
}
|
||||
|
||||
public interface IControlGroups
|
||||
{
|
||||
string[] Groups { get; }
|
||||
ImmutableArray<string> Groups { get; }
|
||||
|
||||
void SelectControlGroup(int group);
|
||||
void CreateControlGroup(int group);
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Frozen;
|
||||
|
||||
namespace OpenRA.Traits
|
||||
{
|
||||
@@ -25,7 +25,7 @@ namespace OpenRA.Traits
|
||||
public readonly string InternalName = null;
|
||||
|
||||
[Desc("Pick a random faction as the player's faction out of this list.")]
|
||||
public readonly HashSet<string> RandomFactionMembers = [];
|
||||
public readonly FrozenSet<string> RandomFactionMembers = FrozenSet<string>.Empty;
|
||||
|
||||
[Desc("The side that the faction belongs to. For example, England belongs to the 'Allies' side.")]
|
||||
public readonly string Side = null;
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using OpenRA.Graphics;
|
||||
@@ -208,8 +209,8 @@ namespace OpenRA.Widgets
|
||||
public IntegerExpression Y;
|
||||
public IntegerExpression Width;
|
||||
public IntegerExpression Height;
|
||||
public string[] Logic = [];
|
||||
public ChromeLogic[] LogicObjects { get; private set; }
|
||||
public ImmutableArray<string> Logic = [];
|
||||
public ImmutableArray<ChromeLogic> LogicObjects { get; private set; }
|
||||
public bool Visible = true;
|
||||
public bool IgnoreMouseOver;
|
||||
public bool IgnoreChildMouseOver;
|
||||
@@ -307,7 +308,7 @@ namespace OpenRA.Widgets
|
||||
args["widget"] = this;
|
||||
|
||||
LogicObjects = Logic.Select(l => Game.ModData.ObjectCreator.CreateObject<ChromeLogic>(l, args))
|
||||
.ToArray();
|
||||
.ToImmutableArray();
|
||||
|
||||
foreach (var logicObject in LogicObjects)
|
||||
Ui.Subscribe(logicObject);
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Frozen;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
@@ -302,7 +303,7 @@ namespace OpenRA
|
||||
foreach (var player in Players)
|
||||
gameInfo.AddPlayer(player, OrderManager.LobbyInfo);
|
||||
|
||||
gameInfo.DisabledSpawnPoints = OrderManager.LobbyInfo.DisabledSpawnPoints;
|
||||
gameInfo.DisabledSpawnPoints = OrderManager.LobbyInfo.DisabledSpawnPoints.ToFrozenSet();
|
||||
|
||||
gameInfo.StartTimeUtc = DateTime.UtcNow;
|
||||
|
||||
|
||||
@@ -9,7 +9,9 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Frozen;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Mods.Common.Graphics;
|
||||
@@ -33,15 +35,15 @@ namespace OpenRA.Mods.Cnc.Graphics
|
||||
public class ClassicTilesetSpecificSpriteSequence : ClassicSpriteSequence
|
||||
{
|
||||
[Desc("Dictionary of <tileset name>: filename to override the Filename key.")]
|
||||
static readonly SpriteSequenceField<Dictionary<string, string>> TilesetFilenames = new(nameof(TilesetFilenames), null);
|
||||
static readonly SpriteSequenceField<FrozenDictionary<string, string>> TilesetFilenames = new(nameof(TilesetFilenames), null);
|
||||
|
||||
[Desc("Dictionary of <tileset name>: <filename pattern> to override the FilenamePattern key.")]
|
||||
static readonly SpriteSequenceField<Dictionary<string, string>> TilesetFilenamesPattern = new(nameof(TilesetFilenamesPattern), null);
|
||||
static readonly SpriteSequenceField<FrozenDictionary<string, string>> TilesetFilenamesPattern = new(nameof(TilesetFilenamesPattern), null);
|
||||
|
||||
public ClassicTilesetSpecificSpriteSequence(SpriteCache cache, ISpriteSequenceLoader loader, string image, string sequence, MiniYaml data, MiniYaml defaults)
|
||||
: base(cache, loader, image, sequence, data, defaults) { }
|
||||
|
||||
protected override IEnumerable<ReservationInfo> ParseFilenames(ModData modData, string tileset, int[] frames, MiniYaml data, MiniYaml defaults)
|
||||
protected override IEnumerable<ReservationInfo> ParseFilenames(ModData modData, string tileset, ImmutableArray<int> frames, MiniYaml data, MiniYaml defaults)
|
||||
{
|
||||
var tilesetFilenamesPatternNode = data.NodeWithKeyOrDefault(TilesetFilenamesPattern.Key) ?? defaults.NodeWithKeyOrDefault(TilesetFilenamesPattern.Key);
|
||||
if (tilesetFilenamesPatternNode != null)
|
||||
@@ -71,7 +73,7 @@ namespace OpenRA.Mods.Cnc.Graphics
|
||||
return base.ParseFilenames(modData, tileset, frames, data, defaults);
|
||||
}
|
||||
|
||||
protected override IEnumerable<ReservationInfo> ParseCombineFilenames(ModData modData, string tileset, int[] frames, MiniYaml data)
|
||||
protected override IEnumerable<ReservationInfo> ParseCombineFilenames(ModData modData, string tileset, ImmutableArray<int> frames, MiniYaml data)
|
||||
{
|
||||
var node = data.NodeWithKeyOrDefault(TilesetFilenames.Key);
|
||||
if (node != null)
|
||||
@@ -83,7 +85,7 @@ namespace OpenRA.Mods.Cnc.Graphics
|
||||
{
|
||||
var subStart = LoadField("Start", 0, data);
|
||||
var subLength = LoadField("Length", 1, data);
|
||||
frames = Exts.MakeArray(subLength, i => subStart + i);
|
||||
frames = Exts.MakeArray(subLength, i => subStart + i).ToImmutableArray();
|
||||
}
|
||||
|
||||
return [new ReservationInfo(tilesetNode.Value.Value, frames, frames, tilesetNode.Location)];
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Mods.Cnc.Traits;
|
||||
using OpenRA.Mods.Common.Graphics;
|
||||
@@ -22,8 +23,8 @@ namespace OpenRA.Mods.Cnc.Graphics
|
||||
readonly ModelRenderer renderer;
|
||||
readonly ModelAnimation[] components;
|
||||
readonly float scale;
|
||||
readonly float[] lightAmbientColor;
|
||||
readonly float[] lightDiffuseColor;
|
||||
readonly ImmutableArray<float> lightAmbientColor;
|
||||
readonly ImmutableArray<float> lightDiffuseColor;
|
||||
readonly WRot lightSource;
|
||||
readonly WRot camera;
|
||||
readonly PaletteReference colorPalette;
|
||||
@@ -33,7 +34,7 @@ namespace OpenRA.Mods.Cnc.Graphics
|
||||
readonly int zOffset;
|
||||
|
||||
public ModelPreview(ModelRenderer renderer, ModelAnimation[] components, in WVec offset, int zOffset, float scale, WAngle lightPitch, WAngle lightYaw,
|
||||
float[] lightAmbientColor, float[] lightDiffuseColor, WAngle cameraPitch,
|
||||
ImmutableArray<float> lightAmbientColor, ImmutableArray<float> lightDiffuseColor, WAngle cameraPitch,
|
||||
PaletteReference colorPalette, PaletteReference normalsPalette, PaletteReference shadowPalette)
|
||||
{
|
||||
this.renderer = renderer;
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Mods.Cnc.Traits;
|
||||
@@ -24,15 +25,15 @@ namespace OpenRA.Mods.Cnc.Graphics
|
||||
readonly IEnumerable<ModelAnimation> models;
|
||||
readonly WRot camera;
|
||||
readonly WRot lightSource;
|
||||
readonly float[] lightAmbientColor;
|
||||
readonly float[] lightDiffuseColor;
|
||||
readonly ImmutableArray<float> lightAmbientColor;
|
||||
readonly ImmutableArray<float> lightDiffuseColor;
|
||||
readonly PaletteReference normalsPalette;
|
||||
readonly PaletteReference shadowPalette;
|
||||
readonly float scale;
|
||||
|
||||
public ModelRenderable(
|
||||
ModelRenderer renderer, IEnumerable<ModelAnimation> models, WPos pos, int zOffset, in WRot camera, float scale,
|
||||
in WRot lightSource, float[] lightAmbientColor, float[] lightDiffuseColor,
|
||||
in WRot lightSource, ImmutableArray<float> lightAmbientColor, ImmutableArray<float> lightDiffuseColor,
|
||||
PaletteReference color, PaletteReference normals, PaletteReference shadow)
|
||||
: this(renderer, models, pos, zOffset, camera, scale,
|
||||
lightSource, lightAmbientColor, lightDiffuseColor,
|
||||
@@ -42,7 +43,7 @@ namespace OpenRA.Mods.Cnc.Graphics
|
||||
|
||||
public ModelRenderable(
|
||||
ModelRenderer renderer, IEnumerable<ModelAnimation> models, WPos pos, int zOffset, in WRot camera, float scale,
|
||||
in WRot lightSource, float[] lightAmbientColor, float[] lightDiffuseColor,
|
||||
in WRot lightSource, ImmutableArray<float> lightAmbientColor, ImmutableArray<float> lightDiffuseColor,
|
||||
PaletteReference color, PaletteReference normals, PaletteReference shadow,
|
||||
float alpha, in float3 tint, TintModifiers tintModifiers)
|
||||
{
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Mods.Cnc.Traits;
|
||||
@@ -25,15 +26,15 @@ namespace OpenRA.Mods.Cnc.Graphics
|
||||
readonly int2 screenPos;
|
||||
readonly WRot camera;
|
||||
readonly WRot lightSource;
|
||||
readonly float[] lightAmbientColor;
|
||||
readonly float[] lightDiffuseColor;
|
||||
readonly ImmutableArray<float> lightAmbientColor;
|
||||
readonly ImmutableArray<float> lightDiffuseColor;
|
||||
readonly PaletteReference normalsPalette;
|
||||
readonly PaletteReference shadowPalette;
|
||||
readonly float scale;
|
||||
|
||||
public UIModelRenderable(
|
||||
ModelRenderer renderer, IEnumerable<ModelAnimation> models, WPos effectiveWorldPos, int2 screenPos, int zOffset,
|
||||
in WRot camera, float scale, in WRot lightSource, float[] lightAmbientColor, float[] lightDiffuseColor,
|
||||
in WRot camera, float scale, in WRot lightSource, ImmutableArray<float> lightAmbientColor, ImmutableArray<float> lightDiffuseColor,
|
||||
PaletteReference color, PaletteReference normals, PaletteReference shadow)
|
||||
{
|
||||
this.renderer = renderer;
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Frozen;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.Mods.Common.Orders;
|
||||
@@ -87,7 +88,7 @@ namespace OpenRA.Mods.Cnc.Traits
|
||||
[ActorReference(dictionaryReference: LintDictionaryReference.Keys)]
|
||||
[Desc("Conditions to grant when disguised as specified actor.",
|
||||
"A dictionary of [actor id]: [condition].")]
|
||||
public readonly Dictionary<string, string> DisguisedAsConditions = [];
|
||||
public readonly FrozenDictionary<string, string> DisguisedAsConditions = FrozenDictionary<string, string>.Empty;
|
||||
|
||||
[CursorReference]
|
||||
[Desc("Cursor to display when hovering over a valid actor to disguise as.")]
|
||||
|
||||
@@ -9,7 +9,9 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Frozen;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Traits;
|
||||
|
||||
@@ -20,7 +22,7 @@ namespace OpenRA.Mods.Cnc.Traits
|
||||
sealed class LightPaletteRotatorInfo : TraitInfo
|
||||
{
|
||||
[Desc("Palettes this effect should not apply to.")]
|
||||
public readonly HashSet<string> ExcludePalettes = [];
|
||||
public readonly FrozenSet<string> ExcludePalettes = FrozenSet<string>.Empty;
|
||||
|
||||
[Desc("'Speed' at which the effect cycles through palette indices.")]
|
||||
public readonly float TimeStep = .5f;
|
||||
@@ -29,7 +31,7 @@ namespace OpenRA.Mods.Cnc.Traits
|
||||
public readonly int ModifyIndex = 103;
|
||||
|
||||
[Desc("Palette indices to rotate through.")]
|
||||
public readonly int[] RotationIndices = [230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 238, 237, 236, 235, 234, 233, 232, 231];
|
||||
public readonly ImmutableArray<int> RotationIndices = [230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 238, 237, 236, 235, 234, 233, 232, 231];
|
||||
|
||||
public override object Create(ActorInitializer init) { return new LightPaletteRotator(this); }
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Mods.Cnc.Graphics;
|
||||
@@ -52,8 +53,8 @@ namespace OpenRA.Mods.Cnc.Traits.Render
|
||||
|
||||
public readonly WAngle LightPitch = WAngle.FromDegrees(50);
|
||||
public readonly WAngle LightYaw = WAngle.FromDegrees(240);
|
||||
public readonly float[] LightAmbientColor = [0.6f, 0.6f, 0.6f];
|
||||
public readonly float[] LightDiffuseColor = [0.4f, 0.4f, 0.4f];
|
||||
public readonly ImmutableArray<float> LightAmbientColor = [0.6f, 0.6f, 0.6f];
|
||||
public readonly ImmutableArray<float> LightDiffuseColor = [0.4f, 0.4f, 0.4f];
|
||||
|
||||
public override object Create(ActorInitializer init) { return new RenderVoxels(init.Self, this); }
|
||||
|
||||
|
||||
@@ -9,7 +9,9 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Frozen;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Mods.Common;
|
||||
@@ -24,10 +26,10 @@ namespace OpenRA.Mods.Cnc.Traits.Render
|
||||
public class WithCargoInfo : TraitInfo, Requires<CargoInfo>, Requires<BodyOrientationInfo>
|
||||
{
|
||||
[Desc("Cargo position relative to turret or body in (forward, right, up) triples. The default offset should be in the middle of the list.")]
|
||||
public readonly WVec[] LocalOffset = [WVec.Zero];
|
||||
public readonly ImmutableArray<WVec> LocalOffset = [WVec.Zero];
|
||||
|
||||
[Desc("Passenger CargoType to display.")]
|
||||
public readonly HashSet<string> DisplayTypes = [];
|
||||
public readonly FrozenSet<string> DisplayTypes = FrozenSet<string>.Empty;
|
||||
|
||||
public override object Create(ActorInitializer init) { return new WithCargo(init.Self, this); }
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Immutable;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Mods.Common.Traits.Render;
|
||||
using OpenRA.Traits;
|
||||
@@ -18,7 +19,7 @@ namespace OpenRA.Mods.Cnc.Traits.Render
|
||||
public class WithHarvesterSpriteBodyInfo : WithFacingSpriteBodyInfo, Requires<HarvesterInfo>
|
||||
{
|
||||
[Desc("Images switched between depending on fullness of harvester. Overrides RenderSprites.Image.")]
|
||||
public readonly string[] ImageByFullness = [];
|
||||
public readonly ImmutableArray<string> ImageByFullness = [];
|
||||
|
||||
public override object Create(ActorInitializer init) { return new WithHarvesterSpriteBody(init, this); }
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Frozen;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
@@ -19,7 +20,7 @@ namespace OpenRA.Mods.Cnc.Traits.Render
|
||||
{
|
||||
public class WithLandingCraftAnimationInfo : TraitInfo, Requires<IMoveInfo>, Requires<WithSpriteBodyInfo>, Requires<CargoInfo>
|
||||
{
|
||||
public readonly HashSet<string> OpenTerrainTypes = ["Clear"];
|
||||
public readonly FrozenSet<string> OpenTerrainTypes = new HashSet<string> { "Clear" }.ToFrozenSet();
|
||||
|
||||
[SequenceReference]
|
||||
public readonly string OpenSequence = "open";
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Frozen;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using OpenRA.GameRules;
|
||||
using OpenRA.Mods.Cnc.Effects;
|
||||
@@ -26,7 +28,7 @@ namespace OpenRA.Mods.Cnc.Traits
|
||||
[FieldLoader.Require]
|
||||
[Desc("Drop pod unit")]
|
||||
[ActorReference([typeof(AircraftInfo), typeof(FallsToEarthInfo)])]
|
||||
public readonly string[] UnitTypes = null;
|
||||
public readonly ImmutableArray<string> UnitTypes = default;
|
||||
|
||||
[Desc("Number of drop pods spawned.")]
|
||||
public readonly int2 Drops = new(5, 8);
|
||||
@@ -82,7 +84,7 @@ namespace OpenRA.Mods.Cnc.Traits
|
||||
readonly DropPodsPowerInfo info;
|
||||
readonly string[] unitTypes;
|
||||
readonly Dictionary<string, Func<CPos, WPos>> getLaunchLocation = [];
|
||||
readonly Dictionary<string, HashSet<string>> landableTerrainTypes = [];
|
||||
readonly Dictionary<string, FrozenSet<string>> landableTerrainTypes = [];
|
||||
|
||||
public DropPodsPower(Actor self, DropPodsPowerInfo info)
|
||||
: base(self, info)
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Immutable;
|
||||
using OpenRA.Mods.Common.Activities;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Traits;
|
||||
@@ -38,7 +39,7 @@ namespace OpenRA.Mods.Cnc.Traits
|
||||
public readonly int Adjacency = 1;
|
||||
|
||||
[Desc("The range of time (in ticks) until the transformation starts.")]
|
||||
public readonly int[] Delay = [1000, 3000];
|
||||
public readonly ImmutableArray<int> Delay = [1000, 3000];
|
||||
|
||||
public override object Create(ActorInitializer init) { return new TransformsNearResources(init.Self, this); }
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Frozen;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Traits;
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace OpenRA.Mods.Cnc.Traits
|
||||
public readonly short JumpjetTransitionCost = 0;
|
||||
|
||||
[Desc("The terrain types that this actor can transition on. Leave empty to allow any.")]
|
||||
public readonly HashSet<string> JumpjetTransitionTerrainTypes = [];
|
||||
public readonly FrozenSet<string> JumpjetTransitionTerrainTypes = FrozenSet<string>.Empty;
|
||||
|
||||
[Desc("Can this actor transition on slopes?")]
|
||||
public readonly bool JumpjetTransitionOnRamps = true;
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Primitives;
|
||||
@@ -44,8 +45,8 @@ namespace OpenRA.Mods.Cnc.Traits
|
||||
public sealed class ModelRenderer : IDisposable, IRenderer, INotifyActorDisposing
|
||||
{
|
||||
// Static constants
|
||||
static readonly float[] ShadowDiffuse = [0, 0, 0];
|
||||
static readonly float[] ShadowAmbient = [1, 1, 1];
|
||||
static readonly ImmutableArray<float> ShadowDiffuse = [0, 0, 0];
|
||||
static readonly ImmutableArray<float> ShadowAmbient = [1, 1, 1];
|
||||
static readonly float2 SpritePadding = new(2, 2);
|
||||
static readonly float[] ZeroVector = [0, 0, 0, 1];
|
||||
static readonly float[] ZVector = [0, 0, 1, 1];
|
||||
@@ -94,7 +95,7 @@ namespace OpenRA.Mods.Cnc.Traits
|
||||
|
||||
public ModelRenderProxy RenderAsync(
|
||||
WorldRenderer wr, IEnumerable<ModelAnimation> models, in WRot camera, float scale,
|
||||
in WRot groundOrientation, in WRot lightSource, float[] lightAmbientColor, float[] lightDiffuseColor,
|
||||
in WRot groundOrientation, in WRot lightSource, ImmutableArray<float> lightAmbientColor, ImmutableArray<float> lightDiffuseColor,
|
||||
PaletteReference color, PaletteReference normals, PaletteReference shadowPalette)
|
||||
{
|
||||
if (!isInFrame)
|
||||
@@ -281,15 +282,15 @@ namespace OpenRA.Mods.Cnc.Traits
|
||||
ModelRenderData renderData,
|
||||
IModelCache cache,
|
||||
float[] t, float[] lightDirection,
|
||||
float[] ambientLight, float[] diffuseLight,
|
||||
ImmutableArray<float> ambientLight, ImmutableArray<float> diffuseLight,
|
||||
float colorPaletteTextureIndex, float normalsPaletteTextureIndex)
|
||||
{
|
||||
shader.SetTexture("DiffuseTexture", renderData.Sheet.GetTexture());
|
||||
shader.SetVec("Palettes", colorPaletteTextureIndex, normalsPaletteTextureIndex);
|
||||
shader.SetMatrix("TransformMatrix", t);
|
||||
shader.SetVec("LightDirection", lightDirection, 4);
|
||||
shader.SetVec("AmbientLight", ambientLight, 3);
|
||||
shader.SetVec("DiffuseLight", diffuseLight, 3);
|
||||
shader.SetVec("AmbientLight", ambientLight.AsMemory(), 3);
|
||||
shader.SetVec("DiffuseLight", diffuseLight.AsMemory(), 3);
|
||||
|
||||
shader.PrepareRender();
|
||||
renderer.DrawBatch(cache.VertexBuffer, shader, renderData.Start, renderData.Count, PrimitiveType.TriangleList);
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Frozen;
|
||||
using System.Linq;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Traits;
|
||||
@@ -23,7 +23,7 @@ namespace OpenRA.Mods.Cnc.Traits
|
||||
|
||||
[ActorReference]
|
||||
[Desc("Actor types that should be treated as veins for adjacency.")]
|
||||
public readonly HashSet<string> VeinholeActors = [];
|
||||
public readonly FrozenSet<string> VeinholeActors = FrozenSet<string>.Empty;
|
||||
|
||||
public override object Create(ActorInitializer init) { return new TSEditorResourceLayer(init.Self, this); }
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Frozen;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.Graphics;
|
||||
@@ -25,7 +26,7 @@ namespace OpenRA.Mods.Cnc.Traits
|
||||
|
||||
[ActorReference]
|
||||
[Desc("Actor types that should be treated as veins for adjacency.")]
|
||||
public readonly HashSet<string> VeinholeActors = [];
|
||||
public readonly FrozenSet<string> VeinholeActors = FrozenSet<string>.Empty;
|
||||
|
||||
public override object Create(ActorInitializer init) { return new TSResourceLayer(init.Self, this); }
|
||||
}
|
||||
|
||||
@@ -9,7 +9,9 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Frozen;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
@@ -22,16 +24,16 @@ namespace OpenRA.Mods.Cnc.Traits
|
||||
public class TSTiberiumRendererInfo : ResourceRendererInfo
|
||||
{
|
||||
[Desc("Sequences to use for ramp type 1.", "Dictionary of [resource type]: [list of sequences].")]
|
||||
public readonly Dictionary<string, string[]> Ramp1Sequences = [];
|
||||
public readonly FrozenDictionary<string, ImmutableArray<string>> Ramp1Sequences = FrozenDictionary<string, ImmutableArray<string>>.Empty;
|
||||
|
||||
[Desc("Sequences to use for ramp type 2.", "Dictionary of [resource type]: [list of sequences].")]
|
||||
public readonly Dictionary<string, string[]> Ramp2Sequences = [];
|
||||
public readonly FrozenDictionary<string, ImmutableArray<string>> Ramp2Sequences = FrozenDictionary<string, ImmutableArray<string>>.Empty;
|
||||
|
||||
[Desc("Sequences to use for ramp type 3.", "Dictionary of [resource type]: [list of sequences].")]
|
||||
public readonly Dictionary<string, string[]> Ramp3Sequences = [];
|
||||
public readonly FrozenDictionary<string, ImmutableArray<string>> Ramp3Sequences = FrozenDictionary<string, ImmutableArray<string>>.Empty;
|
||||
|
||||
[Desc("Sequences to use for ramp type 4.", "Dictionary of [resource type]: [list of sequences].")]
|
||||
public readonly Dictionary<string, string[]> Ramp4Sequences = [];
|
||||
public readonly FrozenDictionary<string, ImmutableArray<string>> Ramp4Sequences = FrozenDictionary<string, ImmutableArray<string>>.Empty;
|
||||
|
||||
public override object Create(ActorInitializer init) { return new TSTiberiumRenderer(init.Self, this); }
|
||||
}
|
||||
@@ -52,7 +54,7 @@ namespace OpenRA.Mods.Cnc.Traits
|
||||
world = self.World;
|
||||
}
|
||||
|
||||
void LoadVariants(Dictionary<string, string[]> rampSequences, Dictionary<string, Dictionary<string, ISpriteSequence>> rampVariants)
|
||||
void LoadVariants(FrozenDictionary<string, ImmutableArray<string>> rampSequences, Dictionary<string, Dictionary<string, ISpriteSequence>> rampVariants)
|
||||
{
|
||||
var sequences = world.Map.Sequences;
|
||||
foreach (var kv in rampSequences)
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Frozen;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.Graphics;
|
||||
@@ -45,7 +46,7 @@ namespace OpenRA.Mods.Cnc.Traits
|
||||
|
||||
[ActorReference]
|
||||
[Desc("Actor types that should be treated as veins for adjacency.")]
|
||||
public readonly HashSet<string> VeinholeActors = [];
|
||||
public readonly FrozenSet<string> VeinholeActors = FrozenSet<string>.Empty;
|
||||
|
||||
void IMapPreviewSignatureInfo.PopulateMapPreviewSignatureCells(Map map, ActorInfo ai, ActorReference s, List<(MPos Uv, Color Color)> destinationBuffer)
|
||||
{
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Frozen;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Mods.Common;
|
||||
@@ -26,13 +28,13 @@ namespace OpenRA.Mods.Cnc.Traits
|
||||
{
|
||||
[FieldLoader.Require]
|
||||
[Desc("Resource types to animate.")]
|
||||
public readonly HashSet<string> Types = null;
|
||||
public readonly FrozenSet<string> Types = null;
|
||||
|
||||
[Desc("The percentage of resource cells to play the animation on.", "Use two values to randomize between them.")]
|
||||
public readonly int[] Ratio = [1, 10];
|
||||
public readonly ImmutableArray<int> Ratio = [1, 10];
|
||||
|
||||
[Desc("Tick interval between two animation spawning.", "Use two values to randomize between them.")]
|
||||
public readonly int[] Interval = [200, 500];
|
||||
public readonly ImmutableArray<int> Interval = [200, 500];
|
||||
|
||||
[FieldLoader.Require]
|
||||
[Desc("Animation image.")]
|
||||
@@ -40,7 +42,7 @@ namespace OpenRA.Mods.Cnc.Traits
|
||||
|
||||
[SequenceReference(nameof(Image))]
|
||||
[Desc("Randomly select one of these sequences to render.")]
|
||||
public readonly string[] Sequences = ["idle"];
|
||||
public readonly ImmutableArray<string> Sequences = ["idle"];
|
||||
|
||||
[PaletteReference]
|
||||
[Desc("Animation palette.")]
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@@ -394,8 +395,8 @@ namespace OpenRA.Mods.Cnc.UtilityCommands
|
||||
switch (s.Key)
|
||||
{
|
||||
case "Allies":
|
||||
pr.Allies = s.Value.Split(',').Intersect(players).Except(neutral).ToArray();
|
||||
pr.Enemies = s.Value.Split(',').SymmetricDifference(players).Except(neutral).ToArray();
|
||||
pr.Allies = s.Value.Split(',').Intersect(players).Except(neutral).ToImmutableArray();
|
||||
pr.Enemies = s.Value.Split(',').SymmetricDifference(players).Except(neutral).ToImmutableArray();
|
||||
break;
|
||||
default:
|
||||
Console.WriteLine("Ignoring unknown {0}={1} for player {2}", s.Key, s.Value, pr.Name);
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using OpenRA.Graphics;
|
||||
@@ -50,7 +51,7 @@ namespace OpenRA.Mods.Cnc.UtilityCommands
|
||||
Game.ModData = destModData;
|
||||
var destPaletteInfo = destModData.DefaultRules.Actors[SystemActors.Player].TraitInfo<PlayerColorPaletteInfo>();
|
||||
var destRemapIndex = destPaletteInfo.RemapIndex;
|
||||
var shadowIndex = Array.Empty<int>();
|
||||
var shadowIndex = ImmutableArray<int>.Empty;
|
||||
|
||||
// the remap range is always 16 entries, but their location and order changes
|
||||
for (var i = 0; i < 16; i++)
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Immutable;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Mods.Cnc.Graphics;
|
||||
using OpenRA.Mods.Cnc.Traits;
|
||||
@@ -26,8 +27,8 @@ namespace OpenRA.Mods.Cnc.Widgets
|
||||
public float Scale = 10f;
|
||||
public int LightPitch = 142;
|
||||
public int LightYaw = 682;
|
||||
public float[] LightAmbientColor = [0.6f, 0.6f, 0.6f];
|
||||
public float[] LightDiffuseColor = [0.4f, 0.4f, 0.4f];
|
||||
public ImmutableArray<float> LightAmbientColor = [0.6f, 0.6f, 0.6f];
|
||||
public ImmutableArray<float> LightDiffuseColor = [0.4f, 0.4f, 0.4f];
|
||||
public WRot Rotation = WRot.None;
|
||||
public WAngle CameraAngle = WAngle.FromDegrees(40);
|
||||
|
||||
@@ -35,8 +36,8 @@ namespace OpenRA.Mods.Cnc.Widgets
|
||||
public Func<string> GetPlayerPalette;
|
||||
public Func<string> GetNormalsPalette;
|
||||
public Func<string> GetShadowPalette;
|
||||
public Func<float[]> GetLightAmbientColor;
|
||||
public Func<float[]> GetLightDiffuseColor;
|
||||
public Func<ImmutableArray<float>> GetLightAmbientColor;
|
||||
public Func<ImmutableArray<float>> GetLightDiffuseColor;
|
||||
public Func<float> GetScale;
|
||||
public Func<int> GetLightPitch;
|
||||
public Func<int> GetLightYaw;
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Frozen;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
@@ -22,7 +23,7 @@ namespace OpenRA.Mods.Common
|
||||
|
||||
public static class AIUtils
|
||||
{
|
||||
public static bool IsAreaAvailable<T>(World world, Player player, Map map, int radius, HashSet<string> terrainTypes)
|
||||
public static bool IsAreaAvailable<T>(World world, Player player, Map map, int radius, FrozenSet<string> terrainTypes)
|
||||
{
|
||||
var cells = world.ActorsHavingTrait<T>().Where(a => a.Owner == player);
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using OpenRA.Activities;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Mods.Common.Traits.Render;
|
||||
@@ -23,7 +24,7 @@ namespace OpenRA.Mods.Common.Activities
|
||||
public readonly string ToActor;
|
||||
public CVec Offset = CVec.Zero;
|
||||
public WAngle Facing = new(384);
|
||||
public string[] Sounds = [];
|
||||
public ImmutableArray<string> Sounds = [];
|
||||
public string Notification = null;
|
||||
public string TextNotification = null;
|
||||
public int ForceHealthPercentage = 0;
|
||||
|
||||
@@ -9,13 +9,15 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Immutable;
|
||||
|
||||
namespace OpenRA
|
||||
{
|
||||
public class AssetBrowser : IGlobalModData
|
||||
{
|
||||
public readonly string[] SpriteExtensions = [];
|
||||
public readonly string[] ModelExtensions = [];
|
||||
public readonly string[] AudioExtensions = [];
|
||||
public readonly string[] VideoExtensions = [];
|
||||
public readonly ImmutableArray<string> SpriteExtensions = [];
|
||||
public readonly ImmutableArray<string> ModelExtensions = [];
|
||||
public readonly ImmutableArray<string> AudioExtensions = [];
|
||||
public readonly ImmutableArray<string> VideoExtensions = [];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Frozen;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
@@ -234,13 +235,13 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
public string Text { get; }
|
||||
|
||||
readonly MarkerLayerOverlay markerLayerOverlay;
|
||||
readonly ImmutableDictionary<int, ImmutableArray<CPos>> tiles;
|
||||
readonly FrozenDictionary<int, ImmutableArray<CPos>> tiles;
|
||||
|
||||
public ClearAllMarkerTilesEditorAction(
|
||||
MarkerLayerOverlay markerLayerOverlay)
|
||||
{
|
||||
this.markerLayerOverlay = markerLayerOverlay;
|
||||
tiles = markerLayerOverlay.Tiles.ToImmutableDictionary(t => t.Key, t => t.Value.ToImmutableArray());
|
||||
tiles = markerLayerOverlay.Tiles.ToFrozenDictionary(t => t.Key, t => t.Value.ToImmutableArray());
|
||||
var allTilesCount = tiles.Values.Sum(x => x.Length);
|
||||
|
||||
Text = FluentProvider.GetMessage(ClearedAllMarkerTiles, "count", allTilesCount);
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using OpenRA.Effects;
|
||||
using OpenRA.Graphics;
|
||||
|
||||
@@ -17,8 +18,8 @@ namespace OpenRA.Mods.Common.Effects
|
||||
{
|
||||
public sealed class FloatingSprite : IEffect, ISpatiallyPartitionable
|
||||
{
|
||||
readonly WDist[] speed;
|
||||
readonly WDist[] gravity;
|
||||
readonly ImmutableArray<WDist> speed;
|
||||
readonly ImmutableArray<WDist> gravity;
|
||||
readonly Animation anim;
|
||||
|
||||
readonly bool visibleThroughFog;
|
||||
@@ -32,8 +33,8 @@ namespace OpenRA.Mods.Common.Effects
|
||||
int ticks;
|
||||
WAngle facing;
|
||||
|
||||
public FloatingSprite(Actor emitter, string image, string[] sequences, string palette, bool isPlayerPalette,
|
||||
int[] lifetime, WDist[] speed, WDist[] gravity, int turnRate, int randomRate, WPos pos, WAngle facing,
|
||||
public FloatingSprite(Actor emitter, string image, ImmutableArray<string> sequences, string palette, bool isPlayerPalette,
|
||||
ImmutableArray<int> lifetime, ImmutableArray<WDist> speed, ImmutableArray<WDist> gravity, int turnRate, int randomRate, WPos pos, WAngle facing,
|
||||
bool visibleThroughFog = false)
|
||||
{
|
||||
var world = emitter.World;
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
|
||||
namespace OpenRA.Mods.Common.FileSystem
|
||||
{
|
||||
@@ -20,18 +21,52 @@ namespace OpenRA.Mods.Common.FileSystem
|
||||
[Desc("Mod to use for content installation.")]
|
||||
public readonly string ContentInstallerMod = null;
|
||||
|
||||
[FieldLoader.Require]
|
||||
[Desc("A list of mod-provided packages. Anything required to display the initial load screen must be listed here.")]
|
||||
public readonly Dictionary<string, string> SystemPackages = null;
|
||||
[FieldLoader.LoadUsing(nameof(LoadSystemPackages))]
|
||||
public readonly ImmutableArray<KeyValuePair<string, string>> SystemPackages = default;
|
||||
|
||||
[Desc("A list of user-installed packages. If missing (and not marked as optional), these will trigger the content installer.")]
|
||||
public readonly Dictionary<string, string> ContentPackages = null;
|
||||
[FieldLoader.LoadUsing(nameof(LoadContentPackages))]
|
||||
public readonly ImmutableArray<KeyValuePair<string, string>> ContentPackages = default;
|
||||
|
||||
[Desc("Files that aren't mounted as packages, but still need to trigger the content installer if missing.")]
|
||||
public readonly Dictionary<string, string> RequiredContentFiles = null;
|
||||
[FieldLoader.LoadUsing(nameof(LoadRequiredContentFiles))]
|
||||
public readonly ImmutableArray<KeyValuePair<string, string>> RequiredContentFiles = default;
|
||||
|
||||
bool isContentAvailable = true;
|
||||
|
||||
static object LoadSystemPackages(MiniYaml yaml)
|
||||
{
|
||||
return LoadPackages(yaml, nameof(SystemPackages), true);
|
||||
}
|
||||
|
||||
static object LoadContentPackages(MiniYaml yaml)
|
||||
{
|
||||
return LoadPackages(yaml, nameof(ContentPackages), false);
|
||||
}
|
||||
|
||||
static object LoadRequiredContentFiles(MiniYaml yaml)
|
||||
{
|
||||
return LoadPackages(yaml, nameof(RequiredContentFiles), false);
|
||||
}
|
||||
|
||||
static object LoadPackages(MiniYaml yaml, string key, bool required)
|
||||
{
|
||||
var packageNode = yaml.NodeWithKeyOrDefault(key);
|
||||
if (packageNode == null)
|
||||
{
|
||||
if (required)
|
||||
throw new FieldLoader.MissingFieldsException([key]);
|
||||
return default(ImmutableArray<KeyValuePair<string, string>>);
|
||||
}
|
||||
|
||||
var packages = new List<KeyValuePair<string, string>>(packageNode.Value.Nodes.Length);
|
||||
foreach (var node in packageNode.Value.Nodes)
|
||||
packages.Add(KeyValuePair.Create(node.Key, node.Value.Value));
|
||||
|
||||
return packages.ToImmutableArray();
|
||||
}
|
||||
|
||||
public void Mount(OpenRA.FileSystem.FileSystem fileSystem, ObjectCreator objectCreator)
|
||||
{
|
||||
foreach (var kv in SystemPackages)
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.FileSystem
|
||||
@@ -23,7 +24,21 @@ namespace OpenRA.Mods.Common.FileSystem
|
||||
|
||||
public class DefaultFileSystemLoader : IFileSystemLoader
|
||||
{
|
||||
public readonly Dictionary<string, string> Packages = null;
|
||||
[FieldLoader.LoadUsing(nameof(LoadPackages))]
|
||||
public readonly ImmutableArray<KeyValuePair<string, string>> Packages = default;
|
||||
|
||||
static object LoadPackages(MiniYaml yaml)
|
||||
{
|
||||
var packageNode = yaml.NodeWithKeyOrDefault(nameof(Packages));
|
||||
if (packageNode == null)
|
||||
return default(ImmutableArray<KeyValuePair<string, string>>);
|
||||
|
||||
var packages = new List<KeyValuePair<string, string>>(packageNode.Value.Nodes.Length);
|
||||
foreach (var node in packageNode.Value.Nodes)
|
||||
packages.Add(KeyValuePair.Create(node.Key, node.Value.Value));
|
||||
|
||||
return packages.ToImmutableArray();
|
||||
}
|
||||
|
||||
public void Mount(OpenRA.FileSystem.FileSystem fileSystem, ObjectCreator objectCreator)
|
||||
{
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
@@ -87,20 +88,17 @@ namespace OpenRA.Mods.Common.Graphics
|
||||
public bool FlipY;
|
||||
public float ZRamp;
|
||||
public BlendMode BlendMode;
|
||||
public int[] Frames;
|
||||
public ImmutableArray<int> Frames;
|
||||
}
|
||||
|
||||
protected readonly struct ReservationInfo
|
||||
{
|
||||
public readonly string Filename;
|
||||
public readonly List<int> LoadFrames;
|
||||
public readonly int[] Frames;
|
||||
public readonly ImmutableArray<int> LoadFrames;
|
||||
public readonly ImmutableArray<int> Frames;
|
||||
public readonly MiniYamlNode.SourceLocation Location;
|
||||
|
||||
public ReservationInfo(string filename, int[] loadFrames, int[] frames, MiniYamlNode.SourceLocation location)
|
||||
: this(filename, loadFrames?.ToList(), frames, location) { }
|
||||
|
||||
public ReservationInfo(string filename, List<int> loadFrames, int[] frames, MiniYamlNode.SourceLocation location)
|
||||
public ReservationInfo(string filename, ImmutableArray<int> loadFrames, ImmutableArray<int> frames, MiniYamlNode.SourceLocation location)
|
||||
{
|
||||
Filename = filename;
|
||||
LoadFrames = loadFrames;
|
||||
@@ -150,7 +148,7 @@ namespace OpenRA.Mods.Common.Graphics
|
||||
protected static readonly SpriteSequenceField<WDist> ShadowZOffset = new(nameof(ShadowZOffset), new WDist(-5));
|
||||
|
||||
[Desc("The individual frames to play instead of going through them sequentially from the `Start`.")]
|
||||
protected static readonly SpriteSequenceField<int[]> Frames = new(nameof(Frames), null);
|
||||
protected static readonly SpriteSequenceField<ImmutableArray<int>> Frames = new(nameof(Frames), default);
|
||||
|
||||
[Desc("Don't apply terrain lighting or colored overlays.")]
|
||||
protected static readonly SpriteSequenceField<bool> IgnoreWorldTint = new(nameof(IgnoreWorldTint), false);
|
||||
@@ -181,7 +179,7 @@ namespace OpenRA.Mods.Common.Graphics
|
||||
protected static readonly SpriteSequenceField<MiniYaml> Combine = new(nameof(Combine), null);
|
||||
|
||||
[Desc("Sets transparency - use one value to set for all frames or provide a value for each frame.")]
|
||||
protected static readonly SpriteSequenceField<float[]> Alpha = new(nameof(Alpha), null);
|
||||
protected static readonly SpriteSequenceField<ImmutableArray<float>> Alpha = new(nameof(Alpha), default);
|
||||
|
||||
[Desc("Fade the animation from fully opaque on the first frame to fully transparent after the last frame.")]
|
||||
protected static readonly SpriteSequenceField<bool> AlphaFade = new(nameof(AlphaFade), false);
|
||||
@@ -196,7 +194,7 @@ namespace OpenRA.Mods.Common.Graphics
|
||||
protected static readonly SpriteSequenceField<float2> DepthSpriteOffset = new(nameof(DepthSpriteOffset), float2.Zero);
|
||||
|
||||
protected static readonly MiniYaml NoData = new(null);
|
||||
protected static readonly int[] FirstFrame = [0];
|
||||
protected static readonly ImmutableArray<int> FirstFrame = [0];
|
||||
|
||||
protected readonly ISpriteSequenceLoader Loader;
|
||||
|
||||
@@ -220,7 +218,7 @@ namespace OpenRA.Mods.Common.Graphics
|
||||
protected int shadowZOffset;
|
||||
protected bool ignoreWorldTint;
|
||||
protected float scale;
|
||||
protected float[] alpha;
|
||||
protected ImmutableArray<float> alpha;
|
||||
protected bool alphaFade;
|
||||
protected Rectangle? bounds;
|
||||
|
||||
@@ -296,12 +294,12 @@ namespace OpenRA.Mods.Common.Graphics
|
||||
return Rectangle.FromLTRB(left, top, right, bottom);
|
||||
}
|
||||
|
||||
protected static List<int> CalculateFrameIndices(
|
||||
int start, int? length, int stride, int facings, int[] frames, bool transpose, bool reverseFacings, int shadowStart)
|
||||
protected static ImmutableArray<int> CalculateFrameIndices(
|
||||
int start, int? length, int stride, int facings, ImmutableArray<int> frames, bool transpose, bool reverseFacings, int shadowStart)
|
||||
{
|
||||
// Request all frames
|
||||
if (length == null)
|
||||
return null;
|
||||
return default;
|
||||
|
||||
// Only request the subset of frames that we actually need
|
||||
var usedFrames = new List<int>();
|
||||
@@ -313,7 +311,7 @@ namespace OpenRA.Mods.Common.Graphics
|
||||
var i = transpose ? frame * facings + facingInner :
|
||||
facingInner * stride + frame;
|
||||
|
||||
usedFrames.Add(frames?[i] ?? start + i);
|
||||
usedFrames.Add(frames != null ? frames[i] : start + i);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -325,10 +323,10 @@ namespace OpenRA.Mods.Common.Graphics
|
||||
usedFrames.Add(usedFrames[i] + shadowOffset);
|
||||
}
|
||||
|
||||
return usedFrames;
|
||||
return usedFrames.ToImmutableArray();
|
||||
}
|
||||
|
||||
protected virtual IEnumerable<ReservationInfo> ParseFilenames(ModData modData, string tileset, int[] frames, MiniYaml data, MiniYaml defaults)
|
||||
protected virtual IEnumerable<ReservationInfo> ParseFilenames(ModData modData, string tileset, ImmutableArray<int> frames, MiniYaml data, MiniYaml defaults)
|
||||
{
|
||||
var filenamePatternNode = data.NodeWithKeyOrDefault(FilenamePattern.Key) ?? defaults.NodeWithKeyOrDefault(FilenamePattern.Key);
|
||||
if (!string.IsNullOrEmpty(filenamePatternNode?.Value.Value))
|
||||
@@ -347,14 +345,14 @@ namespace OpenRA.Mods.Common.Graphics
|
||||
return [new ReservationInfo(filename, loadFrames, frames, location)];
|
||||
}
|
||||
|
||||
protected virtual IEnumerable<ReservationInfo> ParseCombineFilenames(ModData modData, string tileset, int[] frames, MiniYaml data)
|
||||
protected virtual IEnumerable<ReservationInfo> ParseCombineFilenames(ModData modData, string tileset, ImmutableArray<int> frames, MiniYaml data)
|
||||
{
|
||||
var filename = LoadField(Filename, data, null, out var location);
|
||||
if (frames == null && LoadField<string>(Length.Key, null, data) != "*")
|
||||
{
|
||||
var subStart = LoadField("Start", 0, data);
|
||||
var subLength = LoadField("Length", 1, data);
|
||||
frames = Exts.MakeArray(subLength, i => subStart + i);
|
||||
frames = Exts.MakeArray(subLength, i => subStart + i).ToImmutableArray();
|
||||
}
|
||||
|
||||
yield return new ReservationInfo(filename, frames, frames, location);
|
||||
@@ -522,24 +520,25 @@ namespace OpenRA.Mods.Common.Graphics
|
||||
if (alpha != null)
|
||||
{
|
||||
if (alpha.Length == 1)
|
||||
alpha = Exts.MakeArray(length.Value, _ => alpha[0]);
|
||||
alpha = Exts.MakeArray(length.Value, _ => alpha[0]).ToImmutableArray();
|
||||
else if (alpha.Length != length.Value)
|
||||
throw new YamlException($"Sequence {image}.{Name} must define either 1 or {length.Value} Alpha values.");
|
||||
}
|
||||
else if (alphaFade)
|
||||
alpha = Exts.MakeArray(length.Value, i => float2.Lerp(1f, 0f, i / (length.Value - 1f)));
|
||||
alpha = Exts.MakeArray(length.Value, i => float2.Lerp(1f, 0f, i / (length.Value - 1f))).ToImmutableArray();
|
||||
|
||||
// Reindex sprites to order facings anti-clockwise and remove unused frames
|
||||
var index = CalculateFrameIndices(start, length.Value, stride ?? length.Value, facings, null, transpose, reverseFacings, -1);
|
||||
var index = CalculateFrameIndices(start, length.Value, stride ?? length.Value, facings, default, transpose, reverseFacings, -1);
|
||||
if (reverses)
|
||||
{
|
||||
index.AddRange(index.Skip(1).Take(length.Value - 2).Reverse());
|
||||
alpha = alpha?.Concat(alpha.Skip(1).Take(length.Value - 2).Reverse()).ToArray();
|
||||
index = index.AddRange(index.Skip(1).Take(length.Value - 2).Reverse());
|
||||
if (alpha != null)
|
||||
alpha = alpha.AddRange(alpha.Skip(1).Take(length.Value - 2).Reverse());
|
||||
|
||||
length = 2 * length - 2;
|
||||
}
|
||||
|
||||
if (index.Count == 0)
|
||||
if (index.Length == 0)
|
||||
throw new YamlException($"Sequence {image}.{Name} does not define any frames.");
|
||||
|
||||
var minIndex = index.Min();
|
||||
@@ -610,7 +609,7 @@ namespace OpenRA.Mods.Common.Graphics
|
||||
|
||||
public virtual float GetAlpha(int frame)
|
||||
{
|
||||
return alpha?[frame] ?? 1f;
|
||||
return alpha != null ? alpha[frame] : 1f;
|
||||
}
|
||||
|
||||
protected virtual float GetScale()
|
||||
|
||||
@@ -9,7 +9,9 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Frozen;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using OpenRA.Graphics;
|
||||
|
||||
@@ -31,15 +33,15 @@ namespace OpenRA.Mods.Common.Graphics
|
||||
public class TilesetSpecificSpriteSequence : DefaultSpriteSequence
|
||||
{
|
||||
[Desc("Dictionary of <tileset name>: filename to override the Filename key.")]
|
||||
static readonly SpriteSequenceField<Dictionary<string, string>> TilesetFilenames = new(nameof(TilesetFilenames), null);
|
||||
static readonly SpriteSequenceField<FrozenDictionary<string, string>> TilesetFilenames = new(nameof(TilesetFilenames), null);
|
||||
|
||||
[Desc("Dictionary of <tileset name>: <filename pattern> to override the FilenamePattern key.")]
|
||||
static readonly SpriteSequenceField<Dictionary<string, string>> TilesetFilenamesPattern = new(nameof(TilesetFilenamesPattern), null);
|
||||
static readonly SpriteSequenceField<FrozenDictionary<string, string>> TilesetFilenamesPattern = new(nameof(TilesetFilenamesPattern), null);
|
||||
|
||||
public TilesetSpecificSpriteSequence(SpriteCache cache, ISpriteSequenceLoader loader, string image, string sequence, MiniYaml data, MiniYaml defaults)
|
||||
: base(cache, loader, image, sequence, data, defaults) { }
|
||||
|
||||
protected override IEnumerable<ReservationInfo> ParseFilenames(ModData modData, string tileset, int[] frames, MiniYaml data, MiniYaml defaults)
|
||||
protected override IEnumerable<ReservationInfo> ParseFilenames(ModData modData, string tileset, ImmutableArray<int> frames, MiniYaml data, MiniYaml defaults)
|
||||
{
|
||||
var tilesetFilenamesPatternNode = data.NodeWithKeyOrDefault(TilesetFilenamesPattern.Key) ?? defaults.NodeWithKeyOrDefault(TilesetFilenamesPattern.Key);
|
||||
if (tilesetFilenamesPatternNode != null)
|
||||
@@ -69,7 +71,7 @@ namespace OpenRA.Mods.Common.Graphics
|
||||
return base.ParseFilenames(modData, tileset, frames, data, defaults);
|
||||
}
|
||||
|
||||
protected override IEnumerable<ReservationInfo> ParseCombineFilenames(ModData modData, string tileset, int[] frames, MiniYaml data)
|
||||
protected override IEnumerable<ReservationInfo> ParseCombineFilenames(ModData modData, string tileset, ImmutableArray<int> frames, MiniYaml data)
|
||||
{
|
||||
var node = data.NodeWithKeyOrDefault(TilesetFilenames.Key);
|
||||
if (node != null)
|
||||
@@ -81,7 +83,7 @@ namespace OpenRA.Mods.Common.Graphics
|
||||
{
|
||||
var subStart = LoadField("Start", 0, data);
|
||||
var subLength = LoadField("Length", 1, data);
|
||||
frames = Exts.MakeArray(subLength, i => subStart + i);
|
||||
frames = Exts.MakeArray(subLength, i => subStart + i).ToImmutableArray();
|
||||
}
|
||||
|
||||
return [new ReservationInfo(tilesetNode.Value.Value, frames, frames, tilesetNode.Location)];
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Mods.Common.Graphics;
|
||||
@@ -24,7 +25,7 @@ namespace OpenRA.Mods.Common.HitShapes
|
||||
public WDist OuterRadius { get; private set; }
|
||||
|
||||
[FieldLoader.Require]
|
||||
public readonly int2[] Points;
|
||||
public readonly ImmutableArray<int2> Points;
|
||||
|
||||
[Desc("Defines the top offset relative to the actor's center.")]
|
||||
public readonly int VerticalTopOffset = 0;
|
||||
@@ -42,7 +43,7 @@ namespace OpenRA.Mods.Common.HitShapes
|
||||
|
||||
public PolygonShape() { }
|
||||
|
||||
public PolygonShape(int2[] points) { Points = points; }
|
||||
public PolygonShape(ImmutableArray<int2> points) { Points = points; }
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
|
||||
@@ -100,7 +100,7 @@ namespace OpenRA.Mods.Common.Lint
|
||||
// Logic classes can declare the data key names that specify hotkeys.
|
||||
if (node.Key == "Logic" && node.Value.Nodes.Length > 0)
|
||||
{
|
||||
var typeNames = FieldLoader.GetValue<string[]>(node.Key, node.Value.Value);
|
||||
var typeNames = FieldLoader.GetValue<ImmutableArray<string>>(node.Key, node.Value.Value);
|
||||
var checkArgKeys = new List<string>();
|
||||
foreach (var typeName in typeNames)
|
||||
{
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using OpenRA.Widgets;
|
||||
|
||||
namespace OpenRA.Mods.Common.Lint
|
||||
@@ -32,7 +33,7 @@ namespace OpenRA.Mods.Common.Lint
|
||||
|
||||
if (node.Key == "Logic")
|
||||
{
|
||||
var typeNames = FieldLoader.GetValue<string[]>(node.Key, node.Value.Value);
|
||||
var typeNames = FieldLoader.GetValue<ImmutableArray<string>>(node.Key, node.Value.Value);
|
||||
foreach (var typeName in typeNames)
|
||||
{
|
||||
var type = Game.ModData.ObjectCreator.FindType(typeName);
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
@@ -39,7 +40,7 @@ namespace OpenRA.Mods.Common.Lint
|
||||
foreach (var context in usedKeys.EmptyKeyContexts)
|
||||
emitWarning($"Empty key in map ftl files required by {context}");
|
||||
|
||||
var mapMessages = FieldLoader.GetValue<string[]>("value", map.FluentMessageDefinitions.Value);
|
||||
var mapMessages = FieldLoader.GetValue<ImmutableArray<string>>("value", map.FluentMessageDefinitions.Value);
|
||||
var modMessages = modData.Manifest.FluentMessages;
|
||||
|
||||
// For maps we don't warn on unused keys. They might be unused on *this* map,
|
||||
@@ -363,7 +364,7 @@ namespace OpenRA.Mods.Common.Lint
|
||||
{
|
||||
if (childNode.Key == "Logic")
|
||||
{
|
||||
foreach (var logicName in FieldLoader.GetValue<string[]>(childNode.Key, childNode.Value.Value))
|
||||
foreach (var logicName in FieldLoader.GetValue<ImmutableArray<string>>(childNode.Key, childNode.Value.Value))
|
||||
{
|
||||
var logicType = modData.ObjectCreator.FindType(logicName);
|
||||
if (logicType == null)
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.IO;
|
||||
using Linguini.Syntax.Ast;
|
||||
using Linguini.Syntax.Parser;
|
||||
@@ -25,7 +26,7 @@ namespace OpenRA.Mods.Common.Lint
|
||||
if (map.FluentMessageDefinitions == null)
|
||||
return;
|
||||
|
||||
Run(emitError, emitWarning, map, FieldLoader.GetValue<string[]>("value", map.FluentMessageDefinitions.Value));
|
||||
Run(emitError, emitWarning, map, FieldLoader.GetValue<ImmutableArray<string>>("value", map.FluentMessageDefinitions.Value));
|
||||
}
|
||||
|
||||
void ILintPass.Run(Action<string> emitError, Action<string> emitWarning, ModData modData)
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Primitives;
|
||||
@@ -60,7 +61,7 @@ namespace OpenRA.Mods.Common.Lint
|
||||
}
|
||||
}
|
||||
|
||||
static bool HasInvalidBounds(WDist[] bounds, Size tileSize, int tileScale)
|
||||
static bool HasInvalidBounds(ImmutableArray<WDist> bounds, Size tileSize, int tileScale)
|
||||
{
|
||||
if (bounds == null)
|
||||
return false;
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Immutable;
|
||||
using OpenRA.Server;
|
||||
|
||||
namespace OpenRA.Mods.Common.Lint
|
||||
@@ -26,7 +27,7 @@ namespace OpenRA.Mods.Common.Lint
|
||||
Run(emitError, map.MapFormat, map.Author, map.Title, map.Categories);
|
||||
}
|
||||
|
||||
static void Run(Action<string> emitError, int mapFormat, string author, string title, string[] categories)
|
||||
static void Run(Action<string> emitError, int mapFormat, string author, string title, ImmutableArray<string> categories)
|
||||
{
|
||||
if (mapFormat < Map.SupportedMapFormat)
|
||||
emitError($"Map format `{mapFormat}` does not match the supported version `{Map.CurrentMapFormat}`.");
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Server;
|
||||
@@ -30,7 +31,7 @@ namespace OpenRA.Mods.Common.Lint
|
||||
spawns.Add(s.Get<LocationInit>().Value);
|
||||
}
|
||||
|
||||
Run(emitError, emitWarning, players, map.Visibility, map.Rules.Actors[SystemActors.World], spawns.ToArray());
|
||||
Run(emitError, emitWarning, players, map.Visibility, map.Rules.Actors[SystemActors.World], spawns.ToImmutableArray());
|
||||
}
|
||||
|
||||
void ILintServerMapPass.Run(Action<string> emitError, Action<string> emitWarning, ModData modData, MapPreview map, Ruleset mapRules)
|
||||
@@ -39,7 +40,7 @@ namespace OpenRA.Mods.Common.Lint
|
||||
}
|
||||
|
||||
static void Run(Action<string> emitError, Action<string> emitWarning,
|
||||
MapPlayers players, MapVisibility visibility, ActorInfo worldActorInfo, CPos[] spawnPoints)
|
||||
MapPlayers players, MapVisibility visibility, ActorInfo worldActorInfo, ImmutableArray<CPos> spawnPoints)
|
||||
{
|
||||
if (players.Players.Count > 64)
|
||||
emitError("Defining more than 64 players is not allowed.");
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using OpenRA.FileSystem;
|
||||
using OpenRA.Server;
|
||||
|
||||
@@ -94,7 +95,7 @@ namespace OpenRA.Mods.Common.Lint
|
||||
if (ruleDefinitions == null)
|
||||
return;
|
||||
|
||||
var mapFiles = FieldLoader.GetValue<string[]>("value", ruleDefinitions.Value);
|
||||
var mapFiles = FieldLoader.GetValue<ImmutableArray<string>>("value", ruleDefinitions.Value);
|
||||
foreach (var f in mapFiles)
|
||||
CheckActors(MiniYaml.FromStream(fileSystem.Open(f), f), emitError, modData);
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using OpenRA.FileSystem;
|
||||
using OpenRA.GameRules;
|
||||
using OpenRA.Server;
|
||||
@@ -115,7 +116,7 @@ namespace OpenRA.Mods.Common.Lint
|
||||
if (weaponDefinitions == null)
|
||||
return;
|
||||
|
||||
var mapFiles = FieldLoader.GetValue<string[]>("value", weaponDefinitions.Value);
|
||||
var mapFiles = FieldLoader.GetValue<ImmutableArray<string>>("value", weaponDefinitions.Value);
|
||||
foreach (var f in mapFiles)
|
||||
CheckWeapons(MiniYaml.FromStream(fileSystem.Open(f), f), emitError, emitWarning, modData);
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using OpenRA.FileSystem;
|
||||
using OpenRA.Mods.Common.UpdateRules;
|
||||
@@ -47,8 +48,8 @@ namespace OpenRA.Mods.Common.Lint
|
||||
var files = modData.Manifest.Rules.AsEnumerable();
|
||||
if (ruleDefinitions.Value != null)
|
||||
{
|
||||
var mapFiles = FieldLoader.GetValue<string[]>("value", ruleDefinitions.Value);
|
||||
files = files.Append(mapFiles);
|
||||
var mapFiles = FieldLoader.GetValue<ImmutableArray<string>>("value", ruleDefinitions.Value);
|
||||
files = files.Concat(mapFiles);
|
||||
}
|
||||
|
||||
var nodes = new List<MiniYamlNode>();
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Frozen;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
@@ -85,16 +86,16 @@ namespace OpenRA.Mods.Common.MapGenerator
|
||||
public class MapGeneratorDropdownChoice
|
||||
{
|
||||
public readonly string Label = null;
|
||||
public readonly string[] Tileset = null;
|
||||
public readonly int[] Players = null;
|
||||
public readonly ImmutableArray<string> Tileset = default;
|
||||
public readonly ImmutableArray<int> Players = default;
|
||||
|
||||
[FieldLoader.LoadUsing(nameof(LoadSettings))]
|
||||
[FieldLoader.Require]
|
||||
public readonly ImmutableList<MiniYamlNode> Settings = null;
|
||||
public readonly ImmutableArray<MiniYamlNode> Settings = default;
|
||||
|
||||
static ImmutableList<MiniYamlNode> LoadSettings(MiniYaml yaml)
|
||||
static object LoadSettings(MiniYaml yaml)
|
||||
{
|
||||
return yaml.NodeWithKey("Settings").Value.Nodes.ToImmutableList();
|
||||
return yaml.NodeWithKey("Settings").Value.Nodes.ToImmutableArray();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,7 +115,7 @@ namespace OpenRA.Mods.Common.MapGenerator
|
||||
return ret;
|
||||
}
|
||||
|
||||
public readonly string[] Default = null;
|
||||
public readonly ImmutableArray<string> Default = default;
|
||||
string value = null;
|
||||
|
||||
public MapGeneratorMultiChoiceOption(string id, MiniYaml yaml)
|
||||
@@ -126,7 +127,7 @@ namespace OpenRA.Mods.Common.MapGenerator
|
||||
if (validChoices.Contains(value))
|
||||
return Choices[value].Settings;
|
||||
|
||||
var fallback = Default?.FirstOrDefault(validChoices.Contains) ?? validChoices.FirstOrDefault();
|
||||
var fallback = Default != null ? Default.FirstOrDefault(validChoices.Contains) : validChoices.FirstOrDefault();
|
||||
return fallback != null ? Choices[fallback].Settings : [];
|
||||
}
|
||||
|
||||
@@ -146,8 +147,8 @@ namespace OpenRA.Mods.Common.MapGenerator
|
||||
{
|
||||
return Choices
|
||||
.Where(kv =>
|
||||
(kv.Value.Tileset?.Contains(terrainInfo.Id) ?? true) &&
|
||||
(kv.Value.Players?.Contains(playerCount) ?? true))
|
||||
(kv.Value.Tileset == null || kv.Value.Tileset.Contains(terrainInfo.Id)) &&
|
||||
(kv.Value.Players == null || kv.Value.Players.Contains(playerCount)))
|
||||
.Select(kv => kv.Key)
|
||||
.ToList();
|
||||
}
|
||||
@@ -177,7 +178,7 @@ namespace OpenRA.Mods.Common.MapGenerator
|
||||
public readonly string Parameter = null;
|
||||
|
||||
[FieldLoader.Require]
|
||||
public readonly int[] Choices = null;
|
||||
public readonly ImmutableArray<int> Choices = default;
|
||||
|
||||
public readonly int? Default = null;
|
||||
int value;
|
||||
@@ -185,7 +186,7 @@ namespace OpenRA.Mods.Common.MapGenerator
|
||||
public MapGeneratorMultiIntegerChoiceOption(string id, MiniYaml yaml)
|
||||
: base(id, yaml)
|
||||
{
|
||||
Value = Default ?? Choices?.First() ?? 0;
|
||||
Value = Default ?? (Choices != null ? Choices[0] : 0);
|
||||
}
|
||||
|
||||
public int Value
|
||||
@@ -210,7 +211,7 @@ namespace OpenRA.Mods.Common.MapGenerator
|
||||
{
|
||||
sealed class MapGenerationArgsWithOptions : MapGenerationArgs
|
||||
{
|
||||
public Dictionary<string, string> Options = [];
|
||||
public FrozenDictionary<string, string> Options = FrozenDictionary<string, string>.Empty;
|
||||
}
|
||||
|
||||
readonly IMapGeneratorInfo generatorInfo;
|
||||
@@ -218,6 +219,8 @@ namespace OpenRA.Mods.Common.MapGenerator
|
||||
public MapGeneratorSettings(IMapGeneratorInfo generatorInfo, MiniYaml yaml)
|
||||
{
|
||||
this.generatorInfo = generatorInfo;
|
||||
|
||||
var options = new List<MapGeneratorOption>();
|
||||
foreach (var node in yaml.Nodes)
|
||||
{
|
||||
var split = node.Key.Split('@');
|
||||
@@ -225,17 +228,19 @@ namespace OpenRA.Mods.Common.MapGenerator
|
||||
continue;
|
||||
|
||||
if (split[0] == "BooleanOption")
|
||||
Options.Add(new MapGeneratorBooleanOption(split[1], node.Value));
|
||||
options.Add(new MapGeneratorBooleanOption(split[1], node.Value));
|
||||
else if (split[0] == "IntegerOption")
|
||||
Options.Add(new MapGeneratorIntegerOption(split[1], node.Value));
|
||||
options.Add(new MapGeneratorIntegerOption(split[1], node.Value));
|
||||
else if (split[0] == "MultiIntegerChoiceOption")
|
||||
Options.Add(new MapGeneratorMultiIntegerChoiceOption(split[1], node.Value));
|
||||
options.Add(new MapGeneratorMultiIntegerChoiceOption(split[1], node.Value));
|
||||
else if (split[0] == "MultiChoiceOption")
|
||||
Options.Add(new MapGeneratorMultiChoiceOption(split[1], node.Value));
|
||||
options.Add(new MapGeneratorMultiChoiceOption(split[1], node.Value));
|
||||
}
|
||||
|
||||
Options = options.ToImmutableArray();
|
||||
}
|
||||
|
||||
public List<MapGeneratorOption> Options { get; } = [];
|
||||
public ImmutableArray<MapGeneratorOption> Options { get; } = [];
|
||||
|
||||
public void Randomize(MersenneTwister random)
|
||||
{
|
||||
@@ -306,7 +311,7 @@ namespace OpenRA.Mods.Common.MapGenerator
|
||||
Title = FluentProvider.GetMessage(generatorInfo.MapTitle),
|
||||
Author = FluentProvider.GetMessage(generatorInfo.Name),
|
||||
Settings = new MiniYaml(null, MiniYaml.Merge(layers)),
|
||||
Options = options
|
||||
Options = options.ToFrozenDictionary()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1951,7 +1951,7 @@ namespace OpenRA.Mods.Common.MapGenerator
|
||||
var allowedTerrainResourceCombos = resourceTypes
|
||||
.SelectMany(resourceTypeInfo => resourceTypeInfo.AllowedTerrainTypes
|
||||
.Select(terrainName => (resourceTypeInfo, terrainInfo.GetTerrainIndex(terrainName))))
|
||||
.ToImmutableHashSet();
|
||||
.ToHashSet();
|
||||
|
||||
var strengths = new Dictionary<ResourceTypeInfo, CellLayer<int>>();
|
||||
foreach (var resourceType in resourceTypes)
|
||||
|
||||
@@ -597,10 +597,9 @@ namespace OpenRA.Mods.Common.MapGenerator
|
||||
var pathStart = points[0];
|
||||
var pathEnd = points[^1];
|
||||
var orderedPermittedBrushes = Brushes.All.ToImmutableArray();
|
||||
var permittedBrushes = orderedPermittedBrushes.ToImmutableHashSet();
|
||||
var permittedStartBrushes = Brushes.Start.ToImmutableHashSet();
|
||||
var permittedInnerBrushes = Brushes.Inner.ToImmutableHashSet();
|
||||
var permittedEndBrushes = Brushes.End.ToImmutableHashSet();
|
||||
var permittedStartBrushes = Brushes.Start.ToHashSet();
|
||||
var permittedInnerBrushes = Brushes.Inner.ToHashSet();
|
||||
var permittedEndBrushes = Brushes.End.ToHashSet();
|
||||
|
||||
const int MaxCost = int.MaxValue;
|
||||
var segmentTypeToId = new Dictionary<string, int>();
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Frozen;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.IO;
|
||||
@@ -24,8 +25,8 @@ namespace OpenRA.Mods.Common
|
||||
[FluentReference]
|
||||
public readonly string Title;
|
||||
public readonly string Identifier;
|
||||
public readonly string[] TestFiles = [];
|
||||
public readonly string[] Sources = [];
|
||||
public readonly ImmutableArray<string> TestFiles = [];
|
||||
public readonly ImmutableArray<string> Sources = [];
|
||||
public readonly bool Required;
|
||||
public readonly string Download;
|
||||
|
||||
@@ -46,7 +47,7 @@ namespace OpenRA.Mods.Common
|
||||
public readonly MiniYaml Type;
|
||||
|
||||
// Used to find installation locations for SourceType.Install
|
||||
public readonly string[] RegistryPrefixes = [string.Empty];
|
||||
public readonly ImmutableArray<string> RegistryPrefixes = [string.Empty];
|
||||
public readonly string RegistryKey;
|
||||
public readonly string RegistryValue;
|
||||
|
||||
@@ -87,7 +88,7 @@ namespace OpenRA.Mods.Common
|
||||
public readonly string MirrorList;
|
||||
public readonly string SHA1;
|
||||
public readonly string Type;
|
||||
public readonly Dictionary<string, string> Extract;
|
||||
public readonly FrozenDictionary<string, string> Extract;
|
||||
|
||||
public ModDownload(MiniYaml yaml)
|
||||
{
|
||||
@@ -103,35 +104,35 @@ namespace OpenRA.Mods.Common
|
||||
|
||||
[IncludeFluentReferences(LintDictionaryReference.Values)]
|
||||
[FieldLoader.LoadUsing(nameof(LoadPackages))]
|
||||
public readonly Dictionary<string, ModPackage> Packages = [];
|
||||
public readonly ImmutableArray<KeyValuePair<string, ModPackage>> Packages = [];
|
||||
|
||||
static object LoadPackages(MiniYaml yaml)
|
||||
{
|
||||
var packages = new Dictionary<string, ModPackage>();
|
||||
var packages = new List<KeyValuePair<string, ModPackage>>();
|
||||
var packageNode = yaml.NodeWithKeyOrDefault("Packages");
|
||||
if (packageNode != null)
|
||||
foreach (var node in packageNode.Value.Nodes)
|
||||
packages.Add(node.Key, new ModPackage(node.Value));
|
||||
packages.Add(KeyValuePair.Create(node.Key, new ModPackage(node.Value)));
|
||||
|
||||
return packages;
|
||||
return packages.ToImmutableArray();
|
||||
}
|
||||
|
||||
[FieldLoader.LoadUsing(nameof(LoadDownloads))]
|
||||
public readonly string[] Downloads = [];
|
||||
public readonly ImmutableArray<string> Downloads = [];
|
||||
|
||||
static object LoadDownloads(MiniYaml yaml)
|
||||
{
|
||||
var downloadNode = yaml.NodeWithKeyOrDefault("Downloads");
|
||||
return downloadNode != null ? downloadNode.Value.Nodes.Select(n => n.Key).ToArray() : [];
|
||||
return downloadNode != null ? downloadNode.Value.Nodes.Select(n => n.Key).ToImmutableArray() : [];
|
||||
}
|
||||
|
||||
[FieldLoader.LoadUsing(nameof(LoadSources))]
|
||||
public readonly string[] Sources = [];
|
||||
public readonly ImmutableArray<string> Sources = [];
|
||||
|
||||
static object LoadSources(MiniYaml yaml)
|
||||
{
|
||||
var sourceNode = yaml.NodeWithKeyOrDefault("Sources");
|
||||
return sourceNode != null ? sourceNode.Value.Nodes.Select(n => n.Key).ToArray() : [];
|
||||
return sourceNode != null ? sourceNode.Value.Nodes.Select(n => n.Key).ToImmutableArray() : [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using OpenRA.GameRules;
|
||||
using OpenRA.Graphics;
|
||||
@@ -25,7 +26,7 @@ namespace OpenRA.Mods.Common.Projectiles
|
||||
public class AreaBeamInfo : IProjectileInfo
|
||||
{
|
||||
[Desc("Projectile speed in WDist / tick, two values indicate a randomly picked velocity per beam.")]
|
||||
public readonly WDist[] Speed = [new(128)];
|
||||
public readonly ImmutableArray<WDist> Speed = [new(128)];
|
||||
|
||||
[Desc("The maximum duration (in ticks) of each beam burst.")]
|
||||
public readonly int Duration = 10;
|
||||
@@ -46,10 +47,10 @@ namespace OpenRA.Mods.Common.Projectiles
|
||||
public readonly WDist MinDistance = WDist.Zero;
|
||||
|
||||
[Desc("Damage modifier applied at each range step.")]
|
||||
public readonly int[] Falloff = [100, 100];
|
||||
public readonly ImmutableArray<int> Falloff = [100, 100];
|
||||
|
||||
[Desc("Ranges at which each Falloff step is defined.")]
|
||||
public readonly WDist[] Range = [WDist.Zero, new(int.MaxValue)];
|
||||
public readonly ImmutableArray<WDist> Range = [WDist.Zero, new(int.MaxValue)];
|
||||
|
||||
[Desc("The maximum/constant/incremental inaccuracy used in conjunction with the InaccuracyType property.")]
|
||||
public readonly WDist Inaccuracy = WDist.Zero;
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Frozen;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using OpenRA.GameRules;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Mods.Common.Effects;
|
||||
@@ -25,7 +27,7 @@ namespace OpenRA.Mods.Common.Projectiles
|
||||
public class BulletInfo : IProjectileInfo
|
||||
{
|
||||
[Desc("Projectile speed in WDist / tick, two values indicate variable velocity.")]
|
||||
public readonly WDist[] Speed = [new(17)];
|
||||
public readonly ImmutableArray<WDist> Speed = [new(17)];
|
||||
|
||||
[Desc("The maximum/constant/incremental inaccuracy used in conjunction with the InaccuracyType property.")]
|
||||
public readonly WDist Inaccuracy = WDist.Zero;
|
||||
@@ -41,7 +43,7 @@ namespace OpenRA.Mods.Common.Projectiles
|
||||
|
||||
[SequenceReference(nameof(Image), allowNullImage: true)]
|
||||
[Desc("Loop a randomly chosen sequence of Image from this list while this projectile is moving.")]
|
||||
public readonly string[] Sequences = ["idle"];
|
||||
public readonly ImmutableArray<string> Sequences = ["idle"];
|
||||
|
||||
[PaletteReference(nameof(IsPlayerPalette))]
|
||||
[Desc("The palette used to draw this projectile.")]
|
||||
@@ -61,7 +63,7 @@ namespace OpenRA.Mods.Common.Projectiles
|
||||
|
||||
[SequenceReference(nameof(TrailImage), allowNullImage: true)]
|
||||
[Desc("Loop a randomly chosen sequence of TrailImage from this list while this projectile is moving.")]
|
||||
public readonly string[] TrailSequences = ["idle"];
|
||||
public readonly ImmutableArray<string> TrailSequences = ["idle"];
|
||||
|
||||
[Desc("Interval in ticks between each spawned Trail animation.")]
|
||||
public readonly int TrailInterval = 2;
|
||||
@@ -83,7 +85,7 @@ namespace OpenRA.Mods.Common.Projectiles
|
||||
public readonly WDist Width = new(1);
|
||||
|
||||
[Desc("Arc in WAngles, two values indicate variable arc.")]
|
||||
public readonly WAngle[] LaunchAngle = [WAngle.Zero];
|
||||
public readonly ImmutableArray<WAngle> LaunchAngle = [WAngle.Zero];
|
||||
|
||||
[Desc("Up to how many times does this bullet bounce when touching ground without hitting a target.",
|
||||
"0 implies exploding on contact with the originally targeted position.")]
|
||||
@@ -96,7 +98,7 @@ namespace OpenRA.Mods.Common.Projectiles
|
||||
public readonly string BounceSound = null;
|
||||
|
||||
[Desc("Terrain where the projectile explodes instead of bouncing.")]
|
||||
public readonly HashSet<string> InvalidBounceTerrain = [];
|
||||
public readonly FrozenSet<string> InvalidBounceTerrain = FrozenSet<string>.Empty;
|
||||
|
||||
[Desc("Trigger the explosion if the projectile touches an actor thats owner has these player relationships.")]
|
||||
public readonly PlayerRelationship ValidBounceBlockerRelationships = PlayerRelationship.Enemy | PlayerRelationship.Neutral;
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using OpenRA.GameRules;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Primitives;
|
||||
@@ -24,7 +25,7 @@ namespace OpenRA.Mods.Common.Projectiles
|
||||
|
||||
[SequenceReference(nameof(Image), allowNullImage: true)]
|
||||
[Desc("Loop a randomly chosen sequence of Image from this list while falling.")]
|
||||
public readonly string[] Sequences = ["idle"];
|
||||
public readonly ImmutableArray<string> Sequences = ["idle"];
|
||||
|
||||
[SequenceReference(nameof(Image), allowNullImage: true)]
|
||||
[Desc("Sequence to play when launched. Skipped if null or empty.")]
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using OpenRA.GameRules;
|
||||
using OpenRA.Graphics;
|
||||
@@ -29,7 +30,7 @@ namespace OpenRA.Mods.Common.Projectiles
|
||||
|
||||
[SequenceReference(nameof(Image), allowNullImage: true)]
|
||||
[Desc("Loop a randomly chosen sequence of Image from this list while this projectile is moving.")]
|
||||
public readonly string[] Sequences = ["idle"];
|
||||
public readonly ImmutableArray<string> Sequences = ["idle"];
|
||||
|
||||
[PaletteReference(nameof(IsPlayerPalette))]
|
||||
[Desc("Palette used to render the projectile sequence.")]
|
||||
@@ -118,7 +119,7 @@ namespace OpenRA.Mods.Common.Projectiles
|
||||
|
||||
[SequenceReference(nameof(TrailImage), allowNullImage: true)]
|
||||
[Desc("Loop a randomly chosen sequence of TrailImage from this list while this projectile is moving.")]
|
||||
public readonly string[] TrailSequences = ["idle"];
|
||||
public readonly ImmutableArray<string> TrailSequences = ["idle"];
|
||||
|
||||
[PaletteReference(nameof(TrailUsePlayerPalette))]
|
||||
[Desc("Palette used to render the trail sequence.")]
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using OpenRA.Effects;
|
||||
using OpenRA.GameRules;
|
||||
using OpenRA.Graphics;
|
||||
@@ -35,7 +36,7 @@ namespace OpenRA.Mods.Common.Effects
|
||||
readonly int impactDelay;
|
||||
readonly int turn;
|
||||
readonly string trailImage;
|
||||
readonly string[] trailSequences;
|
||||
readonly ImmutableArray<string> trailSequences;
|
||||
readonly string trailPalette;
|
||||
readonly int trailInterval;
|
||||
readonly int trailDelay;
|
||||
@@ -49,7 +50,7 @@ namespace OpenRA.Mods.Common.Effects
|
||||
public NukeLaunch(Player firedBy, string image, WeaponInfo weapon, string weaponPalette, string upSequence, string downSequence,
|
||||
WPos launchPos, WPos targetPos, WDist detonationAltitude, bool removeOnDetonation, WDist velocity, int launchDelay, int impactDelay,
|
||||
bool skipAscent,
|
||||
string trailImage, string[] trailSequences, string trailPalette, bool trailUsePlayerPalette, int trailDelay, int trailInterval)
|
||||
string trailImage, ImmutableArray<string> trailSequences, string trailPalette, bool trailUsePlayerPalette, int trailDelay, int trailInterval)
|
||||
{
|
||||
this.firedBy = firedBy;
|
||||
this.weapon = weapon;
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Frozen;
|
||||
using System.Linq;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
@@ -23,7 +23,7 @@ namespace OpenRA.Mods.Common.Scripting
|
||||
public class LuaScriptInfo : TraitInfo, Requires<SpawnMapActorsInfo>, NotBefore<SpawnStartingUnitsInfo>
|
||||
{
|
||||
[Desc("File names with location relative to the map.")]
|
||||
public readonly HashSet<string> Scripts = [];
|
||||
public readonly FrozenSet<string> Scripts = FrozenSet<string>.Empty;
|
||||
|
||||
public override object Create(ActorInitializer init) { return new LuaScript(this); }
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Frozen;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
@@ -1298,13 +1299,13 @@ namespace OpenRA.Mods.Common.Server
|
||||
return;
|
||||
|
||||
var mapCache = server.ModData.MapCache;
|
||||
if (server.Settings.MapPool.Length > 0)
|
||||
server.MapPool = server.Settings.MapPool.ToHashSet();
|
||||
if (server.Settings.MapPool.Count > 0)
|
||||
server.MapPool = server.Settings.MapPool;
|
||||
else if (!server.Settings.QueryMapRepository)
|
||||
server.MapPool = mapCache
|
||||
.Where(p => p.Status == MapStatus.Available && p.Visibility.HasFlag(MapVisibility.Lobby))
|
||||
.Select(p => p.Uid)
|
||||
.ToHashSet();
|
||||
.ToFrozenSet();
|
||||
else
|
||||
return;
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Frozen;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.IO;
|
||||
@@ -40,9 +41,9 @@ namespace OpenRA.Mods.Common.Terrain
|
||||
|
||||
public class DefaultTerrainTemplateInfo : TerrainTemplateInfo
|
||||
{
|
||||
public readonly string[] Images;
|
||||
public readonly string[] DepthImages;
|
||||
public readonly int[] Frames;
|
||||
public readonly ImmutableArray<string> Images;
|
||||
public readonly ImmutableArray<string> DepthImages;
|
||||
public readonly ImmutableArray<int> Frames;
|
||||
public readonly string Palette;
|
||||
|
||||
public DefaultTerrainTemplateInfo(ITerrainInfo terrainInfo, MiniYaml my)
|
||||
@@ -75,8 +76,8 @@ namespace OpenRA.Mods.Common.Terrain
|
||||
public readonly string Id;
|
||||
public readonly Size TileSize = new(24, 24);
|
||||
public readonly int SheetSize = 512;
|
||||
public readonly Color[] HeightDebugColors = [Color.Red];
|
||||
public readonly string[] EditorTemplateOrder;
|
||||
public readonly ImmutableArray<Color> HeightDebugColors = [Color.Red];
|
||||
public readonly ImmutableArray<string> EditorTemplateOrder;
|
||||
public readonly bool IgnoreTileSpriteOffsets;
|
||||
public readonly bool EnableDepth = false;
|
||||
public readonly float MinHeightColorBrightness = 1.0f;
|
||||
@@ -84,13 +85,13 @@ namespace OpenRA.Mods.Common.Terrain
|
||||
public readonly string Palette = TileSet.TerrainPaletteInternalName;
|
||||
|
||||
[FieldLoader.Ignore]
|
||||
public readonly IReadOnlyDictionary<ushort, TerrainTemplateInfo> Templates;
|
||||
public readonly FrozenDictionary<ushort, TerrainTemplateInfo> Templates;
|
||||
[FieldLoader.Ignore]
|
||||
public readonly IReadOnlyDictionary<string, IEnumerable<MultiBrushInfo>> MultiBrushCollections;
|
||||
public readonly FrozenDictionary<string, ImmutableArray<MultiBrushInfo>> MultiBrushCollections;
|
||||
|
||||
[FieldLoader.Ignore]
|
||||
public readonly TerrainTypeInfo[] TerrainInfo;
|
||||
readonly Dictionary<string, byte> terrainIndexByType = [];
|
||||
public readonly ImmutableArray<TerrainTypeInfo> TerrainInfo;
|
||||
readonly FrozenDictionary<string, byte> terrainIndexByType;
|
||||
readonly byte defaultWalkableTerrainIndex;
|
||||
|
||||
public DefaultTerrain(IReadOnlyFileSystem fileSystem, string filepath)
|
||||
@@ -105,35 +106,38 @@ namespace OpenRA.Mods.Common.Terrain
|
||||
TerrainInfo = yaml["Terrain"].ToDictionary().Values
|
||||
.Select(y => new TerrainTypeInfo(y))
|
||||
.OrderBy(tt => tt.Type)
|
||||
.ToArray();
|
||||
.ToImmutableArray();
|
||||
|
||||
if (TerrainInfo.Length >= byte.MaxValue)
|
||||
throw new YamlException("Too many terrain types.");
|
||||
|
||||
var tiby = new Dictionary<string, byte>(TerrainInfo.Length);
|
||||
for (byte i = 0; i < TerrainInfo.Length; i++)
|
||||
{
|
||||
var tt = TerrainInfo[i].Type;
|
||||
|
||||
if (terrainIndexByType.ContainsKey(tt))
|
||||
if (!tiby.TryAdd(tt, i))
|
||||
throw new YamlException($"Duplicate terrain type '{tt}' in '{filepath}'.");
|
||||
|
||||
terrainIndexByType.Add(tt, i);
|
||||
}
|
||||
|
||||
terrainIndexByType = tiby.ToFrozenDictionary();
|
||||
|
||||
defaultWalkableTerrainIndex = GetTerrainIndex("Clear");
|
||||
|
||||
// Templates
|
||||
Templates = yaml["Templates"].ToDictionary().Values
|
||||
.Select(y => (TerrainTemplateInfo)new DefaultTerrainTemplateInfo(this, y)).ToDictionary(t => t.Id);
|
||||
.Select(y => (TerrainTemplateInfo)new DefaultTerrainTemplateInfo(this, y))
|
||||
.ToDictionary(t => t.Id)
|
||||
.ToFrozenDictionary();
|
||||
|
||||
MultiBrushCollections =
|
||||
yaml.TryGetValue("MultiBrushCollections", out var collectionDefinitions)
|
||||
? collectionDefinitions.ToDictionary()
|
||||
.Select(kv => new KeyValuePair<string, IEnumerable<MultiBrushInfo>>(
|
||||
.Select(kv => new KeyValuePair<string, ImmutableArray<MultiBrushInfo>>(
|
||||
kv.Key,
|
||||
MultiBrushInfo.ParseCollection(kv.Value)))
|
||||
.ToImmutableDictionary()
|
||||
: ImmutableDictionary<string, IEnumerable<MultiBrushInfo>>.Empty;
|
||||
.ToFrozenDictionary()
|
||||
: FrozenDictionary<string, ImmutableArray<MultiBrushInfo>>.Empty;
|
||||
}
|
||||
|
||||
public TerrainTypeInfo this[byte index] => TerrainInfo[index];
|
||||
@@ -175,19 +179,19 @@ namespace OpenRA.Mods.Common.Terrain
|
||||
string ITerrainInfo.Id => Id;
|
||||
string ITerrainInfo.Name => Name;
|
||||
Size ITerrainInfo.TileSize => TileSize;
|
||||
TerrainTypeInfo[] ITerrainInfo.TerrainTypes => TerrainInfo;
|
||||
ImmutableArray<TerrainTypeInfo> ITerrainInfo.TerrainTypes => TerrainInfo;
|
||||
TerrainTileInfo ITerrainInfo.GetTerrainInfo(TerrainTile r) { return GetTileInfo(r); }
|
||||
bool ITerrainInfo.TryGetTerrainInfo(TerrainTile r, out TerrainTileInfo info) { return TryGetTileInfo(r, out info); }
|
||||
Color[] ITerrainInfo.HeightDebugColors => HeightDebugColors;
|
||||
ImmutableArray<Color> ITerrainInfo.HeightDebugColors => HeightDebugColors;
|
||||
IEnumerable<Color> ITerrainInfo.RestrictedPlayerColors { get { return TerrainInfo.Where(ti => ti.RestrictPlayerColor).Select(ti => ti.Color); } }
|
||||
float ITerrainInfo.MinHeightColorBrightness => MinHeightColorBrightness;
|
||||
float ITerrainInfo.MaxHeightColorBrightness => MaxHeightColorBrightness;
|
||||
|
||||
TerrainTile ITerrainInfo.DefaultTerrainTile => new(Templates.First().Key, 0);
|
||||
|
||||
string[] ITemplatedTerrainInfo.EditorTemplateOrder => EditorTemplateOrder;
|
||||
IReadOnlyDictionary<ushort, TerrainTemplateInfo> ITemplatedTerrainInfo.Templates => Templates;
|
||||
IReadOnlyDictionary<string, IEnumerable<MultiBrushInfo>> ITemplatedTerrainInfo.MultiBrushCollections => MultiBrushCollections;
|
||||
ImmutableArray<string> ITemplatedTerrainInfo.EditorTemplateOrder => EditorTemplateOrder;
|
||||
FrozenDictionary<ushort, TerrainTemplateInfo> ITemplatedTerrainInfo.Templates => Templates;
|
||||
FrozenDictionary<string, ImmutableArray<MultiBrushInfo>> ITemplatedTerrainInfo.MultiBrushCollections => MultiBrushCollections;
|
||||
|
||||
void IDumpSheetsTerrainInfo.DumpSheets(string terrainName, ImmutablePalette palette, ref int sheetCount)
|
||||
{
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using OpenRA.Graphics;
|
||||
@@ -83,7 +84,7 @@ namespace OpenRA.Mods.Common.Terrain
|
||||
}
|
||||
|
||||
var frameCount = terrainInfo.EnableDepth && depthFrames == null ? allFrames.Length / 2 : allFrames.Length;
|
||||
var indices = templateInfo.Frames ?? Exts.MakeArray(t.Value.TilesCount, j => j);
|
||||
var indices = templateInfo.Frames != null ? templateInfo.Frames : Exts.MakeArray(t.Value.TilesCount, j => j).ToImmutableArray();
|
||||
|
||||
var start = indices.Min();
|
||||
var end = indices.Max();
|
||||
|
||||
@@ -9,16 +9,17 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Frozen;
|
||||
using System.Collections.Immutable;
|
||||
using OpenRA.Mods.Common.MapGenerator;
|
||||
|
||||
namespace OpenRA.Mods.Common.Terrain
|
||||
{
|
||||
public interface ITemplatedTerrainInfo : ITerrainInfo
|
||||
{
|
||||
string[] EditorTemplateOrder { get; }
|
||||
IReadOnlyDictionary<ushort, TerrainTemplateInfo> Templates { get; }
|
||||
IReadOnlyDictionary<string, IEnumerable<MultiBrushInfo>> MultiBrushCollections { get; }
|
||||
ImmutableArray<string> EditorTemplateOrder { get; }
|
||||
FrozenDictionary<ushort, TerrainTemplateInfo> Templates { get; }
|
||||
FrozenDictionary<string, ImmutableArray<MultiBrushInfo>> MultiBrushCollections { get; }
|
||||
}
|
||||
|
||||
public interface ITerrainInfoNotifyMapCreated : ITerrainInfo
|
||||
@@ -31,7 +32,7 @@ namespace OpenRA.Mods.Common.Terrain
|
||||
public readonly ushort Id;
|
||||
public readonly int2 Size;
|
||||
public readonly bool PickAny;
|
||||
public readonly string[] Categories;
|
||||
public readonly ImmutableArray<string> Categories;
|
||||
|
||||
readonly TerrainTileInfo[] tileInfo;
|
||||
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Frozen;
|
||||
using System.Collections.Immutable;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
@@ -18,13 +19,13 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public class AcceptsDeliveredCashInfo : TraitInfo
|
||||
{
|
||||
[Desc("Accepted `DeliversCash` types. Leave empty to accept all types.")]
|
||||
public readonly HashSet<string> ValidTypes = [];
|
||||
public readonly FrozenSet<string> ValidTypes = FrozenSet<string>.Empty;
|
||||
|
||||
[Desc("Player relationships the owner of the delivering actor needs.")]
|
||||
public readonly PlayerRelationship ValidRelationships = PlayerRelationship.Ally;
|
||||
|
||||
[Desc("Play a randomly selected sound from this list when accepting cash.")]
|
||||
public readonly string[] Sounds = [];
|
||||
public readonly ImmutableArray<string> Sounds = [];
|
||||
|
||||
public override object Create(ActorInitializer init) { return new AcceptsDeliveredCash(this); }
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Frozen;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
@@ -18,7 +18,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public class AcceptsDeliveredExperienceInfo : TraitInfo, Requires<GainsExperienceInfo>
|
||||
{
|
||||
[Desc("Accepted `DeliversExperience` types. Leave empty to accept all types.")]
|
||||
public readonly HashSet<string> ValidTypes = [];
|
||||
public readonly FrozenSet<string> ValidTypes = FrozenSet<string>.Empty;
|
||||
|
||||
[Desc("Player relationships the owner of the delivering actor needs.")]
|
||||
public readonly PlayerRelationship ValidRelationships = PlayerRelationship.Ally;
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Frozen;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
@@ -17,7 +17,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public class ActorSpawnerInfo : ConditionalTraitInfo
|
||||
{
|
||||
[Desc("Type of ActorSpawner with which it connects.")]
|
||||
public readonly HashSet<string> Types = [];
|
||||
public readonly FrozenSet<string> Types = FrozenSet<string>.Empty;
|
||||
|
||||
public override object Create(ActorInitializer init) { return new ActorSpawner(this); }
|
||||
}
|
||||
@@ -27,6 +27,6 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public ActorSpawner(ActorSpawnerInfo info)
|
||||
: base(info) { }
|
||||
|
||||
public HashSet<string> Types => Info.Types;
|
||||
public FrozenSet<string> Types => Info.Types;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Frozen;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using OpenRA.Activities;
|
||||
using OpenRA.Mods.Common.Activities;
|
||||
@@ -83,7 +85,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Minimum altitude where this aircraft is considered airborne.")]
|
||||
public readonly int MinAirborneAltitude = 1;
|
||||
|
||||
public readonly HashSet<string> LandableTerrainTypes = [];
|
||||
public readonly FrozenSet<string> LandableTerrainTypes = FrozenSet<string>.Empty;
|
||||
|
||||
[Desc("Can the actor be ordered to move in to shroud?")]
|
||||
public readonly bool MoveIntoShroud = true;
|
||||
@@ -142,10 +144,10 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public readonly WDist AltitudeVelocity = new(43);
|
||||
|
||||
[Desc("Sounds to play when the actor is taking off.")]
|
||||
public readonly string[] TakeoffSounds = [];
|
||||
public readonly ImmutableArray<string> TakeoffSounds = [];
|
||||
|
||||
[Desc("Sounds to play when the actor is landing.")]
|
||||
public readonly string[] LandingSounds = [];
|
||||
public readonly ImmutableArray<string> LandingSounds = [];
|
||||
|
||||
[Desc("The distance of the resupply base that the aircraft will wait for its turn.")]
|
||||
public readonly WDist WaitDistanceFromResupplyBase = new(3072);
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Collections.Immutable;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
@@ -22,7 +22,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public readonly string Name = "primary";
|
||||
|
||||
[Desc("Name(s) of armament(s) that use this pool.")]
|
||||
public readonly string[] Armaments = ["primary", "secondary"];
|
||||
public readonly ImmutableArray<string> Armaments = ["primary", "secondary"];
|
||||
|
||||
[Desc("How much ammo does this pool contain when fully loaded.")]
|
||||
public readonly int Ammo = 1;
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using OpenRA.GameRules;
|
||||
using OpenRA.Mods.Common.Traits.Render;
|
||||
@@ -42,10 +43,10 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
[Desc("Muzzle position relative to turret or body, (forward, right, up) triples.",
|
||||
"If weapon Burst = 1, it cycles through all listed offsets, otherwise the offset corresponding to current burst is used.")]
|
||||
public readonly WVec[] LocalOffset = [];
|
||||
public readonly ImmutableArray<WVec> LocalOffset = [];
|
||||
|
||||
[Desc("Muzzle yaw relative to turret or body.")]
|
||||
public readonly WAngle[] LocalYaw = [];
|
||||
public readonly ImmutableArray<WAngle> LocalYaw = [];
|
||||
|
||||
[Desc("Move the turret backwards when firing.")]
|
||||
public readonly WDist Recoil = WDist.Zero;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user