Add Pressure/Flute encounter modifications

Thanks Angeflo for the report, including test cases.
This commit is contained in:
Kaphotics
2016-04-20 19:47:40 -07:00
parent 82ee4ac1bf
commit 4d1c621eb5
3 changed files with 95 additions and 42 deletions

View File

@@ -277,9 +277,29 @@ private LegalityCheck verifyEncounter()
EncounterMatch = Legal.getValidWildEncounters(pk6);
if (EncounterMatch != null)
{
return ((EncounterSlot[])EncounterMatch).Any(slot => !slot.DexNav)
? new LegalityCheck(Severity.Valid, "Valid encounter at location.")
: new LegalityCheck(Severity.Valid, "Valid DexNav encounter at location.");
EncounterSlot[] enc = (EncounterSlot[])EncounterMatch;
if (enc.Any(slot => slot.Normal))
return enc.All(slot => slot.Pressure)
? new LegalityCheck(Severity.Valid, "Valid encounter at location (Pressure/Hustle/Vital Spirit).")
: new LegalityCheck(Severity.Valid, "Valid encounter at location.");
// Decreased Level Encounters
if (enc.Any(slot => slot.WhiteFlute))
return enc.All(slot => slot.Pressure)
? new LegalityCheck(Severity.Valid, "Valid encounter at location (White Flute & Pressure/Hustle/Vital Spirit).")
: new LegalityCheck(Severity.Valid, "Valid encounter at location (White Flute).");
// Increased Level Encounters
if (enc.Any(slot => slot.BlackFlute))
return enc.All(slot => slot.Pressure)
? new LegalityCheck(Severity.Valid, "Valid encounter at location (Black Flute & Pressure/Hustle/Vital Spirit).")
: new LegalityCheck(Severity.Valid, "Valid encounter at location (Black Flute).");
if (enc.Any(slot => slot.Pressure))
return new LegalityCheck(Severity.Valid, "Valid encounter at location (Pressure/Hustle/Vital Spirit).");
return new LegalityCheck(Severity.Valid, "Valid encounter at location (DexNav).");
}
EncounterMatch = Legal.getValidIngameTrade(pk6);
if (EncounterMatch != null)

View File

