mirror of
https://github.com/kwsch/PKHeX
synced 2024-11-27 06:20:25 +00:00
b0da14b71e
Adds a basic editor for recorded Geonet/Unity Tower locations for the Gen 4/5 games, building on this [post by Danius88](https://projectpokemon.org/home/forums/topic/62055-bw-b2w2-unity-tower-geonet-and-passerby-research/). So far, I've implemented buttons that set all locations (including unused ones), set all legal locations, and clear all recorded locations; and checkboxes to toggle whether the whole globe is visible (used in Japanese games) and whether the ferry to Unity Tower is unlocked. Haven't implemented any UI for editing the status of individual locations, since I'm not sure how to lay it out. Also haven't implemented anything related to how the data of the other players in Unity Tower is stored.
127 lines
3.8 KiB
C#
127 lines
3.8 KiB
C#
using System;
|
|
|
|
namespace PKHeX.Core;
|
|
|
|
public sealed class Geonet4
|
|
{
|
|
private readonly SAV4 SAV;
|
|
|
|
/* Lets the globe be panned outside Japan and zoomed out in Japanese games. Has no effect in non-Japanese games.
|
|
* Set once you register a location outside of Japan, even if it's just your own location in a non-Japanese game. */
|
|
public bool GlobalFlag { get; set; }
|
|
|
|
private readonly byte[] Data;
|
|
private readonly int Offset;
|
|
private const int CountryCount = 233;
|
|
|
|
private static ReadOnlySpan<byte> LegalCountries => new byte[]
|
|
{
|
|
001, 002, 003, 006, 008, 009, 012, 013, 015, 016, 017, 018, 020, 021, 022, 023,
|
|
025, 027, 028, 029, 031, 033, 034, 035, 036, 040, 042, 043, 045, 048, 049, 050,
|
|
052, 054, 055, 056, 058, 059, 060, 061, 062, 069, 070, 071, 072, 074, 077, 078,
|
|
079, 080, 081, 082, 083, 085, 086, 088, 089, 090, 091, 092, 093, 094, 095, 097,
|
|
098, 100, 101, 102, 103, 104, 107, 111, 115, 117, 118, 121, 122, 126, 129, 131,
|
|
133, 135, 140, 142, 146, 148, 149, 150, 151, 152, 156, 157, 158, 160, 161, 163,
|
|
164, 166, 167, 110, 171, 172, 179, 183, 186, 187, 188, 189, 192, 193, 194, 196,
|
|
198, 199, 200, 202, 205, 207, 211, 212, 216, 218, 219, 204, 221, 220, 222, 224,
|
|
226, 227,
|
|
};
|
|
|
|
public static byte GetSubregionCount(byte country) => country switch
|
|
{
|
|
009 => 24,
|
|
012 => 7,
|
|
028 => 27,
|
|
036 => 13,
|
|
043 => 31,
|
|
070 => 6,
|
|
071 => 22,
|
|
077 => 16,
|
|
094 => 35,
|
|
101 => 20,
|
|
103 => 50,
|
|
156 => 20,
|
|
166 => 16,
|
|
172 => 7,
|
|
193 => 17,
|
|
199 => 24,
|
|
219 => 12,
|
|
220 => 51,
|
|
_ => 0,
|
|
};
|
|
|
|
public enum Point
|
|
{
|
|
None = 0, // never communicated with
|
|
Blue = 1, // first communicated with today
|
|
Yellow = 2, // already communicated with
|
|
Red = 3, // own registered location
|
|
}
|
|
|
|
public Geonet4(SAV4 sav)
|
|
{
|
|
SAV = sav;
|
|
Offset = SAV.Geonet + 3;
|
|
GlobalFlag = SAV.GeonetGlobalFlag;
|
|
Data = SAV.General.Slice(Offset, CountryCount * 16).ToArray();
|
|
}
|
|
|
|
public void Save()
|
|
{
|
|
SAV.GeonetGlobalFlag = GlobalFlag;
|
|
SAV.SetData(SAV.General.Slice(Offset, CountryCount * 16), Data);
|
|
}
|
|
|
|
public void SetCountrySubregion(byte country, byte subregion, Point point)
|
|
{
|
|
int index = ((country - 1) * 16) + (subregion / 4);
|
|
int shift = 2 * (subregion % 4);
|
|
Data[index] = (byte)((Data[index] & ~(0b11 << shift)) | ((int)point << shift));
|
|
}
|
|
|
|
private void SetAllSubregions(byte country, Point type)
|
|
{
|
|
var subregionCount = GetSubregionCount(country);
|
|
if (subregionCount == 0)
|
|
{
|
|
SetCountrySubregion(country, 0, type);
|
|
return;
|
|
}
|
|
|
|
for (byte subregion = 1; subregion <= subregionCount; subregion++)
|
|
SetCountrySubregion(country, subregion, type);
|
|
}
|
|
|
|
public void SetAll()
|
|
{
|
|
for (byte country = 1; country <= CountryCount; country++)
|
|
SetAllSubregions(country, Point.Yellow);
|
|
|
|
if (SAV.Country > 0)
|
|
SetCountrySubregion((byte)SAV.Country, (byte)SAV.Region, Point.Red);
|
|
|
|
GlobalFlag = true;
|
|
}
|
|
|
|
public void SetAllLegal()
|
|
{
|
|
foreach (var country in LegalCountries)
|
|
SetAllSubregions(country, Point.Yellow);
|
|
|
|
if (SAV.Country > 0)
|
|
SetCountrySubregion((byte)SAV.Country, (byte)SAV.Region, Point.Red);
|
|
|
|
GlobalFlag = true;
|
|
}
|
|
|
|
public void ClearAll()
|
|
{
|
|
for (byte country = 1; country <= CountryCount; country++)
|
|
SetAllSubregions(country, Point.None);
|
|
|
|
if (SAV.Country > 0)
|
|
SetCountrySubregion((byte)SAV.Country, (byte)SAV.Region, Point.Red);
|
|
|
|
GlobalFlag = (SAV.Country > 0 && SAV.Country != 103);
|
|
}
|
|
}
|