mirror of
https://github.com/kwsch/PKHeX.git
synced 2026-03-21 17:48:28 -05:00
Null safety fixes + Plus Records and Medals buttons
Null safety (prevents NullReferenceException crashes): - RefreshBox: null check on GetBoxSlotAtIndex result - RefreshParty: null check on GetPartySlotAtIndex result - PushUndo: guard existing slot before DecryptedBoxData access - RefreshExtraSlots: null check on slotInfo.Read result - ExportBoxShowdown: null check in LINQ Where clause - VerifyAllPkm: null/empty species guard Missing controls added: - Plus Records button in Moves tab (IPlusRecord, Gen 8+) - Medals button in Cosmetic tab (ISuperTrainRegimen, Gen 6)
This commit is contained in:
parent
a8b60cf4ab
commit
2e7fcb24b3
|
|
@ -811,7 +811,7 @@ private async Task ExportBoxShowdownAsync()
|
|||
try
|
||||
{
|
||||
var box = SaveFile.GetBoxData(SavEditor.CurrentBox);
|
||||
var text = string.Join("\n\n", box.Where(p => p.Species > 0).Select(ShowdownParsing.GetShowdownText));
|
||||
var text = string.Join("\n\n", box.Where(p => p is not null && p.Species > 0).Select(ShowdownParsing.GetShowdownText));
|
||||
if (string.IsNullOrWhiteSpace(text))
|
||||
{
|
||||
StatusMessage = "No Pokemon in box to export.";
|
||||
|
|
|
|||
|
|
@ -338,9 +338,13 @@ public string NatureTooltip
|
|||
[ObservableProperty] private ComboItem? _selectedAlphaMove;
|
||||
[ObservableProperty] private bool _hasAlphaMove;
|
||||
|
||||
// Move Shop / Tech Record visibility
|
||||
// Move Shop / Tech Record / Plus Record visibility
|
||||
[ObservableProperty] private bool _hasMoveShop;
|
||||
[ObservableProperty] private bool _hasTechRecords;
|
||||
[ObservableProperty] private bool _hasPlusRecord;
|
||||
|
||||
// Super Training (Medals) visibility — Gen 6
|
||||
[ObservableProperty] private bool _hasSuperTraining;
|
||||
|
||||
// Gen-specific: Catch Rate (Gen 1)
|
||||
[ObservableProperty] private int _catchRate;
|
||||
|
|
@ -1478,6 +1482,12 @@ public void PopulateFields(PKM pk)
|
|||
// Tech Records (Gen 8+)
|
||||
HasTechRecords = pk is ITechRecord;
|
||||
|
||||
// Plus Records (Gen 9a - Z:A)
|
||||
HasPlusRecord = pk is IPlusRecord;
|
||||
|
||||
// Super Training / Medals (Gen 6)
|
||||
HasSuperTraining = pk is ISuperTrainRegimen;
|
||||
|
||||
// Origin Mark indicator
|
||||
var gen = pk.Generation;
|
||||
HasOriginMark = gen >= 3;
|
||||
|
|
@ -1896,6 +1906,39 @@ private async Task OpenTechRecords()
|
|||
catch (Exception ex) { LegalityReport = $"Tech Record error: {ex.Message}"; }
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task OpenPlusRecord()
|
||||
{
|
||||
if (Entity is not IPlusRecord plus) return;
|
||||
if (Entity.PersonalInfo is not IPermitPlus permit) return;
|
||||
try
|
||||
{
|
||||
PreparePKM();
|
||||
var vm = new PlusRecordEditorViewModel(plus, permit, Entity);
|
||||
var view = new PlusRecordEditorView { DataContext = vm };
|
||||
var mainWindow = (Application.Current?.ApplicationLifetime as IClassicDesktopStyleApplicationLifetime)?.MainWindow;
|
||||
if (mainWindow != null)
|
||||
await view.ShowDialog(mainWindow);
|
||||
}
|
||||
catch (Exception ex) { LegalityReport = $"Plus Record error: {ex.Message}"; }
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task OpenMedals()
|
||||
{
|
||||
if (Entity is not ISuperTrainRegimen st) return;
|
||||
try
|
||||
{
|
||||
PreparePKM();
|
||||
var vm = new SuperTrainingEditorViewModel(st);
|
||||
var view = new SuperTrainingEditorView { DataContext = vm };
|
||||
var mainWindow = (Application.Current?.ApplicationLifetime as IClassicDesktopStyleApplicationLifetime)?.MainWindow;
|
||||
if (mainWindow != null)
|
||||
await view.ShowDialog(mainWindow);
|
||||
}
|
||||
catch (Exception ex) { LegalityReport = $"Super Training error: {ex.Message}"; }
|
||||
}
|
||||
|
||||
// --- Ribbons / Memories commands ---
|
||||
|
||||
[RelayCommand]
|
||||
|
|
|
|||
|
|
@ -287,6 +287,7 @@ private void RefreshBox()
|
|||
for (int i = 0; i < slotCount && i < BoxSlots.Count; i++)
|
||||
{
|
||||
var pk = _sav.GetBoxSlotAtIndex(CurrentBox, i);
|
||||
if (pk is null) continue;
|
||||
BoxSlots[i].Entity = pk;
|
||||
if (pk.Species == 0)
|
||||
{
|
||||
|
|
@ -310,6 +311,7 @@ private void RefreshParty()
|
|||
for (int i = 0; i < _sav.PartyCount && i < PartySlots.Count; i++)
|
||||
{
|
||||
var pk = _sav.GetPartySlotAtIndex(i);
|
||||
if (pk is null) continue;
|
||||
PartySlots[i].Entity = pk;
|
||||
if (pk.Species == 0)
|
||||
{
|
||||
|
|
@ -388,7 +390,8 @@ private void SetSlot(SlotModel? slot)
|
|||
if (boxIndex >= 0)
|
||||
{
|
||||
var existing = _sav.GetBoxSlotAtIndex(CurrentBox, boxIndex);
|
||||
PushUndo(CurrentBox, boxIndex, existing, isParty: false);
|
||||
if (existing is not null)
|
||||
PushUndo(CurrentBox, boxIndex, existing, isParty: false);
|
||||
_sav.SetBoxSlotAtIndex(pk, CurrentBox, boxIndex);
|
||||
RefreshBox();
|
||||
return;
|
||||
|
|
@ -398,7 +401,8 @@ private void SetSlot(SlotModel? slot)
|
|||
if (partyIndex >= 0)
|
||||
{
|
||||
var existing = _sav.GetPartySlotAtIndex(partyIndex);
|
||||
PushUndo(0, partyIndex, existing, isParty: true);
|
||||
if (existing is not null)
|
||||
PushUndo(0, partyIndex, existing, isParty: true);
|
||||
_sav.SetPartySlotAtIndex(pk, partyIndex);
|
||||
RefreshParty();
|
||||
}
|
||||
|
|
@ -426,7 +430,8 @@ private void DeleteSlot(SlotModel? slot)
|
|||
if (boxIndex >= 0)
|
||||
{
|
||||
var existing = _sav.GetBoxSlotAtIndex(CurrentBox, boxIndex);
|
||||
PushUndo(CurrentBox, boxIndex, existing, isParty: false);
|
||||
if (existing is not null)
|
||||
PushUndo(CurrentBox, boxIndex, existing, isParty: false);
|
||||
_sav.SetBoxSlotAtIndex(_sav.BlankPKM, CurrentBox, boxIndex);
|
||||
RefreshBox();
|
||||
return;
|
||||
|
|
@ -436,7 +441,8 @@ private void DeleteSlot(SlotModel? slot)
|
|||
if (partyIndex >= 0)
|
||||
{
|
||||
var existing = _sav.GetPartySlotAtIndex(partyIndex);
|
||||
PushUndo(0, partyIndex, existing, isParty: true);
|
||||
if (existing is not null)
|
||||
PushUndo(0, partyIndex, existing, isParty: true);
|
||||
_sav.DeletePartySlot(partyIndex);
|
||||
RefreshParty();
|
||||
}
|
||||
|
|
@ -524,6 +530,7 @@ private void RefreshExtraSlots(SaveFile sav)
|
|||
foreach (var slotInfo in extras)
|
||||
{
|
||||
var pk = slotInfo.Read(sav);
|
||||
if (pk is null) continue;
|
||||
var model = new SlotModel
|
||||
{
|
||||
Slot = slotInfo.Slot,
|
||||
|
|
@ -675,7 +682,7 @@ private void VerifyAllPkm()
|
|||
for (int slot = 0; slot < _sav.BoxSlotCount; slot++)
|
||||
{
|
||||
var pk = _sav.GetBoxSlotAtIndex(box, slot);
|
||||
if (pk.Species == 0) continue;
|
||||
if (pk is null || pk.Species == 0) continue;
|
||||
total++;
|
||||
var la = new LegalityAnalysis(pk);
|
||||
if (la.Valid) legal++; else illegal++;
|
||||
|
|
|
|||
|
|
@ -523,12 +523,14 @@
|
|||
DisplayMemberBinding="{Binding Text, DataType=core:ComboItem}" Height="25" Width="200" HorizontalAlignment="Left" />
|
||||
</StackPanel>
|
||||
|
||||
<!-- Move Shop / Tech Records buttons -->
|
||||
<!-- Move Shop / Tech Records / Plus Records buttons -->
|
||||
<StackPanel Orientation="Horizontal" Spacing="4" Margin="0,4,0,0">
|
||||
<Button Content="Move Shop" Command="{Binding OpenMoveShopCommand}" Padding="6,2" FontSize="10"
|
||||
IsVisible="{Binding HasMoveShop}" />
|
||||
<Button Content="Tech Records" Command="{Binding OpenTechRecordsCommand}" Padding="6,2" FontSize="10"
|
||||
IsVisible="{Binding HasTechRecords}" />
|
||||
<Button Content="Plus Records" Command="{Binding OpenPlusRecordCommand}" Padding="6,2" FontSize="10"
|
||||
IsVisible="{Binding HasPlusRecord}" />
|
||||
</StackPanel>
|
||||
|
||||
<!-- Relearn Moves -->
|
||||
|
|
@ -683,10 +685,12 @@
|
|||
</Grid>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Ribbons / Memories buttons -->
|
||||
<!-- Ribbons / Memories / Medals buttons -->
|
||||
<StackPanel Orientation="Horizontal" Spacing="4" Margin="0,8,0,0">
|
||||
<Button Content="Ribbons" Command="{Binding OpenRibbonsCommand}" Padding="6,2" FontSize="10" />
|
||||
<Button Content="Memories" Command="{Binding OpenMemoriesCommand}" Padding="6,2" FontSize="10" />
|
||||
<Button Content="Medals" Command="{Binding OpenMedalsCommand}" Padding="6,2" FontSize="10"
|
||||
IsVisible="{Binding HasSuperTraining}" />
|
||||
</StackPanel>
|
||||
|
||||
</StackPanel>
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user