@@ -19,8 +19,6 @@ public static partial class Legal
private static readonly EncounterArea[] SlotsO;
private static readonly EncounterArea[] SlotsX;
private static readonly EncounterArea[] SlotsY;
private static readonly EncounterArea[] DexNavA;
private static readonly EncounterArea[] DexNavO;
private static readonly EncounterStatic[] StaticX;
private static readonly EncounterStatic[] StaticY;
private static readonly EncounterStatic[] StaticA;
@@ -42,18 +40,6 @@ private static EncounterArea[] addXYAltTiles(EncounterArea[] GameSlots, Encounte
}
return GameSlots;
}
private static EncounterArea[] getDexNavSlots(EncounterArea[] GameSlots)
{
EncounterArea[] eA = new EncounterArea[GameSlots.Length];
for (int i = 0; i < eA.Length; i++)
{
eA[i] = new EncounterArea { Location = GameSlots[i].Location, Slots = GameSlots[i].Slots };
eA[i].Slots = eA[i].Slots.Where(s => s.Type != SlotType.Rock_Smash).ToArray(); // Skip Rock Smash slots.
foreach (var slot in eA[i].Slots)
slot.DexNav = true;
}
return eA;
}
static Legal() // Setup
{
@@ -84,7 +70,7 @@ private static EncounterArea[] getDexNavSlots(EncounterArea[] GameSlots)
SlotsA = EncounterArea.getArray(Data.unpackMini(Properties.Resources.encounter_a, "ao"));
SlotsO = EncounterArea.getArray(Data.unpackMini(Properties.Resources.encounter_o, "ao"));
// Mark Rock Smash Encounters
// Mark Encounters
foreach (var area in SlotsA)
{
for (int i = 32; i < 37; i++)
@@ -92,6 +78,9 @@ private static EncounterArea[] getDexNavSlots(EncounterArea[] GameSlots)
int slotct = area.Slots.Length;
for (int i = slotct - 15; i < slotct; i++)
area.Slots[i].Type = SlotType.Horde;
for (int i = 0; i < slotct; i++)
area.Slots[i].AllowDexNav = area.Slots[i].Type != SlotType.Rock_Smash;
}
foreach (var area in SlotsO)
{
@@ -100,10 +89,10 @@ private static EncounterArea[] getDexNavSlots(EncounterArea[] GameSlots)
int slotct = area.Slots.Length;
for (int i = slotct - 15; i < slotct; i++)
area.Slots[i].Type = SlotType.Horde;
}
DexNavA = getDexNavSlots(SlotsA);
DexNavO = getDexNavSlots(SlotsO);
for (int i = 0; i < slotct; i++)
area.Slots[i].AllowDexNav = area.Slots[i].Type != SlotType.Rock_Smash;
}
}
internal static IEnumerable<int> getValidMoves(PK6 pk6)
@@ -220,13 +209,7 @@ internal static EncounterSlot[] getValidWildEncounters(PK6 pk6)
List<EncounterSlot> s = new List<EncounterSlot>();
foreach (var area in getEncounterAreas(pk6))
s.AddRange(getValidEncounterSlots(pk6, area, DexNav: false));
if (s.Any()) return s.ToArray();
if (!pk6.AO) return null;
// By default, no slots are currently stored. Continue!
foreach (var area in getDexNavAreas(pk6))
s.AddRange(getValidEncounterSlots(pk6, area, DexNav: true));
s.AddRange(getValidEncounterSlots(pk6, area, DexNav: pk6.AO));
return s.Any() ? s.ToArray() : null;
}
internal static EncounterStatic getValidStaticEncounter(PK6 pk6)
@@ -328,7 +311,7 @@ internal static EncounterSlot[] getValidFriendSafari(PK6 pk6)
internal static bool getDexNavValid(PK6 pk6)
{
IEnumerable<EncounterArea> locs = getDexNavAreas(pk6);
return locs.Select(loc => getValidEncounterSlots(pk6, loc, DexNav: true)).Any(slots => slots.Any());
return locs.Select(loc => getValidEncounterSlots(pk6, loc, DexNav: true)).Any(slots => slots.Any(slot => slot.AllowDexNav && slot.DexNav));
}
internal static bool getHasEvolved(PK6 pk6)
{
@@ -385,7 +368,7 @@ private static IEnumerable<EncounterArea> getDexNavAreas(PK6 pk6)
bool alpha = pk6.Version == 26;
if (!alpha && pk6.Version != 27)
return new EncounterArea[0];
return (alpha ? DexNavA : DexNavO).Where(l => l.Location == pk6.Met_Location);
return (alpha ? SlotsA : SlotsO).Where(l => l.Location == pk6.Met_Location);
}
private static IEnumerable<int> getLVLMoves(int species, int lvl, int formnum)
{
@@ -429,32 +412,67 @@ private static IEnumerable<EncounterArea> getEncounterAreas(PK6 pk6)
}
private static IEnumerable<EncounterSlot> getValidEncounterSlots(PK6 pk6, EncounterArea loc, bool DexNav)
{
const int fluteBoost = 4;
const int dexnavBoost = 30;
int df = DexNav ? fluteBoost : 0;
int dn = DexNav ? fluteBoost + dexnavBoost : 0;
List<EncounterSlot> slotdata = new List<EncounterSlot>();
// Get Valid levels
IEnumerable<DexLevel> vs = getValidPreEvolutions(pk6);
// Get slots where pokemon can exist
IEnumerable<EncounterSlot> slots = loc.Slots.Where(slot => vs.Any(evo => evo.Species == slot.Species && evo.Level >= slot.LevelMin));
IEnumerable<EncounterSlot> slots = loc.Slots.Where(slot => vs.Any(evo => evo.Species == slot.Species && evo.Level >= slot.LevelMin - df));
// Filter for Met Level
int lvl = pk6.Met_Level;
slots = DexNav
? slots.Where(slot => slot.LevelMin <= lvl && lvl <= slot.LevelMax + 30) // DexNav Boost Range ??
: slots.Where(slot => slot.LevelMin <= lvl && lvl <= slot.LevelMax); // Non-boosted Level
EncounterSlot[] encounterSlots = slots.Where(slot => slot.LevelMin - df <= lvl && lvl <= slot.LevelMax + (slot.AllowDexNav ? dn : df)).ToArray();
// Filter for Form Specific
if (WildForms.Contains(pk6.Species))
slots = slots.Where(slot => slot.Form == pk6.AltForm);
return slots;
// Pressure Slot
EncounterSlot slotMax = encounterSlots.OrderByDescending(slot => slot.LevelMax).FirstOrDefault();
if (!DexNav)
{
// Filter for Form Specific
slotdata.AddRange(WildForms.Contains(pk6.Species)
? encounterSlots.Where(slot => slot.Form == pk6.AltForm)
: encounterSlots);
if (slotMax != null)
slotdata.Add(new EncounterSlot(slotMax) { Pressure = true, Form = pk6.AltForm });
return slotdata;
}
foreach (EncounterSlot slot in encounterSlots.Where(slot => !WildForms.Contains(pk6.Species) || slot.Form == pk6.AltForm))
{
if (slot.LevelMin >= lvl)
slotdata.Add(new EncounterSlot(slot) { WhiteFlute = true });
else if (slot.LevelMax + 1 <= lvl && lvl <= slot.LevelMax + fluteBoost)
slotdata.Add(new EncounterSlot(slot) { BlackFlute = true });
else if (slot.LevelMax != lvl && slot.AllowDexNav)
slotdata.Add(new EncounterSlot(slot) { DexNav = true });
else
slotdata.Add(new EncounterSlot(slot));
}
if (slotMax != null)
{
EncounterSlot slot = new EncounterSlot(slotMax) {Pressure = true, Form = pk6.AltForm};
if (slot.LevelMin >= lvl)
slot.WhiteFlute = true;
else if (slot.LevelMax + 1 <= lvl && lvl <= slot.LevelMax + fluteBoost)
slot.BlackFlute = true;
else if (slot.LevelMax != lvl && slot.AllowDexNav)
slot.DexNav = true;
slotdata.Add(slot);
}
return slotdata;
}
private static IEnumerable<EncounterArea> getSlots(PK6 pk6, IEnumerable<EncounterArea> tables)
{
int species = pk6.Species;
IEnumerable<DexLevel> vs = getValidPreEvolutions(pk6);
List<EncounterArea> slotLocations = new List<EncounterArea>();
foreach (var loc in tables)
{
IEnumerable<EncounterSlot> slots = loc.Slots.Where(slot => vs.Any(evo => evo.Species == slot.Species && evo.Level >= slot.LevelMin));
if (WildForms.Contains(species))
slots = slots.Where(slot => slot.Form == pk6.AltForm);
IEnumerable<EncounterSlot> slots = loc.Slots.Where(slot => vs.Any(evo => evo.Species == slot.Species));
EncounterSlot[] es = slots.ToArray();
if (es.Length > 0)

View File

@@ -135,7 +135,22 @@ public class EncounterSlot
public int LevelMin;
public int LevelMax;
public SlotType Type = SlotType.Any;
public bool AllowDexNav = false;
public bool Pressure = false;
public bool DexNav = false;
public bool WhiteFlute = false;
public bool BlackFlute = false;
public bool Normal => !(WhiteFlute || BlackFlute || DexNav);
public EncounterSlot() { }
public EncounterSlot(EncounterSlot template)
{
Species = template.Species;
AllowDexNav = template.AllowDexNav;
LevelMax = template.LevelMax;
LevelMin = template.LevelMin;
Type = template.Type;
}
}
public enum SlotType