feat(render): implement Campaign AR and terrain fidelity
This commit is contained in:
parent
99cf26e00c
commit
7a5f96ede5
368 changed files with 50611 additions and 950 deletions
|
|
@ -14,6 +14,117 @@ public enum ParticleRange
|
|||
Extended = 1,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Immutable, value-equal user overrides for one selected render pack. Keys
|
||||
/// are stable setting IDs and compare case-insensitively; values remain the
|
||||
/// declaration's invariant string representation until descriptor validation.
|
||||
/// </summary>
|
||||
public sealed class RenderPackSettingOverrides :
|
||||
IReadOnlyDictionary<string, string>,
|
||||
IEquatable<RenderPackSettingOverrides>
|
||||
{
|
||||
private readonly SortedDictionary<string, string> _values;
|
||||
|
||||
public static RenderPackSettingOverrides Empty { get; } = new([]);
|
||||
|
||||
public RenderPackSettingOverrides(
|
||||
IEnumerable<KeyValuePair<string, string>> values)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(values);
|
||||
_values = new SortedDictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
foreach ((string key, string value) in values)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(key);
|
||||
ArgumentNullException.ThrowIfNull(value);
|
||||
_values[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int Count => _values.Count;
|
||||
|
||||
public IEnumerable<string> Keys => _values.Keys;
|
||||
|
||||
public IEnumerable<string> Values => _values.Values;
|
||||
|
||||
public string this[string key] => _values[key];
|
||||
|
||||
public bool ContainsKey(string key) => _values.ContainsKey(key);
|
||||
|
||||
public bool TryGetValue(string key, out string value) =>
|
||||
_values.TryGetValue(key, out value!);
|
||||
|
||||
public IEnumerator<KeyValuePair<string, string>> GetEnumerator() =>
|
||||
_values.GetEnumerator();
|
||||
|
||||
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() =>
|
||||
GetEnumerator();
|
||||
|
||||
public RenderPackSettingOverrides Set(string settingId, string value)
|
||||
{
|
||||
ArgumentException.ThrowIfNullOrWhiteSpace(settingId);
|
||||
ArgumentNullException.ThrowIfNull(value);
|
||||
var next = new SortedDictionary<string, string>(
|
||||
_values,
|
||||
StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
[settingId] = value,
|
||||
};
|
||||
return new RenderPackSettingOverrides(next);
|
||||
}
|
||||
|
||||
public bool Equals(RenderPackSettingOverrides? other) =>
|
||||
other is not null
|
||||
&& _values.Count == other._values.Count
|
||||
&& _values.All(pair => other._values.TryGetValue(pair.Key, out string? value)
|
||||
&& string.Equals(pair.Value, value, StringComparison.Ordinal));
|
||||
|
||||
public override bool Equals(object? obj) =>
|
||||
obj is RenderPackSettingOverrides other && Equals(other);
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
var hash = new HashCode();
|
||||
foreach ((string key, string value) in _values)
|
||||
{
|
||||
hash.Add(key, StringComparer.OrdinalIgnoreCase);
|
||||
hash.Add(value, StringComparer.Ordinal);
|
||||
}
|
||||
return hash.ToHashCode();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stable, user-authored selection of one optional render pack. Logical ids
|
||||
/// are persisted instead of menu indexes so discovery order can never select a
|
||||
/// different pack or preset after an install/update. The renderer normalizes a
|
||||
/// missing, malformed, unavailable, or incompatible selection back to
|
||||
/// <see cref="Retail"/> and retains the precise reason for diagnostics.
|
||||
/// </summary>
|
||||
public sealed record RenderPackSelectionSettings(
|
||||
string PackId,
|
||||
string? PackVersion,
|
||||
string PresetId)
|
||||
{
|
||||
public const string RetailPackId = "retail";
|
||||
public const string RetailPresetId = "off";
|
||||
|
||||
public static RenderPackSelectionSettings Retail { get; } = new(
|
||||
RetailPackId,
|
||||
PackVersion: null,
|
||||
RetailPresetId);
|
||||
|
||||
/// <summary>
|
||||
/// User-authored values keyed by the selected pack's stable setting IDs.
|
||||
/// Empty by default so pre-render-pack settings files upgrade without a
|
||||
/// migration write.
|
||||
/// </summary>
|
||||
public RenderPackSettingOverrides SettingOverrides { get; init; } =
|
||||
RenderPackSettingOverrides.Empty;
|
||||
|
||||
public bool IsRetail =>
|
||||
string.Equals(PackId, RetailPackId, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Display-related preferences persisted to <c>settings.json</c>.
|
||||
/// Originally documented as "no retail equivalent for FOV / vsync etc" —
|
||||
|
|
@ -77,6 +188,16 @@ public sealed record DisplaySettings(
|
|||
bool BuildingDetailTextures = true,
|
||||
bool MultiPassAlpha = false)
|
||||
{
|
||||
/// <summary>
|
||||
/// Opt-in graphics enhancement selection. This is deliberately separate
|
||||
/// from <see cref="Quality"/>, which remains the authoritative retail
|
||||
/// renderer/streaming quality preset. Keeping the default here means an
|
||||
/// upgraded settings file that predates shader packs deserializes to the
|
||||
/// exact retail path without a migration write.
|
||||
/// </summary>
|
||||
public RenderPackSelectionSettings RenderPack { get; init; } =
|
||||
RenderPackSelectionSettings.Retail;
|
||||
|
||||
/// <summary>Values used on first launch / when settings.json is absent.
|
||||
/// Geometry defaults preserve the pre-L.0 runtime state: Resolution
|
||||
/// matches the WindowOptions startup size (1280×720). FieldOfView is
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue