Kurt
2026-01-11 00:37:48 -06:00
parent 4ea08b3403
commit 3a8bc5889b
16 changed files with 69 additions and 53 deletions

View File

@@ -178,6 +178,8 @@ private byte GetGenderRatioPersonal()
}
#endregion
public bool IsAlpha127 => IsAlpha && HeightScalar == 127 && WeightScalar == 127;
#region Matching
public bool IsMatchExact(PKM pk, EvoCriteria evo)
{
@@ -200,7 +202,8 @@ public bool IsMatchExact(PKM pk, EvoCriteria evo)
return true;
// 3 of the Alpha statics were mistakenly set as 127 scale. If they enter HOME on 3.0.1, they'll get bumped to 255.
if (IsAlpha && this is { HeightScalar: 127, WeightScalar: 127 }) // Average Size Alphas
// Defer scale match to downstream checks; we are sufficiently confident this is the best-match.
if (IsAlpha127) // Average Size Alphas
{
// HOME >=3.0.1 ensures 255 scales for the 127's
// PLA and S/V could have safe-harbored them via <=3.0.0

View File

@@ -358,10 +358,10 @@ public sealed class LegalityCheckLocalization
public string StatDynamaxInvalid { get; set; } = "Dynamax Level is not within the expected range.";
public string StatIncorrectHeight { get; set; } = "Calculated Height does not match stored value.";
public string StatIncorrectHeightCopy { get; set; } = "Copy Height does not match the original value.";
public string StatIncorrectHeightValue { get; set; } = "Height does not match the expected value.";
public string StatIncorrectWeight { get; set; } = "Calculated Weight does not match stored value.";
public string StatIncorrectWeightValue { get; set; } = "Weight does not match the expected value.";
public string StatIncorrectHeightValue_0 { get; set; } = "Height should be {0}.";
public string StatIncorrectWeightValue_0 { get; set; } = "Weight should be {0}.";
public string StatIncorrectScaleValue_0 { get; set; } = "Scale should be {0}.";
public string StatInvalidHeightWeight { get; set; } = "Height / Weight values are statistically improbable.";
public string StatIncorrectCP { get; set; } = "Calculated CP does not match stored value.";
public string StatGigantamaxInvalid { get; set; } = "Gigantamax Flag mismatch.";

View File

@@ -355,10 +355,10 @@ public static class LegalityCheckResultCodeExtensions
RibbonEgg => localization.RibbonEgg,
StatDynamaxInvalid => localization.StatDynamaxInvalid,
StatIncorrectHeight => localization.StatIncorrectHeight,
StatIncorrectHeightCopy => localization.StatIncorrectHeightCopy,
StatIncorrectHeightValue => localization.StatIncorrectHeightValue,
StatIncorrectWeight => localization.StatIncorrectWeight,
StatIncorrectWeightValue => localization.StatIncorrectWeightValue,
StatIncorrectScaleValue_0 => localization.StatIncorrectScaleValue_0,
StatIncorrectHeightValue_0 => localization.StatIncorrectHeightValue_0,
StatIncorrectWeightValue_0 => localization.StatIncorrectWeightValue_0,
StatInvalidHeightWeight => localization.StatInvalidHeightWeight,
StatIncorrectCP_0 => localization.StatIncorrectCP,
StatGigantamaxInvalid => localization.StatGigantamaxInvalid,

View File

@@ -305,10 +305,7 @@ public enum LegalityCheckResultCode : ushort
// Stats
StatDynamaxInvalid,
StatIncorrectHeight,
StatIncorrectHeightCopy,
StatIncorrectHeightValue,
StatIncorrectWeight,
StatIncorrectWeightValue,
StatInvalidHeightWeight,
StatGigantamaxInvalid,
StatGigantamaxValid,
@@ -412,6 +409,9 @@ public enum LegalityCheckResultCode : ushort
MovePPUpsTooHigh_0, // move slot
MemoryHTGender_0, // gender value
G6SuperTrainBagInvalid_0,
StatIncorrectHeightValue_0,
StatIncorrectWeightValue_0,
StatIncorrectScaleValue_0,
// Single Argument: Move ID
FirstWithMove,

View File

@@ -47,14 +47,14 @@ private void CheckScalars(LegalityAnalysis data, PA8 pa)
if (pa.IsAlpha && data.EncounterMatch is EncounterSlot8a)
{
if (pa.HeightScalar != 255)
data.AddLine(GetInvalid(StatIncorrectHeightValue, 255));
data.AddLine(GetInvalid(StatIncorrectHeightValue_0, 255));
if (pa.WeightScalar != 255)
data.AddLine(GetInvalid(StatIncorrectWeightValue, 255));
data.AddLine(GetInvalid(StatIncorrectWeightValue_0, 255));
}
// No way to mutate the display height scalar value. Must match!
if (pa.HeightScalar != pa.Scale)
data.AddLine(GetInvalid(CheckIdentifier.Encounter, StatIncorrectHeightCopy));
data.AddLine(GetInvalid(CheckIdentifier.Encounter, StatIncorrectScaleValue_0, pa.HeightScalar));
}
private static void CheckLearnset(LegalityAnalysis data, PA8 pa)

View File

@@ -225,9 +225,9 @@ private void VerifyMiscScaleValues(LegalityAnalysis data, PKM pk, IEncounterTemp
else if (data.EncounterMatch.Context is EntityContext.Gen9a)
{
if (s2.HeightScalar != 0)
data.AddLine(GetInvalid(Encounter, StatIncorrectHeightValue));
data.AddLine(GetInvalid(Encounter, StatIncorrectHeightValue_0, 0));
if (s2.WeightScalar != 0)
data.AddLine(GetInvalid(Encounter, StatIncorrectWeightValue));
data.AddLine(GetInvalid(Encounter, StatIncorrectWeightValue_0, 0));
}
else if (CheckHeightWeightOdds(data.EncounterMatch))
{
@@ -239,8 +239,26 @@ private void VerifyMiscScaleValues(LegalityAnalysis data, PKM pk, IEncounterTemp
}
// Check for Scale
if (pk is IScaledSize3 s3 && IsHeightScaleMatchRequired(pk) && s2.HeightScalar != s3.Scale)
data.AddLine(GetInvalid(StatIncorrectHeightValue));
if (pk is IScaledSize3 s3)
{
// PLA static Alphas have potential for 127 scale; this is already checked explicitly in the matching check.
// Ensure all Alphas have 255 scale.
// Otherwise, ensure scale matches height scalar if required.
if (enc is IAlphaReadOnly { IsAlpha: true })
{
byte expect = enc switch
{
EncounterStatic8a { IsAlpha127: true } when s2 is { HeightScalar: 127, WeightScalar: 127 } => 127, // Fixed size Alphas not yet converted by HOME >= 3.0.1
_ => byte.MaxValue,
};
if (s3.Scale != expect)
data.AddLine(GetInvalid(StatIncorrectScaleValue_0, expect));
}
else if (IsHeightScaleMatchRequired(pk) && s2.HeightScalar != s3.Scale)
{
data.AddLine(GetInvalid(StatIncorrectScaleValue_0, s2.HeightScalar));
}
}
}
private void VerifyIsMovesetAllowed(LegalityAnalysis data, SK2 sk2)
@@ -302,12 +320,7 @@ private static void VerifyStats5(LegalityAnalysis data, PK5 pk5)
}
}
private static bool IsHeightScaleMatchRequired(PKM pk)
{
if (pk is IHomeTrack { HasTracker: false })
return false;
return true;
}
private static bool IsHeightScaleMatchRequired(PKM pk) => pk is IHomeTrack { HasTracker: true };
private void VerifyStats9(LegalityAnalysis data, PK9 pk9)
{

View File

@@ -282,10 +282,10 @@
"RibbonMarkingAffixed_0": "Invalid Affixed Ribbon/Marking: {0}",
"StatDynamaxInvalid": "Dynamax Level is not within the expected range.",
"StatIncorrectHeight": "Calculated Height does not match stored value.",
"StatIncorrectHeightCopy": "Copy Height does not match the original value.",
"StatIncorrectHeightValue": "Height does not match the expected value.",
"StatIncorrectWeight": "Calculated Weight does not match stored value.",
"StatIncorrectWeightValue": "Weight does not match the expected value.",
"StatIncorrectHeightValue_0": "Height should be {0}.",
"StatIncorrectWeightValue_0": "Weight should be {0}.",
"StatIncorrectScaleValue_0": "Scale should be {0}.",
"StatInvalidHeightWeight": "Height / Weight values are statistically improbable.",
"StatIncorrectCP": "Calculated CP does not match stored value.",
"StatGigantamaxInvalid": "Gigantamax Flag mismatch.",

View File

@@ -282,10 +282,10 @@
"RibbonMarkingAffixed_0": "Invalid Affixed Ribbon/Marking: {0}",
"StatDynamaxInvalid": "Dynamax Level is not within the expected range.",
"StatIncorrectHeight": "Calculated Height does not match stored value.",
"StatIncorrectHeightCopy": "Copy Height does not match the original value.",
"StatIncorrectHeightValue": "Height does not match the expected value.",
"StatIncorrectWeight": "Calculated Weight does not match stored value.",
"StatIncorrectWeightValue": "Weight does not match the expected value.",
"StatIncorrectHeightValue_0": "Height should be {0}.",
"StatIncorrectWeightValue_0": "Weight should be {0}.",
"StatIncorrectScaleValue_0": "Scale should be {0}.",
"StatInvalidHeightWeight": "Height / Weight values are statistically improbable.",
"StatIncorrectCP": "Calculated CP does not match stored value.",
"StatGigantamaxInvalid": "Gigantamax Flag mismatch.",

View File

@@ -282,10 +282,10 @@
"RibbonMarkingAffixed_0": "Cinta/marca pegada inválida: {0}",
"StatDynamaxInvalid": "El nivel Dinamax no está dentro del rango esperado.",
"StatIncorrectHeight": "La altura calculada no coincide con el valor almacenado.",
"StatIncorrectHeightCopy": "La altura copiada no coincide con el valor original.",
"StatIncorrectHeightValue": "La altura no coincide con el valor esperado.",
"StatIncorrectWeight": "El peso calculado no coincide con el valor almacenado.",
"StatIncorrectWeightValue": "El peso no coincide con el valor esperado.",
"StatIncorrectHeightValue_0": "Height should be {0}.",
"StatIncorrectWeightValue_0": "Weight should be {0}.",
"StatIncorrectScaleValue_0": "Scale should be {0}.",
"StatInvalidHeightWeight": "Los valores de altura/peso son estadísticamente improbables.",
"StatIncorrectCP": "Los CP calculados no coinciden con el valor almacenado.",
"StatGigantamaxInvalid": "Gigamax incompatible.",

View File

@@ -282,10 +282,10 @@
"RibbonMarkingAffixed_0": "Cinta/marca pegada inválida: {0}",
"StatDynamaxInvalid": "El nivel Dinamax no está dentro del rango esperado.",
"StatIncorrectHeight": "La altura calculada no coincide con el valor almacenado.",
"StatIncorrectHeightCopy": "La altura copiada no coincide con el valor original.",
"StatIncorrectHeightValue": "La altura no coincide con el valor esperado.",
"StatIncorrectWeight": "El peso calculado no coincide con el valor almacenado.",
"StatIncorrectWeightValue": "El peso no coincide con el valor esperado.",
"StatIncorrectHeightValue_0": "Height should be {0}.",
"StatIncorrectWeightValue_0": "Weight should be {0}.",
"StatIncorrectScaleValue_0": "Scale should be {0}.",
"StatInvalidHeightWeight": "Los valores de altura/peso son estadísticamente improbables.",
"StatIncorrectCP": "Los CP calculados no coinciden con el valor almacenado.",
"StatGigantamaxInvalid": "Gigamax incompatible.",

View File

@@ -282,10 +282,10 @@
"RibbonMarkingAffixed_0": "Ruban/marquage apposé non valide : {0}",
"StatDynamaxInvalid": "Le niveau Dynamax n'est pas dans la plage attendue.",
"StatIncorrectHeight": "La hauteur calculée ne correspond pas à la valeur stockée.",
"StatIncorrectHeightCopy": "La hauteur de la copie ne correspond pas à la valeur d'origine.",
"StatIncorrectHeightValue": "La hauteur ne correspond pas à la valeur attendue.",
"StatIncorrectWeight": "Le poids calculé ne correspond pas à la valeur stockée.",
"StatIncorrectWeightValue": "Le poids ne correspond pas à la valeur attendue.",
"StatIncorrectHeightValue_0": "Height should be {0}.",
"StatIncorrectWeightValue_0": "Weight should be {0}.",
"StatIncorrectScaleValue_0": "Scale should be {0}.",
"StatInvalidHeightWeight": "Les valeurs de taille et de poids sont statistiquement improbables.",
"StatIncorrectCP": "Les PCs calculés ne correspondent pas à la valeur enregistrée.",
"StatGigantamaxInvalid": "Le drapeau de Gigamax est incorrect.",

View File

@@ -282,10 +282,10 @@
"RibbonMarkingAffixed_0": "Fioccho o Emblema fissato invalido: {0}",
"StatDynamaxInvalid": "Il Livello Dynamax non è in un range accettabile.",
"StatIncorrectHeight": "L'Altezza calcolata non corrisponde con il valore nei dati.",
"StatIncorrectHeightCopy": "Copy Height non corrisponde il valore originale.",
"StatIncorrectHeightValue": "L'Altezza non combacia con il valore previsto.",
"StatIncorrectWeight": "Il Peso calcolato non corrisponde con il valore nei dati.",
"StatIncorrectWeightValue": "Il Peso non cirrsponde con il valore previsto.",
"StatIncorrectHeightValue_0": "Height should be {0}.",
"StatIncorrectWeightValue_0": "Weight should be {0}.",
"StatIncorrectScaleValue_0": "Scale should be {0}.",
"StatInvalidHeightWeight": "Il valore di Altezza e Peso è statisticamente improbabile.",
"StatIncorrectCP": "I PL calcolati non combaciano con il valore nei dati.",
"StatGigantamaxInvalid": "Gigamax non corrispondente.",

View File

@@ -282,10 +282,10 @@
"RibbonMarkingAffixed_0": "無効なリボン/マーキングが設定されています: {0}",
"StatDynamaxInvalid": "ダイマックスレベルが範囲外です。",
"StatIncorrectHeight": "計算された高さが保存値と一致しません。",
"StatIncorrectHeightCopy": "コピーした高さが元の高さと一致しません。",
"StatIncorrectHeightValue": "高さが範囲と一致しません。",
"StatIncorrectWeight": "計算された重さが保存値と一致しません。",
"StatIncorrectWeightValue": "重さが範囲と一致しません。",
"StatIncorrectHeightValue_0": "Height should be {0}.",
"StatIncorrectWeightValue_0": "Weight should be {0}.",
"StatIncorrectScaleValue_0": "Scale should be {0}.",
"StatInvalidHeightWeight": "高さ/重さの数値が可能範囲を超えています。",
"StatIncorrectCP": "計算されたCPが保存値と一致しません。",
"StatGigantamaxInvalid": "キョダイマックスフラグの不一致。",

View File

@@ -282,10 +282,10 @@
"RibbonMarkingAffixed_0": "Invalid Affixed Ribbon/Marking: {0}",
"StatDynamaxInvalid": "다이맥스 레벨이 예상 범위를 벗어났습니다.",
"StatIncorrectHeight": "계산된 키와 저장된 값이 일치하지 않습니다.",
"StatIncorrectHeightCopy": "Copy Height does not match the original value.",
"StatIncorrectHeightValue": "Height does not match the expected value.",
"StatIncorrectWeight": "계산된 몸무게와 저장된 값이 일치하지 않습니다.",
"StatIncorrectWeightValue": "Weight does not match the expected value.",
"StatIncorrectHeightValue_0": "Height should be {0}.",
"StatIncorrectWeightValue_0": "Weight should be {0}.",
"StatIncorrectScaleValue_0": "Scale should be {0}.",
"StatInvalidHeightWeight": "Height / Weight values are statistically improbable.",
"StatIncorrectCP": "계산된 CP와 저장된 값이 일치하지 않습니다.",
"StatGigantamaxInvalid": "거다이맥스 플래그가 일치하지 않습니다.",

View File

@@ -282,10 +282,10 @@
"RibbonMarkingAffixed_0": "无效的奖章/证章: {0}",
"StatDynamaxInvalid": "极巨等级不在预期范围内。",
"StatIncorrectHeight": "计算的身高数据与存储值不匹配",
"StatIncorrectHeightCopy": "复制身高数据与原始身高值不匹配。",
"StatIncorrectHeightValue": "身高数据与期望身高值不匹配。",
"StatIncorrectWeight": "计算的体重数据与存储值不匹配",
"StatIncorrectWeightValue": "体重数据与期望体重值不匹配。",
"StatIncorrectHeightValue_0": "Height should be {0}.",
"StatIncorrectWeightValue_0": "Weight should be {0}.",
"StatIncorrectScaleValue_0": "Scale should be {0}.",
"StatInvalidHeightWeight": "身高或体重值在统计学意义上不可获得。",
"StatIncorrectCP": "计算的CP值与存储值不匹配。",
"StatGigantamaxInvalid": "超极巨标志不匹配。",

View File

@@ -282,10 +282,10 @@
"RibbonMarkingAffixed_0": "無效之獎章/證章: {0}。",
"StatDynamaxInvalid": "極巨化等級不在預期範圍內。",
"StatIncorrectHeight": "計算之高度與存儲值不匹配。",
"StatIncorrectHeightCopy": "複製之高度與原值不匹配。",
"StatIncorrectHeightValue": "高度與期望值不匹配。",
"StatIncorrectWeight": "計算之重量與存儲值不匹配。",
"StatIncorrectWeightValue": "體重與期望值不匹配。",
"StatIncorrectHeightValue_0": "Height should be {0}.",
"StatIncorrectWeightValue_0": "Weight should be {0}.",
"StatIncorrectScaleValue_0": "Scale should be {0}.",
"StatInvalidHeightWeight": "此身高或體重於統計學意義上不可獲得。",
"StatIncorrectCP": "計算之 CP 值與存儲值不匹配。",
"StatGigantamaxInvalid": "超極巨標識不匹配。",