Ownership data
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
using ZeroSpace.Model;
|
||||
|
||||
namespace ZeroSpace.MapEditor.Models;
|
||||
|
||||
public enum FactionMode
|
||||
{
|
||||
None,
|
||||
EdenAccord, // Hotkey A - #10b981
|
||||
KeeperCouncil, // Hotkey S - #38bdf8
|
||||
ObsidianOrder // Hotkey D - #ef4444
|
||||
}
|
||||
|
||||
public static class FactionModeExtensions
|
||||
{
|
||||
public static string ToOwnerName(this FactionMode mode) => mode switch
|
||||
{
|
||||
FactionMode.EdenAccord => StarSystemOwners.EdenAccord,
|
||||
FactionMode.KeeperCouncil => StarSystemOwners.KeeperCouncil,
|
||||
FactionMode.ObsidianOrder => StarSystemOwners.ObsidianOrder,
|
||||
_ => string.Empty
|
||||
};
|
||||
|
||||
public static string ToDisplayName(this FactionMode mode) => mode switch
|
||||
{
|
||||
FactionMode.EdenAccord => "Eden Accord",
|
||||
FactionMode.KeeperCouncil => "Keeper Council",
|
||||
FactionMode.ObsidianOrder => "Obsidian Order",
|
||||
_ => "None"
|
||||
};
|
||||
|
||||
public static string GetColorHex(this FactionMode mode) => mode switch
|
||||
{
|
||||
FactionMode.EdenAccord => StarSystemOwners.GetColor(StarSystemOwners.EdenAccord),
|
||||
FactionMode.KeeperCouncil => StarSystemOwners.GetColor(StarSystemOwners.KeeperCouncil),
|
||||
FactionMode.ObsidianOrder => StarSystemOwners.GetColor(StarSystemOwners.ObsidianOrder),
|
||||
_ => "#94a3b8"
|
||||
};
|
||||
|
||||
public static FactionMode FromOwnerName(string? owner) => owner switch
|
||||
{
|
||||
StarSystemOwners.EdenAccord => FactionMode.EdenAccord,
|
||||
StarSystemOwners.KeeperCouncil => FactionMode.KeeperCouncil,
|
||||
StarSystemOwners.ObsidianOrder => FactionMode.ObsidianOrder,
|
||||
_ => FactionMode.None
|
||||
};
|
||||
}
|
||||
@@ -9,10 +9,23 @@ namespace ZeroSpace.MapEditor.Services;
|
||||
/// </summary>
|
||||
public sealed class StarSystemDoc
|
||||
{
|
||||
private string _owner = string.Empty;
|
||||
|
||||
public string FilePath { get; set; } = string.Empty;
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string SystemCategory { get; set; } = string.Empty;
|
||||
public string Owner { get; set; } = string.Empty;
|
||||
public string Owner
|
||||
{
|
||||
get => _owner;
|
||||
set
|
||||
{
|
||||
if (!string.Equals(_owner, value, StringComparison.Ordinal))
|
||||
{
|
||||
_owner = value;
|
||||
IsDirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
public bool HigherInfluenceYield { get; set; }
|
||||
public bool HigherCreditYield { get; set; }
|
||||
public bool HigherEnergyYield { get; set; }
|
||||
@@ -151,27 +164,30 @@ public static class StarSystemDocStore
|
||||
doc.HasPosition = true;
|
||||
}
|
||||
|
||||
doc.IsDirty = false;
|
||||
return doc;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes x/y back into each dirty file's frontmatter, preserving
|
||||
/// Writes x/y and owner back into each dirty file's frontmatter, preserving
|
||||
/// every other line byte-for-byte.
|
||||
/// </summary>
|
||||
public static int SavePositions(IEnumerable<StarSystemDoc> docs)
|
||||
public static int SaveDocs(IEnumerable<StarSystemDoc> docs)
|
||||
{
|
||||
var count = 0;
|
||||
var errors = new List<Exception>();
|
||||
var items = docs.Where(static d => d.IsDirty)
|
||||
.Select(static d => (Doc: d, TargetX: d.X, TargetY: d.Y))
|
||||
.Select(static d => (Doc: d, TargetX: d.X, TargetY: d.Y, TargetOwner: d.Owner))
|
||||
.ToList();
|
||||
|
||||
foreach (var item in items)
|
||||
{
|
||||
try
|
||||
{
|
||||
SavePosition(item.Doc.FilePath, item.TargetX, item.TargetY);
|
||||
if (item.Doc.X == item.TargetX && item.Doc.Y == item.TargetY)
|
||||
SaveDoc(item.Doc.FilePath, item.TargetX, item.TargetY, item.TargetOwner);
|
||||
if (item.Doc.X == item.TargetX &&
|
||||
item.Doc.Y == item.TargetY &&
|
||||
string.Equals(item.Doc.Owner, item.TargetOwner, StringComparison.Ordinal))
|
||||
{
|
||||
item.Doc.IsDirty = false;
|
||||
}
|
||||
@@ -197,12 +213,24 @@ public static class StarSystemDocStore
|
||||
return count;
|
||||
}
|
||||
|
||||
public static void SavePosition(StarSystemDoc doc)
|
||||
/// <summary>
|
||||
/// Backwards-compatible alias for <see cref="SaveDocs"/>.
|
||||
/// </summary>
|
||||
public static int SavePositions(IEnumerable<StarSystemDoc> docs) => SaveDocs(docs);
|
||||
|
||||
public static void SaveDoc(StarSystemDoc doc)
|
||||
{
|
||||
SavePosition(doc.FilePath, doc.X, doc.Y);
|
||||
SaveDoc(doc.FilePath, doc.X, doc.Y, doc.Owner);
|
||||
}
|
||||
|
||||
public static void SavePosition(StarSystemDoc doc) => SaveDoc(doc);
|
||||
|
||||
public static void SavePosition(string filePath, double x, double y)
|
||||
{
|
||||
SaveDoc(filePath, x, y, owner: null);
|
||||
}
|
||||
|
||||
public static void SaveDoc(string filePath, double x, double y, string? owner = null)
|
||||
{
|
||||
var text = File.ReadAllText(filePath);
|
||||
var newline = text.Contains("\r\n", StringComparison.Ordinal) ? "\r\n" : "\n";
|
||||
@@ -220,8 +248,10 @@ public static class StarSystemDocStore
|
||||
|
||||
var xLine = $"x: {x.ToString("F1", CultureInfo.InvariantCulture)}";
|
||||
var yLine = $"y: {y.ToString("F1", CultureInfo.InvariantCulture)}";
|
||||
var ownerLine = owner is not null ? $"owner: {owner}" : null;
|
||||
var foundX = false;
|
||||
var foundY = false;
|
||||
var foundOwner = false;
|
||||
|
||||
for (var i = 1; i < closeIndex; i++)
|
||||
{
|
||||
@@ -236,6 +266,17 @@ public static class StarSystemDocStore
|
||||
lines[i] = yLine;
|
||||
foundY = true;
|
||||
}
|
||||
else if (ownerLine is not null && string.Equals(key, "owner", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
lines[i] = ownerLine;
|
||||
foundOwner = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (ownerLine is not null && !foundOwner)
|
||||
{
|
||||
lines.Insert(closeIndex, ownerLine);
|
||||
closeIndex++;
|
||||
}
|
||||
|
||||
if (!foundX)
|
||||
|
||||
@@ -4,25 +4,44 @@
|
||||
x:Class="ZeroSpace.MapEditor.Views.MapEditorPage"
|
||||
Title="ZeroSpace Map Editor">
|
||||
<Grid RowDefinitions="Auto,*" ColumnDefinitions="*,340">
|
||||
<HorizontalStackLayout Grid.Row="0" Grid.ColumnSpan="2" Padding="8" Spacing="8">
|
||||
<Button Text="Open Folder" Clicked="OnOpenFolderClicked" />
|
||||
<Button x:Name="SaveButton" Text="Saved" Clicked="OnSaveClicked" IsEnabled="False" />
|
||||
<Button Text="+" WidthRequest="44" Clicked="OnZoomInClicked" />
|
||||
<Button Text="−" WidthRequest="44" Clicked="OnZoomOutClicked" />
|
||||
<Button Text="Reset View" Clicked="OnResetViewClicked" />
|
||||
<Button x:Name="PanModeButton" Text="Pan: Off" Clicked="OnPanModeClicked" />
|
||||
<CheckBox x:Name="BackgroundCheckBox" IsChecked="True" CheckedChanged="OnBackgroundToggled" VerticalOptions="Center" />
|
||||
<Label Text="Galaxy map" VerticalOptions="Center" />
|
||||
<SearchBar x:Name="SearchControl"
|
||||
Placeholder="Search systems..."
|
||||
WidthRequest="220"
|
||||
TextChanged="OnSearchTextChanged"
|
||||
SearchButtonPressed="OnSearchButtonPressed" />
|
||||
<Label x:Name="StatusLabel"
|
||||
Text="No folder loaded."
|
||||
VerticalOptions="Center"
|
||||
Margin="8,0,0,0" />
|
||||
</HorizontalStackLayout>
|
||||
<ScrollView Grid.Row="0" Grid.ColumnSpan="2" Orientation="Horizontal" HorizontalScrollBarVisibility="Never">
|
||||
<HorizontalStackLayout Padding="8" Spacing="8" VerticalOptions="Center">
|
||||
<Button Text="Open Folder" Clicked="OnOpenFolderClicked" />
|
||||
<Button x:Name="SaveButton" Text="Saved" Clicked="OnSaveClicked" IsEnabled="False" />
|
||||
<Button Text="+" WidthRequest="44" Clicked="OnZoomInClicked" />
|
||||
<Button Text="−" WidthRequest="44" Clicked="OnZoomOutClicked" />
|
||||
<Button Text="Reset View" Clicked="OnResetViewClicked" />
|
||||
<Button x:Name="PanModeButton" Text="Pan: Off" Clicked="OnPanModeClicked" />
|
||||
<CheckBox x:Name="BackgroundCheckBox" IsChecked="True" CheckedChanged="OnBackgroundToggled" VerticalOptions="Center" />
|
||||
<Label Text="Galaxy map" VerticalOptions="Center" />
|
||||
<BoxView WidthRequest="1" HeightRequest="24" Color="#334155" VerticalOptions="Center" Margin="4,0" />
|
||||
<Label Text="Faction:" VerticalOptions="Center" FontAttributes="Bold" />
|
||||
<Button x:Name="EdenFactionButton" Text="[A] Eden Accord" Clicked="OnEdenFactionClicked" />
|
||||
<Button x:Name="KeeperFactionButton" Text="[S] Keeper Council" Clicked="OnKeeperFactionClicked" />
|
||||
<Button x:Name="ObsidianFactionButton" Text="[D] Obsidian Order" Clicked="OnObsidianFactionClicked" />
|
||||
<Button x:Name="NoneFactionButton" Text="None" Clicked="OnNoneFactionClicked" />
|
||||
<Border x:Name="ActiveFactionBadge"
|
||||
StrokeShape="RoundRectangle 4"
|
||||
StrokeThickness="1"
|
||||
Padding="6,2"
|
||||
VerticalOptions="Center"
|
||||
IsVisible="False">
|
||||
<Label x:Name="ActiveFactionLabel"
|
||||
FontSize="12"
|
||||
FontAttributes="Bold" />
|
||||
</Border>
|
||||
<BoxView WidthRequest="1" HeightRequest="24" Color="#334155" VerticalOptions="Center" Margin="4,0" />
|
||||
<SearchBar x:Name="SearchControl"
|
||||
Placeholder="Search systems..."
|
||||
WidthRequest="220"
|
||||
TextChanged="OnSearchTextChanged"
|
||||
SearchButtonPressed="OnSearchButtonPressed" />
|
||||
<Label x:Name="StatusLabel"
|
||||
Text="No folder loaded."
|
||||
VerticalOptions="Center"
|
||||
Margin="8,0,0,0" />
|
||||
</HorizontalStackLayout>
|
||||
</ScrollView>
|
||||
|
||||
<GraphicsView Grid.Row="1" Grid.Column="0" x:Name="MapView">
|
||||
<GraphicsView.GestureRecognizers>
|
||||
@@ -43,7 +62,15 @@
|
||||
<Label x:Name="CategoryLabel" />
|
||||
|
||||
<Label Text="Owner" FontAttributes="Bold" />
|
||||
<Label x:Name="OwnerLabel" />
|
||||
<Border x:Name="OwnerBadge"
|
||||
StrokeShape="RoundRectangle 6"
|
||||
StrokeThickness="1"
|
||||
Padding="8,4"
|
||||
HorizontalOptions="Start"
|
||||
BackgroundColor="#1e293b"
|
||||
Stroke="#334155">
|
||||
<Label x:Name="OwnerLabel" Text="—" FontAttributes="Bold" TextColor="#94a3b8" />
|
||||
</Border>
|
||||
|
||||
<Label Text="Yields" FontAttributes="Bold" />
|
||||
<Label x:Name="YieldsLabel" />
|
||||
|
||||
@@ -2,6 +2,7 @@ using System.Globalization;
|
||||
using CommunityToolkit.Maui.Storage;
|
||||
using ZeroSpace.MapEditor.Models;
|
||||
using ZeroSpace.MapEditor.Services;
|
||||
using ZeroSpace.Model;
|
||||
|
||||
namespace ZeroSpace.MapEditor.Views;
|
||||
|
||||
@@ -34,9 +35,14 @@ public partial class MapEditorPage : ContentPage
|
||||
public MapEditorPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
UpdateFactionModeUI();
|
||||
_drawable.FindNode = name => _byName.TryGetValue(name, out var node) ? node : null;
|
||||
MapView.Drawable = _drawable;
|
||||
MapView.SizeChanged += OnMapViewSizeChanged;
|
||||
#if WINDOWS
|
||||
Loaded += OnPageLoaded;
|
||||
Unloaded += OnPageUnloaded;
|
||||
#endif
|
||||
TryAutoLoad();
|
||||
LoadGalaxyMapAsync();
|
||||
}
|
||||
@@ -127,6 +133,223 @@ public partial class MapEditorPage : ContentPage
|
||||
: "Select mode enabled. Drag empty space to multi-select.";
|
||||
}
|
||||
|
||||
// ----- faction mode -----
|
||||
|
||||
private FactionMode _activeFaction = FactionMode.None;
|
||||
|
||||
public FactionMode ActiveFaction => _activeFaction;
|
||||
|
||||
public void SetActiveFactionMode(FactionMode mode)
|
||||
{
|
||||
_activeFaction = mode;
|
||||
UpdateFactionModeUI();
|
||||
if (_activeFaction != FactionMode.None)
|
||||
{
|
||||
StatusLabel.Text = $"Faction painting mode: {_activeFaction.ToDisplayName()} (Click system or press A/S/D).";
|
||||
}
|
||||
}
|
||||
|
||||
public void HandleFactionHotkey(FactionMode mode)
|
||||
{
|
||||
SetActiveFactionMode(mode);
|
||||
var targets = _selectedNodes.Count > 0
|
||||
? _selectedNodes.ToList()
|
||||
: (_selected is not null ? new List<MapNode> { _selected } : null);
|
||||
|
||||
if (targets is not null && targets.Count > 0)
|
||||
{
|
||||
ApplyFactionToNodes(targets, mode);
|
||||
}
|
||||
}
|
||||
|
||||
public void ApplyFactionToNodes(IEnumerable<MapNode> nodes, FactionMode mode)
|
||||
{
|
||||
var ownerName = mode.ToOwnerName();
|
||||
var anyChanged = false;
|
||||
foreach (var node in nodes)
|
||||
{
|
||||
if (!string.Equals(node.Doc.Owner, ownerName, StringComparison.Ordinal))
|
||||
{
|
||||
node.Doc.Owner = ownerName;
|
||||
anyChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (anyChanged)
|
||||
{
|
||||
UpdateDirtyState();
|
||||
if (_selected is not null)
|
||||
{
|
||||
PopulateInspector(_selected);
|
||||
}
|
||||
|
||||
MapView.Invalidate();
|
||||
ScheduleAutoSave();
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsTextInputFocused()
|
||||
{
|
||||
if (SearchControl.IsFocused || XEntry.IsFocused || YEntry.IsFocused)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
#if WINDOWS
|
||||
if (Handler?.PlatformView is Microsoft.UI.Xaml.FrameworkElement fe && fe.XamlRoot is not null)
|
||||
{
|
||||
var focused = Microsoft.UI.Xaml.Input.FocusManager.GetFocusedElement(fe.XamlRoot);
|
||||
if (focused is Microsoft.UI.Xaml.Controls.TextBox ||
|
||||
focused is Microsoft.UI.Xaml.Controls.AutoSuggestBox ||
|
||||
focused is Microsoft.UI.Xaml.Controls.RichEditBox ||
|
||||
focused is Microsoft.UI.Xaml.Controls.PasswordBox)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#if WINDOWS
|
||||
private Microsoft.UI.Xaml.UIElement? _keyElement;
|
||||
private Microsoft.UI.Xaml.Input.KeyEventHandler? _keyHandler;
|
||||
|
||||
private void OnPageLoaded(object? sender, EventArgs e)
|
||||
{
|
||||
if (Handler?.PlatformView is Microsoft.UI.Xaml.FrameworkElement fe)
|
||||
{
|
||||
_keyHandler = new Microsoft.UI.Xaml.Input.KeyEventHandler(OnPlatformKeyDown);
|
||||
_keyElement = fe.XamlRoot?.Content as Microsoft.UI.Xaml.UIElement ?? fe;
|
||||
_keyElement.AddHandler(Microsoft.UI.Xaml.UIElement.KeyDownEvent, _keyHandler, handledEventsToo: true);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnPageUnloaded(object? sender, EventArgs e)
|
||||
{
|
||||
if (_keyHandler is not null)
|
||||
{
|
||||
if (_keyElement is not null)
|
||||
{
|
||||
_keyElement.RemoveHandler(Microsoft.UI.Xaml.UIElement.KeyDownEvent, _keyHandler);
|
||||
_keyElement = null;
|
||||
}
|
||||
|
||||
_keyHandler = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnPlatformKeyDown(object sender, Microsoft.UI.Xaml.Input.KeyRoutedEventArgs e)
|
||||
{
|
||||
if (IsTextInputFocused())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var ctrlDown = Microsoft.UI.Input.InputKeyboardSource
|
||||
.GetKeyStateForCurrentThread(global::Windows.System.VirtualKey.Control)
|
||||
.HasFlag(global::Windows.UI.Core.CoreVirtualKeyStates.Down);
|
||||
var altDown = e.KeyStatus.IsMenuKeyDown || Microsoft.UI.Input.InputKeyboardSource
|
||||
.GetKeyStateForCurrentThread(global::Windows.System.VirtualKey.Menu)
|
||||
.HasFlag(global::Windows.UI.Core.CoreVirtualKeyStates.Down);
|
||||
|
||||
if (ctrlDown || altDown)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch (e.Key)
|
||||
{
|
||||
case global::Windows.System.VirtualKey.A:
|
||||
HandleFactionHotkey(FactionMode.EdenAccord);
|
||||
e.Handled = true;
|
||||
break;
|
||||
case global::Windows.System.VirtualKey.S:
|
||||
HandleFactionHotkey(FactionMode.KeeperCouncil);
|
||||
e.Handled = true;
|
||||
break;
|
||||
case global::Windows.System.VirtualKey.D:
|
||||
HandleFactionHotkey(FactionMode.ObsidianOrder);
|
||||
e.Handled = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
private void OnEdenFactionClicked(object? sender, EventArgs e) =>
|
||||
ToggleOrSetFactionMode(FactionMode.EdenAccord);
|
||||
|
||||
private void OnKeeperFactionClicked(object? sender, EventArgs e) =>
|
||||
ToggleOrSetFactionMode(FactionMode.KeeperCouncil);
|
||||
|
||||
private void OnObsidianFactionClicked(object? sender, EventArgs e) =>
|
||||
ToggleOrSetFactionMode(FactionMode.ObsidianOrder);
|
||||
|
||||
private void OnNoneFactionClicked(object? sender, EventArgs e) =>
|
||||
SetActiveFactionMode(FactionMode.None);
|
||||
|
||||
private void ToggleOrSetFactionMode(FactionMode mode)
|
||||
{
|
||||
var targetMode = _activeFaction == mode ? FactionMode.None : mode;
|
||||
SetActiveFactionMode(targetMode);
|
||||
if (targetMode != FactionMode.None && _selectedNodes.Count > 0)
|
||||
{
|
||||
ApplyFactionToNodes(_selectedNodes, targetMode);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateFactionModeUI()
|
||||
{
|
||||
// Eden Accord [A]
|
||||
var isEden = _activeFaction == FactionMode.EdenAccord;
|
||||
EdenFactionButton.BackgroundColor = isEden ? Color.FromArgb("#10b981") : Color.FromArgb("#1e293b");
|
||||
EdenFactionButton.TextColor = isEden ? Colors.White : Color.FromArgb("#10b981");
|
||||
EdenFactionButton.BorderColor = isEden ? Color.FromArgb("#059669") : Color.FromArgb("#10b981");
|
||||
EdenFactionButton.BorderWidth = isEden ? 2 : 1;
|
||||
EdenFactionButton.FontAttributes = isEden ? FontAttributes.Bold : FontAttributes.None;
|
||||
|
||||
// Keeper Council [S]
|
||||
var isKeeper = _activeFaction == FactionMode.KeeperCouncil;
|
||||
KeeperFactionButton.BackgroundColor = isKeeper ? Color.FromArgb("#38bdf8") : Color.FromArgb("#1e293b");
|
||||
KeeperFactionButton.TextColor = isKeeper ? Color.FromArgb("#0f172a") : Color.FromArgb("#38bdf8");
|
||||
KeeperFactionButton.BorderColor = isKeeper ? Color.FromArgb("#0284c7") : Color.FromArgb("#38bdf8");
|
||||
KeeperFactionButton.BorderWidth = isKeeper ? 2 : 1;
|
||||
KeeperFactionButton.FontAttributes = isKeeper ? FontAttributes.Bold : FontAttributes.None;
|
||||
|
||||
// Obsidian Order [D]
|
||||
var isObsidian = _activeFaction == FactionMode.ObsidianOrder;
|
||||
ObsidianFactionButton.BackgroundColor = isObsidian ? Color.FromArgb("#ef4444") : Color.FromArgb("#1e293b");
|
||||
ObsidianFactionButton.TextColor = isObsidian ? Colors.White : Color.FromArgb("#ef4444");
|
||||
ObsidianFactionButton.BorderColor = isObsidian ? Color.FromArgb("#dc2626") : Color.FromArgb("#ef4444");
|
||||
ObsidianFactionButton.BorderWidth = isObsidian ? 2 : 1;
|
||||
ObsidianFactionButton.FontAttributes = isObsidian ? FontAttributes.Bold : FontAttributes.None;
|
||||
|
||||
// None
|
||||
var isNone = _activeFaction == FactionMode.None;
|
||||
NoneFactionButton.BackgroundColor = isNone ? Color.FromArgb("#475569") : Color.FromArgb("#1e293b");
|
||||
NoneFactionButton.TextColor = isNone ? Colors.White : Color.FromArgb("#94a3b8");
|
||||
NoneFactionButton.BorderColor = isNone ? Color.FromArgb("#64748b") : Color.FromArgb("#475569");
|
||||
NoneFactionButton.BorderWidth = isNone ? 2 : 1;
|
||||
NoneFactionButton.FontAttributes = isNone ? FontAttributes.Bold : FontAttributes.None;
|
||||
|
||||
// Badge indicator
|
||||
if (_activeFaction != FactionMode.None)
|
||||
{
|
||||
var hex = _activeFaction.GetColorHex();
|
||||
var factionColor = Color.FromArgb(hex);
|
||||
ActiveFactionBadge.IsVisible = true;
|
||||
ActiveFactionBadge.Stroke = factionColor;
|
||||
ActiveFactionBadge.BackgroundColor = factionColor.WithAlpha(0.2f);
|
||||
ActiveFactionLabel.Text = $"Active: {_activeFaction.ToDisplayName()}";
|
||||
ActiveFactionLabel.TextColor = factionColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
ActiveFactionBadge.IsVisible = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void CenterOnNode(MapNode node)
|
||||
{
|
||||
var width = MapView.Width;
|
||||
@@ -325,7 +548,7 @@ public partial class MapEditorPage : ContentPage
|
||||
_pressNode.IsSelected = true;
|
||||
SetActiveNode(_pressNode);
|
||||
InspectorScroll.IsVisible = true;
|
||||
PopulateInspector(_selected);
|
||||
PopulateInspector(_pressNode);
|
||||
}
|
||||
|
||||
MapView.Invalidate();
|
||||
@@ -336,7 +559,7 @@ public partial class MapEditorPage : ContentPage
|
||||
{
|
||||
_wasAlreadySelectedInGroup = _selectedNodes.Count > 1;
|
||||
SetActiveNode(_pressNode);
|
||||
PopulateInspector(_selected);
|
||||
PopulateInspector(_pressNode);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -478,6 +701,10 @@ public partial class MapEditorPage : ContentPage
|
||||
{
|
||||
var hit = HitTest(position.Value);
|
||||
Select(hit);
|
||||
if (hit is not null && _activeFaction != FactionMode.None)
|
||||
{
|
||||
ApplyFactionToNodes(new[] { hit }, _activeFaction);
|
||||
}
|
||||
}
|
||||
|
||||
_panning = false;
|
||||
@@ -485,6 +712,7 @@ public partial class MapEditorPage : ContentPage
|
||||
else if (_pressNode is not null)
|
||||
{
|
||||
var wasDragging = _draggingNode;
|
||||
var clickedNode = _pressNode;
|
||||
if (!_draggingNode && _wasAlreadySelectedInGroup)
|
||||
{
|
||||
Select(_pressNode);
|
||||
@@ -497,6 +725,10 @@ public partial class MapEditorPage : ContentPage
|
||||
{
|
||||
_ = AutoSaveAsync();
|
||||
}
|
||||
else if (_activeFaction != FactionMode.None)
|
||||
{
|
||||
ApplyFactionToNodes(new[] { clickedNode }, _activeFaction);
|
||||
}
|
||||
}
|
||||
else if (_marqueeSelecting)
|
||||
{
|
||||
@@ -652,11 +884,12 @@ public partial class MapEditorPage : ContentPage
|
||||
}
|
||||
else
|
||||
{
|
||||
SetActiveNode(primary ?? (_selected is not null && _selectedNodes.Contains(_selected)
|
||||
var primaryNode = primary ?? (_selected is not null && _selectedNodes.Contains(_selected)
|
||||
? _selected
|
||||
: _selectedNodes.First()));
|
||||
: _selectedNodes.First());
|
||||
SetActiveNode(primaryNode);
|
||||
InspectorScroll.IsVisible = true;
|
||||
PopulateInspector(_selected);
|
||||
PopulateInspector(primaryNode);
|
||||
if (_selectedNodes.Count > 1)
|
||||
{
|
||||
StatusLabel.Text = $"{_selectedNodes.Count} systems selected.";
|
||||
@@ -695,7 +928,14 @@ public partial class MapEditorPage : ContentPage
|
||||
var doc = node.Doc;
|
||||
NameLabel.Text = doc.Name;
|
||||
CategoryLabel.Text = string.IsNullOrEmpty(doc.SystemCategory) ? "—" : doc.SystemCategory;
|
||||
OwnerLabel.Text = string.IsNullOrEmpty(doc.Owner) ? "—" : doc.Owner;
|
||||
var owner = doc.Owner;
|
||||
OwnerLabel.Text = string.IsNullOrEmpty(owner) ? "—" : owner;
|
||||
var ownerColor = Color.FromArgb(StarSystemOwners.GetColor(owner));
|
||||
OwnerLabel.TextColor = string.IsNullOrEmpty(owner) ? Color.FromArgb("#94a3b8") : ownerColor;
|
||||
OwnerBadge.Stroke = string.IsNullOrEmpty(owner) ? Color.FromArgb("#334155") : ownerColor;
|
||||
OwnerBadge.BackgroundColor = string.IsNullOrEmpty(owner)
|
||||
? Color.FromArgb("#1e293b")
|
||||
: ownerColor.WithAlpha(0.15f);
|
||||
YieldsLabel.Text = YieldText(doc);
|
||||
BuffLabel.Text = doc.OccupationBuff ?? "—";
|
||||
MasteryLabel.Text = doc.SystemMastery ?? "—";
|
||||
@@ -913,7 +1153,7 @@ public partial class MapEditorPage : ContentPage
|
||||
SaveButton.Text = "Save";
|
||||
SaveButton.IsEnabled = true;
|
||||
StatusLabel.Text =
|
||||
$"{remainingDirty} unsaved position change{(remainingDirty == 1 ? string.Empty : "s")}.";
|
||||
$"{remainingDirty} unsaved change{(remainingDirty == 1 ? string.Empty : "s")}.";
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -944,7 +1184,7 @@ public partial class MapEditorPage : ContentPage
|
||||
{
|
||||
SaveButton.Text = "Save";
|
||||
SaveButton.IsEnabled = true;
|
||||
StatusLabel.Text = $"{dirty} unsaved position change{(dirty == 1 ? string.Empty : "s")}.";
|
||||
StatusLabel.Text = $"{dirty} unsaved change{(dirty == 1 ? string.Empty : "s")}.";
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ZeroSpace.Model\ZeroSpace.Model.csproj" />
|
||||
<PackageReference Include="Microsoft.Maui.Controls" Version="10.0.110" />
|
||||
<PackageReference Include="CommunityToolkit.Maui.Core" Version="15.0.1" />
|
||||
<!-- In-game galaxy map screenshot shown as the canvas background. -->
|
||||
|
||||
@@ -23,7 +23,7 @@ public static class StarSystems
|
||||
Id: "AquilaRift",
|
||||
Name: "Aquila Rift",
|
||||
SystemCategory: StarSystemCategory.SideSystem,
|
||||
Owner: "The Eden Accord",
|
||||
Owner: "The Keeper Council",
|
||||
HigherInfluenceYield: false,
|
||||
HigherCreditYield: false,
|
||||
HigherEnergyYield: false,
|
||||
@@ -39,7 +39,7 @@ public static class StarSystems
|
||||
Id: "ArtemisGrotto",
|
||||
Name: "Artemis Grotto",
|
||||
SystemCategory: StarSystemCategory.HomeworldSystem,
|
||||
Owner: "The Eden Accord",
|
||||
Owner: "The Keeper Council",
|
||||
HigherInfluenceYield: false,
|
||||
HigherCreditYield: false,
|
||||
HigherEnergyYield: false,
|
||||
@@ -119,7 +119,7 @@ public static class StarSystems
|
||||
Id: "BurningCairn",
|
||||
Name: "Burning Cairn",
|
||||
SystemCategory: StarSystemCategory.SideSystem,
|
||||
Owner: "The Eden Accord",
|
||||
Owner: "The Keeper Council",
|
||||
HigherInfluenceYield: false,
|
||||
HigherCreditYield: false,
|
||||
HigherEnergyYield: false,
|
||||
@@ -135,7 +135,7 @@ public static class StarSystems
|
||||
Id: "CalmBelt",
|
||||
Name: "Calm Belt",
|
||||
SystemCategory: StarSystemCategory.SideSystem,
|
||||
Owner: "The Eden Accord",
|
||||
Owner: "The Keeper Council",
|
||||
HigherInfluenceYield: false,
|
||||
HigherCreditYield: false,
|
||||
HigherEnergyYield: false,
|
||||
@@ -183,7 +183,7 @@ public static class StarSystems
|
||||
Id: "CrimsonExpanse",
|
||||
Name: "Crimson Expanse",
|
||||
SystemCategory: StarSystemCategory.CoreSystem,
|
||||
Owner: "The Eden Accord",
|
||||
Owner: "The Keeper Council",
|
||||
HigherInfluenceYield: false,
|
||||
HigherCreditYield: false,
|
||||
HigherEnergyYield: false,
|
||||
@@ -215,7 +215,7 @@ public static class StarSystems
|
||||
Id: "DevilSTrident",
|
||||
Name: "Devil's Trident",
|
||||
SystemCategory: StarSystemCategory.CoreSystem,
|
||||
Owner: "The Eden Accord",
|
||||
Owner: "The Keeper Council",
|
||||
HigherInfluenceYield: false,
|
||||
HigherCreditYield: true,
|
||||
HigherEnergyYield: false,
|
||||
@@ -231,7 +231,7 @@ public static class StarSystems
|
||||
Id: "DraconisReach",
|
||||
Name: "Draconis Reach",
|
||||
SystemCategory: StarSystemCategory.SideSystem,
|
||||
Owner: "The Eden Accord",
|
||||
Owner: "The Keeper Council",
|
||||
HigherInfluenceYield: false,
|
||||
HigherCreditYield: false,
|
||||
HigherEnergyYield: false,
|
||||
@@ -247,7 +247,7 @@ public static class StarSystems
|
||||
Id: "EbonyKeep",
|
||||
Name: "Ebony Keep",
|
||||
SystemCategory: StarSystemCategory.CoreSystem,
|
||||
Owner: "The Eden Accord",
|
||||
Owner: "The Obsidian Order",
|
||||
HigherInfluenceYield: true,
|
||||
HigherCreditYield: false,
|
||||
HigherEnergyYield: false,
|
||||
@@ -327,7 +327,7 @@ public static class StarSystems
|
||||
Id: "ForgeOfSouls",
|
||||
Name: "Forge of Souls",
|
||||
SystemCategory: StarSystemCategory.HomeworldSystem,
|
||||
Owner: "The Eden Accord",
|
||||
Owner: "The Obsidian Order",
|
||||
HigherInfluenceYield: false,
|
||||
HigherCreditYield: false,
|
||||
HigherEnergyYield: true,
|
||||
@@ -343,7 +343,7 @@ public static class StarSystems
|
||||
Id: "GalacticZenith",
|
||||
Name: "Galactic Zenith",
|
||||
SystemCategory: StarSystemCategory.CoreSystem,
|
||||
Owner: "The Eden Accord",
|
||||
Owner: "The Keeper Council",
|
||||
HigherInfluenceYield: true,
|
||||
HigherCreditYield: true,
|
||||
HigherEnergyYield: true,
|
||||
@@ -375,7 +375,7 @@ public static class StarSystems
|
||||
Id: "GelidStorm",
|
||||
Name: "Gelid Storm",
|
||||
SystemCategory: StarSystemCategory.SideSystem,
|
||||
Owner: "The Eden Accord",
|
||||
Owner: "The Obsidian Order",
|
||||
HigherInfluenceYield: false,
|
||||
HigherCreditYield: false,
|
||||
HigherEnergyYield: false,
|
||||
@@ -391,7 +391,7 @@ public static class StarSystems
|
||||
Id: "GlitteringHope",
|
||||
Name: "Glittering Hope",
|
||||
SystemCategory: StarSystemCategory.HomeworldSystem,
|
||||
Owner: "The Eden Accord",
|
||||
Owner: "The Keeper Council",
|
||||
HigherInfluenceYield: true,
|
||||
HigherCreditYield: false,
|
||||
HigherEnergyYield: false,
|
||||
@@ -407,7 +407,7 @@ public static class StarSystems
|
||||
Id: "HeigenStream",
|
||||
Name: "Heigen Stream",
|
||||
SystemCategory: StarSystemCategory.SideSystem,
|
||||
Owner: "The Eden Accord",
|
||||
Owner: "The Obsidian Order",
|
||||
HigherInfluenceYield: false,
|
||||
HigherCreditYield: false,
|
||||
HigherEnergyYield: false,
|
||||
@@ -423,7 +423,7 @@ public static class StarSystems
|
||||
Id: "HeliosCrossing",
|
||||
Name: "Helios Crossing",
|
||||
SystemCategory: StarSystemCategory.CoreSystem,
|
||||
Owner: "The Eden Accord",
|
||||
Owner: "The Obsidian Order",
|
||||
HigherInfluenceYield: false,
|
||||
HigherCreditYield: false,
|
||||
HigherEnergyYield: false,
|
||||
@@ -487,7 +487,7 @@ public static class StarSystems
|
||||
Id: "InfernoSEdgeStronghold",
|
||||
Name: "Inferno's Edge Stronghold",
|
||||
SystemCategory: StarSystemCategory.CoreSystem,
|
||||
Owner: "The Eden Accord",
|
||||
Owner: "The Keeper Council",
|
||||
HigherInfluenceYield: false,
|
||||
HigherCreditYield: false,
|
||||
HigherEnergyYield: true,
|
||||
@@ -519,7 +519,7 @@ public static class StarSystems
|
||||
Id: "IvoryFields",
|
||||
Name: "Ivory Fields",
|
||||
SystemCategory: StarSystemCategory.HomeworldSystem,
|
||||
Owner: "The Eden Accord",
|
||||
Owner: "The Obsidian Order",
|
||||
HigherInfluenceYield: false,
|
||||
HigherCreditYield: false,
|
||||
HigherEnergyYield: false,
|
||||
@@ -567,7 +567,7 @@ public static class StarSystems
|
||||
Id: "LeviathanSWake",
|
||||
Name: "Leviathan's Wake",
|
||||
SystemCategory: StarSystemCategory.CoreSystem,
|
||||
Owner: "The Eden Accord",
|
||||
Owner: "The Keeper Council",
|
||||
HigherInfluenceYield: false,
|
||||
HigherCreditYield: false,
|
||||
HigherEnergyYield: true,
|
||||
@@ -599,7 +599,7 @@ public static class StarSystems
|
||||
Id: "MagentaBloom",
|
||||
Name: "Magenta Bloom",
|
||||
SystemCategory: StarSystemCategory.SideSystem,
|
||||
Owner: "The Eden Accord",
|
||||
Owner: "The Keeper Council",
|
||||
HigherInfluenceYield: false,
|
||||
HigherCreditYield: false,
|
||||
HigherEnergyYield: false,
|
||||
@@ -663,7 +663,7 @@ public static class StarSystems
|
||||
Id: "NeeraSGift",
|
||||
Name: "Neera's Gift",
|
||||
SystemCategory: StarSystemCategory.HomeworldSystem,
|
||||
Owner: "The Eden Accord",
|
||||
Owner: "The Keeper Council",
|
||||
HigherInfluenceYield: false,
|
||||
HigherCreditYield: false,
|
||||
HigherEnergyYield: false,
|
||||
@@ -695,7 +695,7 @@ public static class StarSystems
|
||||
Id: "NexusPrime",
|
||||
Name: "Nexus Prime",
|
||||
SystemCategory: StarSystemCategory.HomeworldSystem,
|
||||
Owner: "The Eden Accord",
|
||||
Owner: "The Keeper Council",
|
||||
HigherInfluenceYield: false,
|
||||
HigherCreditYield: true,
|
||||
HigherEnergyYield: false,
|
||||
@@ -711,7 +711,7 @@ public static class StarSystems
|
||||
Id: "NoxiousEnergy",
|
||||
Name: "Noxious Energy",
|
||||
SystemCategory: StarSystemCategory.SideSystem,
|
||||
Owner: "The Eden Accord",
|
||||
Owner: "The Obsidian Order",
|
||||
HigherInfluenceYield: false,
|
||||
HigherCreditYield: false,
|
||||
HigherEnergyYield: false,
|
||||
@@ -727,7 +727,7 @@ public static class StarSystems
|
||||
Id: "NucleicRedux",
|
||||
Name: "Nucleic Redux",
|
||||
SystemCategory: StarSystemCategory.CoreSystem,
|
||||
Owner: "The Eden Accord",
|
||||
Owner: "The Keeper Council",
|
||||
HigherInfluenceYield: false,
|
||||
HigherCreditYield: false,
|
||||
HigherEnergyYield: false,
|
||||
@@ -743,7 +743,7 @@ public static class StarSystems
|
||||
Id: "ObsidianPalace",
|
||||
Name: "Obsidian Palace",
|
||||
SystemCategory: StarSystemCategory.HomeworldSystem,
|
||||
Owner: "The Eden Accord",
|
||||
Owner: "The Obsidian Order",
|
||||
HigherInfluenceYield: false,
|
||||
HigherCreditYield: false,
|
||||
HigherEnergyYield: false,
|
||||
@@ -791,7 +791,7 @@ public static class StarSystems
|
||||
Id: "PleiadesCluster",
|
||||
Name: "Pleiades Cluster",
|
||||
SystemCategory: StarSystemCategory.SideSystem,
|
||||
Owner: "The Eden Accord",
|
||||
Owner: "The Keeper Council",
|
||||
HigherInfluenceYield: false,
|
||||
HigherCreditYield: true,
|
||||
HigherEnergyYield: false,
|
||||
@@ -871,7 +871,7 @@ public static class StarSystems
|
||||
Id: "ShatteredLight",
|
||||
Name: "Shattered Light",
|
||||
SystemCategory: StarSystemCategory.CoreSystem,
|
||||
Owner: "The Eden Accord",
|
||||
Owner: "The Keeper Council",
|
||||
HigherInfluenceYield: false,
|
||||
HigherCreditYield: false,
|
||||
HigherEnergyYield: false,
|
||||
@@ -919,7 +919,7 @@ public static class StarSystems
|
||||
Id: "StarlessSky",
|
||||
Name: "Starless Sky",
|
||||
SystemCategory: StarSystemCategory.HomeworldSystem,
|
||||
Owner: "The Eden Accord",
|
||||
Owner: "The Obsidian Order",
|
||||
HigherInfluenceYield: false,
|
||||
HigherCreditYield: false,
|
||||
HigherEnergyYield: false,
|
||||
@@ -935,7 +935,7 @@ public static class StarSystems
|
||||
Id: "SteelDepths",
|
||||
Name: "Steel Depths",
|
||||
SystemCategory: StarSystemCategory.HomeworldSystem,
|
||||
Owner: "The Eden Accord",
|
||||
Owner: "The Obsidian Order",
|
||||
HigherInfluenceYield: false,
|
||||
HigherCreditYield: false,
|
||||
HigherEnergyYield: false,
|
||||
@@ -951,7 +951,7 @@ public static class StarSystems
|
||||
Id: "StellarForge",
|
||||
Name: "Stellar Forge",
|
||||
SystemCategory: StarSystemCategory.CoreSystem,
|
||||
Owner: "The Eden Accord",
|
||||
Owner: "The Obsidian Order",
|
||||
HigherInfluenceYield: false,
|
||||
HigherCreditYield: false,
|
||||
HigherEnergyYield: false,
|
||||
@@ -967,7 +967,7 @@ public static class StarSystems
|
||||
Id: "StrongholdAtlas",
|
||||
Name: "Stronghold Atlas",
|
||||
SystemCategory: StarSystemCategory.HomeworldSystem,
|
||||
Owner: "The Eden Accord",
|
||||
Owner: "The Obsidian Order",
|
||||
HigherInfluenceYield: false,
|
||||
HigherCreditYield: false,
|
||||
HigherEnergyYield: false,
|
||||
@@ -999,7 +999,7 @@ public static class StarSystems
|
||||
Id: "StrongholdLeo",
|
||||
Name: "Stronghold Leo",
|
||||
SystemCategory: StarSystemCategory.HomeworldSystem,
|
||||
Owner: "The Eden Accord",
|
||||
Owner: "The Keeper Council",
|
||||
HigherInfluenceYield: true,
|
||||
HigherCreditYield: false,
|
||||
HigherEnergyYield: false,
|
||||
@@ -1047,7 +1047,7 @@ public static class StarSystems
|
||||
Id: "StrongholdTau",
|
||||
Name: "Stronghold Tau",
|
||||
SystemCategory: StarSystemCategory.HomeworldSystem,
|
||||
Owner: "The Eden Accord",
|
||||
Owner: "The Keeper Council",
|
||||
HigherInfluenceYield: false,
|
||||
HigherCreditYield: true,
|
||||
HigherEnergyYield: false,
|
||||
@@ -1063,7 +1063,7 @@ public static class StarSystems
|
||||
Id: "StrongholdVega",
|
||||
Name: "Stronghold Vega",
|
||||
SystemCategory: StarSystemCategory.HomeworldSystem,
|
||||
Owner: "The Eden Accord",
|
||||
Owner: "The Obsidian Order",
|
||||
HigherInfluenceYield: false,
|
||||
HigherCreditYield: true,
|
||||
HigherEnergyYield: false,
|
||||
@@ -1095,7 +1095,7 @@ public static class StarSystems
|
||||
Id: "TartarusExpanse",
|
||||
Name: "Tartarus Expanse",
|
||||
SystemCategory: StarSystemCategory.CoreSystem,
|
||||
Owner: "The Eden Accord",
|
||||
Owner: "The Keeper Council",
|
||||
HigherInfluenceYield: false,
|
||||
HigherCreditYield: false,
|
||||
HigherEnergyYield: false,
|
||||
@@ -1127,7 +1127,7 @@ public static class StarSystems
|
||||
Id: "TheHighCouncil",
|
||||
Name: "The High Council",
|
||||
SystemCategory: StarSystemCategory.HomeworldSystem,
|
||||
Owner: "The Eden Accord",
|
||||
Owner: "The Keeper Council",
|
||||
HigherInfluenceYield: true,
|
||||
HigherCreditYield: false,
|
||||
HigherEnergyYield: false,
|
||||
@@ -1175,7 +1175,7 @@ public static class StarSystems
|
||||
Id: "TyphonSCall",
|
||||
Name: "Typhon's Call",
|
||||
SystemCategory: StarSystemCategory.HomeworldSystem,
|
||||
Owner: "The Eden Accord",
|
||||
Owner: "The Keeper Council",
|
||||
HigherInfluenceYield: false,
|
||||
HigherCreditYield: false,
|
||||
HigherEnergyYield: true,
|
||||
@@ -1207,7 +1207,7 @@ public static class StarSystems
|
||||
Id: "VoidStar",
|
||||
Name: "Void Star",
|
||||
SystemCategory: StarSystemCategory.CoreSystem,
|
||||
Owner: "The Eden Accord",
|
||||
Owner: "The Keeper Council",
|
||||
HigherInfluenceYield: false,
|
||||
HigherCreditYield: false,
|
||||
HigherEnergyYield: false,
|
||||
@@ -1239,7 +1239,7 @@ public static class StarSystems
|
||||
Id: "WildSEnd",
|
||||
Name: "Wild's End",
|
||||
SystemCategory: StarSystemCategory.HomeworldSystem,
|
||||
Owner: "The Eden Accord",
|
||||
Owner: "The Obsidian Order",
|
||||
HigherInfluenceYield: false,
|
||||
HigherCreditYield: true,
|
||||
HigherEnergyYield: false,
|
||||
@@ -1255,7 +1255,7 @@ public static class StarSystems
|
||||
Id: "XenonAbyss",
|
||||
Name: "Xenon Abyss",
|
||||
SystemCategory: StarSystemCategory.CoreSystem,
|
||||
Owner: "The Eden Accord",
|
||||
Owner: "The Keeper Council",
|
||||
HigherInfluenceYield: false,
|
||||
HigherCreditYield: false,
|
||||
HigherEnergyYield: false,
|
||||
@@ -1271,7 +1271,7 @@ public static class StarSystems
|
||||
Id: "XenthicFields",
|
||||
Name: "Xenthic Fields",
|
||||
SystemCategory: StarSystemCategory.SideSystem,
|
||||
Owner: "The Eden Accord",
|
||||
Owner: "The Keeper Council",
|
||||
HigherInfluenceYield: false,
|
||||
HigherCreditYield: false,
|
||||
HigherEnergyYield: false,
|
||||
@@ -1303,7 +1303,7 @@ public static class StarSystems
|
||||
Id: "ZetaHorizon",
|
||||
Name: "Zeta Horizon",
|
||||
SystemCategory: StarSystemCategory.SideSystem,
|
||||
Owner: "The Eden Accord",
|
||||
Owner: "The Keeper Council",
|
||||
HigherInfluenceYield: false,
|
||||
HigherCreditYield: false,
|
||||
HigherEnergyYield: false,
|
||||
|
||||
Reference in New Issue
Block a user