mirror of
https://github.com/kwsch/PKHeX
synced 2024-11-10 14:44:24 +00:00
Add shedinja dropped ribbons/marking considerations
Nice bug ya got there, gamefreak. Coulda cleared the AffixedRibbon value instead of copying it on Shedinja creation, and it would have made this unnecessary. Please ditch the Affixed Ribbon gimmick for future games, thanks!
This commit is contained in:
parent
25565e6f07
commit
2aed4c3118
6 changed files with 90 additions and 16 deletions
|
@ -95,8 +95,8 @@ namespace PKHeX.Core
|
||||||
}
|
}
|
||||||
|
|
||||||
var encounter = EncounterSuggestion.GetSuggestedMetInfo(legal.pkm);
|
var encounter = EncounterSuggestion.GetSuggestedMetInfo(legal.pkm);
|
||||||
if (encounter is IRelearn {Relearn: {Count: > 0}} r)
|
if (encounter is IRelearn {Relearn: {Count: > 0} r})
|
||||||
return r.Relearn;
|
return r;
|
||||||
|
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ namespace PKHeX.Core
|
||||||
public sealed record EncounterSlot8 : EncounterSlot, IOverworldCorrelation8
|
public sealed record EncounterSlot8 : EncounterSlot, IOverworldCorrelation8
|
||||||
{
|
{
|
||||||
public readonly AreaWeather8 Weather;
|
public readonly AreaWeather8 Weather;
|
||||||
public override string LongName => Weather == AreaWeather8.All ? wild : $"{wild} [{(((EncounterArea8)Area).PermitCrossover ? "Symbol" : "Hidden")}] - {Weather.ToString().Replace("_", string.Empty)}";
|
public override string LongName => $"{wild} [{(((EncounterArea8)Area).PermitCrossover ? "Symbol" : "Hidden")}] - {Weather.ToString().Replace("_", string.Empty)}";
|
||||||
public override int Generation => 8;
|
public override int Generation => 8;
|
||||||
|
|
||||||
public EncounterSlot8(EncounterArea8 area, int species, int form, int min, int max, AreaWeather8 weather) : base(area, species, form, min, max)
|
public EncounterSlot8(EncounterArea8 area, int species, int form, int min, int max, AreaWeather8 weather) : base(area, species, form, min, max)
|
||||||
|
@ -36,7 +36,7 @@ namespace PKHeX.Core
|
||||||
if (((EncounterArea8)Area).PermitCrossover)
|
if (((EncounterArea8)Area).PermitCrossover)
|
||||||
return MustHave; // symbol walking overworld
|
return MustHave; // symbol walking overworld
|
||||||
|
|
||||||
bool curry = pk is IRibbonSetMark8 {RibbonMarkCurry: true};
|
bool curry = pk is IRibbonSetMark8 {RibbonMarkCurry: true} || pk.Species == (int)Core.Species.Shedinja && pk is PK8 {AffixedRibbon:(int)RibbonIndex.MarkCurry};
|
||||||
if (curry)
|
if (curry)
|
||||||
return MustNotHave;
|
return MustNotHave;
|
||||||
|
|
||||||
|
|
|
@ -84,6 +84,17 @@ namespace PKHeX.Core
|
||||||
return EncounterMatchRating.Deferred;
|
return EncounterMatchRating.Deferred;
|
||||||
|
|
||||||
// Only encounter slots can have these marks; defer for collisions.
|
// Only encounter slots can have these marks; defer for collisions.
|
||||||
|
if (pkm.Species == (int) Core.Species.Shedinja)
|
||||||
|
{
|
||||||
|
// Loses Mark on evolution to Shedinja, but not affixed ribbon value.
|
||||||
|
return pkm switch
|
||||||
|
{
|
||||||
|
IRibbonSetMark8 {RibbonMarkCurry: true} => EncounterMatchRating.Deferred,
|
||||||
|
PK8 {AffixedRibbon: (int) RibbonIndex.MarkCurry} => EncounterMatchRating.Deferred,
|
||||||
|
_ => EncounterMatchRating.Match
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
if (pkm is IRibbonSetMark8 m && (m.RibbonMarkCurry || m.RibbonMarkFishing))
|
if (pkm is IRibbonSetMark8 m && (m.RibbonMarkCurry || m.RibbonMarkFishing))
|
||||||
return EncounterMatchRating.Deferred;
|
return EncounterMatchRating.Deferred;
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,8 @@ namespace PKHeX.Core
|
||||||
|
|
||||||
if (pkm is IRibbonSetMark8 m8 && m8.HasMark())
|
if (pkm is IRibbonSetMark8 m8 && m8.HasMark())
|
||||||
return false;
|
return false;
|
||||||
|
if (pkm.Species == (int)Core.Species.Shedinja && pkm is PK8 { AffixedRibbon: >= (int)RibbonIndex.MarkLunchtime })
|
||||||
|
return false;
|
||||||
|
|
||||||
return base.IsMatchExact(pkm, evo);
|
return base.IsMatchExact(pkm, evo);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using static PKHeX.Core.LegalityCheckStrings;
|
using System.Linq;
|
||||||
|
using static PKHeX.Core.LegalityCheckStrings;
|
||||||
|
|
||||||
namespace PKHeX.Core
|
namespace PKHeX.Core
|
||||||
{
|
{
|
||||||
|
@ -15,7 +16,7 @@ namespace PKHeX.Core
|
||||||
if (pkm is not IRibbonIndex m)
|
if (pkm is not IRibbonIndex m)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (data.Info.Generation != 8)
|
if (data.Info.Generation != 8 || (pkm.Species == (int)Species.Shedinja && data.EncounterOriginal.Species is not (int)Species.Shedinja)) // Shedinja doesn't copy Ribbons or Marks
|
||||||
VerifyNoMarksPresent(data, m);
|
VerifyNoMarksPresent(data, m);
|
||||||
else
|
else
|
||||||
VerifyMarksPresent(data, m);
|
VerifyMarksPresent(data, m);
|
||||||
|
@ -126,9 +127,68 @@ namespace PKHeX.Core
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ((byte)affix > (int)RibbonIndex.MarkSlump)
|
if ((byte)affix > (int)RibbonIndex.MarkSlump)
|
||||||
|
{
|
||||||
data.AddLine(GetInvalid(string.Format(LRibbonMarkingAffixedF_0, affix)));
|
data.AddLine(GetInvalid(string.Format(LRibbonMarkingAffixedF_0, affix)));
|
||||||
else if (!pk8.GetRibbonIndex((RibbonIndex)affix))
|
return;
|
||||||
data.AddLine(GetInvalid(string.Format(LRibbonMarkingAffixedF_0, (RibbonIndex)affix)));
|
}
|
||||||
|
|
||||||
|
if (pk8.Species == (int)Species.Shedinja && data.EncounterOriginal.Species is not (int)Species.Shedinja)
|
||||||
|
{
|
||||||
|
VerifyShedinjaAffixed(data, affix, pk8);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
EnsureHasRibbon(data, pk8, affix);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void VerifyShedinjaAffixed(LegalityAnalysis data, sbyte affix, PK8 pk8)
|
||||||
|
{
|
||||||
|
// Does not copy ribbons or marks, but retains the Affixed Ribbon value.
|
||||||
|
// Try re-verifying to see if it could have had the Ribbon/Mark.
|
||||||
|
|
||||||
|
if ((byte) affix >= (int) RibbonIndex.MarkLunchtime)
|
||||||
|
{
|
||||||
|
if (data.EncounterOriginal.Generation != 8)
|
||||||
|
data.AddLine(GetInvalid(string.Format(LRibbonMarkingAffixedF_0, (RibbonIndex) affix)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var enc = data.EncounterOriginal;
|
||||||
|
if (enc.Generation <= 4 && (pk8.Ball != (int)Ball.Poke || IsMoveSetEvolvedShedinja(pk8)))
|
||||||
|
{
|
||||||
|
// Evolved in a prior generation.
|
||||||
|
EnsureHasRibbon(data, pk8, affix);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var clone = pk8.Clone();
|
||||||
|
clone.Species = (int) Species.Nincada;
|
||||||
|
((IRibbonIndex) clone).SetRibbon(affix);
|
||||||
|
var parse = RibbonVerifier.GetRibbonResults(clone, data.EncounterOriginal);
|
||||||
|
var expect = $"Ribbon{(RibbonIndex) affix}";
|
||||||
|
var name = RibbonStrings.GetName(expect);
|
||||||
|
bool invalid = parse.FirstOrDefault(z => z.Name == name)?.Invalid == true;
|
||||||
|
var severity = invalid ? Severity.Invalid : Severity.Fishy;
|
||||||
|
data.AddLine(Get(string.Format(LRibbonMarkingAffixedF_0, affix), severity));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsMoveSetEvolvedShedinja(PK8 pk8)
|
||||||
|
{
|
||||||
|
if (pk8.HasMove((int) Move.Screech))
|
||||||
|
return true;
|
||||||
|
if (pk8.HasMove((int) Move.SwordsDance))
|
||||||
|
return true;
|
||||||
|
if (pk8.HasMove((int) Move.Slash))
|
||||||
|
return true;
|
||||||
|
if (pk8.HasMove((int) Move.BatonPass))
|
||||||
|
return true;
|
||||||
|
return pk8.HasMove((int)Move.Agility) && !pk8.GetMoveRecordFlag(12);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void EnsureHasRibbon(LegalityAnalysis data, PK8 pk8, sbyte affix)
|
||||||
|
{
|
||||||
|
var hasRibbon = pk8.GetRibbonIndex((RibbonIndex) affix);
|
||||||
|
if (!hasRibbon)
|
||||||
|
data.AddLine(GetInvalid(string.Format(LRibbonMarkingAffixedF_0, (RibbonIndex) affix)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ namespace PKHeX.Core
|
||||||
|
|
||||||
public override void Verify(LegalityAnalysis data)
|
public override void Verify(LegalityAnalysis data)
|
||||||
{
|
{
|
||||||
|
// Flag VC (Gen1/2) ribbons using Gen7 origin rules.
|
||||||
var enc = data.EncounterMatch;
|
var enc = data.EncounterMatch;
|
||||||
var pkm = data.pkm;
|
var pkm = data.pkm;
|
||||||
|
|
||||||
|
@ -25,8 +26,7 @@ namespace PKHeX.Core
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int gen = enc.Generation; // Flag VC (Gen1/2) ribbons using Gen7 origin rules.
|
var result = GetIncorrectRibbons(pkm, enc);
|
||||||
var result = GetIncorrectRibbons(pkm, enc, gen);
|
|
||||||
if (result.Count != 0)
|
if (result.Count != 0)
|
||||||
{
|
{
|
||||||
var msg = string.Join(Environment.NewLine, result);
|
var msg = string.Join(Environment.NewLine, result);
|
||||||
|
@ -38,11 +38,11 @@ namespace PKHeX.Core
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<string> GetIncorrectRibbons(PKM pkm, IEncounterable enc, int gen)
|
private static List<string> GetIncorrectRibbons(PKM pkm, IEncounterable enc)
|
||||||
{
|
{
|
||||||
List<string> missingRibbons = new();
|
List<string> missingRibbons = new();
|
||||||
List<string> invalidRibbons = new();
|
List<string> invalidRibbons = new();
|
||||||
var ribs = GetRibbonResults(pkm, enc, gen);
|
var ribs = GetRibbonResults(pkm, enc);
|
||||||
foreach (var bad in ribs)
|
foreach (var bad in ribs)
|
||||||
(bad.Invalid ? invalidRibbons : missingRibbons).Add(bad.Name);
|
(bad.Invalid ? invalidRibbons : missingRibbons).Add(bad.Name);
|
||||||
|
|
||||||
|
@ -75,14 +75,14 @@ namespace PKHeX.Core
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IEnumerable<RibbonResult> GetRibbonResults(PKM pkm, IEncounterable enc, int gen)
|
internal static IEnumerable<RibbonResult> GetRibbonResults(PKM pkm, IEncounterable enc)
|
||||||
{
|
{
|
||||||
return GetInvalidRibbons(pkm, enc, gen)
|
return GetInvalidRibbons(pkm, enc)
|
||||||
.Concat(GetInvalidRibbonsEvent1(pkm, enc))
|
.Concat(GetInvalidRibbonsEvent1(pkm, enc))
|
||||||
.Concat(GetInvalidRibbonsEvent2(pkm, enc));
|
.Concat(GetInvalidRibbonsEvent2(pkm, enc));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IEnumerable<RibbonResult> GetInvalidRibbons(PKM pkm, IEncounterable enc, int gen)
|
private static IEnumerable<RibbonResult> GetInvalidRibbons(PKM pkm, IEncounterable enc)
|
||||||
{
|
{
|
||||||
if (pkm is IRibbonSetOnly3 o3)
|
if (pkm is IRibbonSetOnly3 o3)
|
||||||
{
|
{
|
||||||
|
@ -91,7 +91,7 @@ namespace PKHeX.Core
|
||||||
}
|
}
|
||||||
if (pkm is IRibbonSetUnique3 u3)
|
if (pkm is IRibbonSetUnique3 u3)
|
||||||
{
|
{
|
||||||
if (gen != 3)
|
if (enc.Generation != 3)
|
||||||
{
|
{
|
||||||
if (u3.RibbonWinning)
|
if (u3.RibbonWinning)
|
||||||
yield return new RibbonResult(nameof(u3.RibbonWinning));
|
yield return new RibbonResult(nameof(u3.RibbonWinning));
|
||||||
|
@ -107,6 +107,7 @@ namespace PKHeX.Core
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int gen = enc.Generation;
|
||||||
if (pkm is IRibbonSetUnique4 u4)
|
if (pkm is IRibbonSetUnique4 u4)
|
||||||
{
|
{
|
||||||
if (!IsAllowedBattleFrontier(pkm.Species, pkm.Form, 4) || gen > 4)
|
if (!IsAllowedBattleFrontier(pkm.Species, pkm.Form, 4) || gen > 4)
|
||||||
|
|
Loading…
Reference in a new issue