Add new virtual method for pre-applying Nickname

Results in correct trash bytes for user-Nickname'd mons as if they were nicknamed via the in-game menu.
This commit is contained in:
Kurt 2026-03-19 03:20:42 -05:00
parent 3c1e7bdc6c
commit ca6fbf024c
5 changed files with 23 additions and 5 deletions

View File

@ -30,8 +30,10 @@ public void SetNickname(string nick)
pk.ClearNickname();
return;
}
pk.IsNicknamed = true;
pk.PrepareNickname();
pk.Nickname = nick;
pk.IsNicknamed = true;
}
/// <summary>

View File

@ -4,7 +4,7 @@ namespace PKHeX.Core;
/// Parameters used to generate data for an encounter.
/// </summary>
/// <param name="Species">Species to generate.</param>
/// <param name="GenderRatio">Gender ratio byte.</param>
/// <param name="GenderRatio">Gender ratio byte from Personal Info.</param>
/// <param name="FlawlessIVs">Count of IVs that are perfect.</param>
/// <param name="RollCount">Count of shiny rolls allowed for the PID calculation.</param>
/// <param name="Height">Height value to generate. If zero, full random.</param>

View File

@ -135,9 +135,9 @@ private static void FlagIsNicknameClean(LegalityAnalysis data, PK3 pk)
{
if (!pk.IsNicknamed || pk.IsEgg)
return;
var nick = pk.NicknameTrash;
if (pk.Japanese)
nick = nick[..5]; // Japanese only wipes the first 5 bytes; everything else is trash.
// Japanese only fills the first 5+1 bytes; everything else is trash.
// International games are 10 chars (full buffer) max; implicit terminator if full.
var nick = pk.GetNicknamePrefillRegion();
if (!TrashByteRules3.IsTerminatedFF(nick))
data.AddLine(GetInvalid(Trainer, TrashBytesMismatchInitial));
}

View File

@ -398,4 +398,15 @@ public override int GetStringTerminatorIndex(ReadOnlySpan<byte> data)
public override int GetStringLength(ReadOnlySpan<byte> data)
=> TrashBytes8.GetStringLength(data);
public override int GetBytesPerChar() => 1;
public override void PrepareNickname() => GetNicknamePrefillRegion().Fill(StringConverter3.TerminatorByte);
public Span<byte> GetNicknamePrefillRegion()
{
// Japanese only fills the first 5+1 bytes; everything else is trash.
// International games are 10 chars (full buffer) max; implicit terminator if full.
if (Japanese)
return NicknameTrash[..6];
return NicknameTrash;
}
}

View File

@ -44,6 +44,11 @@ public abstract class PKM : ISpeciesForm, ITrainerID32, IGeneration, IShiny, ILa
public abstract Span<byte> OriginalTrainerTrash { get; }
public virtual Span<byte> HandlingTrainerTrash => [];
/// <summary>
/// Conditions the <see cref="NicknameTrash"/> data to safely terminate the Nickname string from the text entry screen.
/// </summary>
public virtual void PrepareNickname() { }
protected abstract byte[] Encrypt();
public abstract EntityContext Context { get; }
public byte Format => Context.Generation;