Fix characteristic of all-0 IV mons when EC%6!=0

They'll always be HP.
ty Anubis for testing and SirToastyToes for reporting

Changing characteristic is a 1 in (5/6)*(32^6) chance, when no IVs are forced; aka ~1:900million
or just get a colo e-reader mon with 5/6 chance :)

Gen4/HOME(mobile): correct, unaffected
Gen5-Gen9/HOME(switch): bugged
This commit is contained in:
Kurt 2025-05-17 15:03:42 -05:00
parent 7442e86d65
commit 5a3ebec12b
6 changed files with 14 additions and 5 deletions

View File

@ -79,7 +79,7 @@ public override byte CurrentFriendship
public override bool IsUntraded => Data[0xB8] == 0 && Data[0xB8 + 1] == 0 && Format == Generation; // immediately terminated HandlingTrainerName data (\0)
// Complex Generated Attributes
public override int Characteristic => EntityCharacteristic.GetCharacteristic(EncryptionConstant, IV32);
public override int Characteristic => EntityCharacteristic.GetCharacteristicInit0(EncryptionConstant, IV32);
// Methods
protected override byte[] Encrypt()

View File

@ -289,7 +289,7 @@ public override string Nickname
// Generated Attributes
public override uint PSV => ((PID >> 16) ^ (PID & 0xFFFF)) >> 3;
public override uint TSV => (uint)(TID16 ^ SID16) >> 3;
public override int Characteristic => EntityCharacteristic.GetCharacteristic(PID, IV32);
public override int Characteristic => EntityCharacteristic.GetCharacteristicInit0(PID, IV32);
// Maximums
public override ushort MaxMoveID => Legal.MaxMoveID_5;

View File

@ -74,7 +74,7 @@ public override byte CurrentFriendship
public bool IsUnhatchedEgg => Version == 0 && IsEgg;
// Complex Generated Attributes
public override int Characteristic => EntityCharacteristic.GetCharacteristic(EncryptionConstant, IV32);
public override int Characteristic => EntityCharacteristic.GetCharacteristicInit0(EncryptionConstant, IV32);
// Methods
protected override byte[] Encrypt()

View File

@ -45,7 +45,7 @@ public byte OppositeFriendship
// Complex Generated Attributes
public abstract uint IV32 { get; set; }
public override int Characteristic => EntityCharacteristic.GetCharacteristic(EncryptionConstant, IV32);
public override int Characteristic => EntityCharacteristic.GetCharacteristicInit0(EncryptionConstant, IV32);
// Methods
protected sealed override byte[] Encrypt()

View File

@ -55,7 +55,7 @@ public override byte CurrentFriendship
public override bool IsUntraded => Data[0xA8] == 0 && Data[0xA8 + 1] == 0 && Format == Generation; // immediately terminated HandlingTrainerName data (\0)
// Complex Generated Attributes
public override int Characteristic => EntityCharacteristic.GetCharacteristic(EncryptionConstant, IV32);
public override int Characteristic => EntityCharacteristic.GetCharacteristicInit0(EncryptionConstant, IV32);
// Methods
protected override byte[] Encrypt()

View File

@ -28,6 +28,15 @@ public static int GetCharacteristic(uint ec, uint iv32)
return GetCharacteristic(maxStatIndex, maxStatValue);
}
/// <inheritdoc cref="GetCharacteristic(int,int)"/>
/// <remarks>
/// Generations 5-9(+?) initialize the "best" characteristic index to 0 (HP).
/// In the event that all IVs are 0, the characteristic index is also 0, regardless of EC % 6.
/// The original implementation in Gen4 has the "correct" behavior, being based on EC % 6; as does HOME on mobile.
/// Only formats that display the all-zero-IV characteristic as always-"HP" reference this method.
/// </remarks>
public static int GetCharacteristicInit0(uint ec, uint iv32) => iv32 == 0 ? 0 : GetCharacteristic(ec, iv32);
/// <summary>
/// Gets the characteristic index of the given unpacked IVs.
/// </summary>