From 7bef8606c3c2100e735904db676cb52aae634ccf Mon Sep 17 00:00:00 2001 From: AstrandPallas Date: Mon, 9 Feb 2026 13:00:17 -0800 Subject: [PATCH 1/3] Implement PokePara system with Ghidra-accurate methods - PokePara: CoreParam, CoreDataBlocks A/B/D, Accessor, CalcTool, EvolveManager, BoxMarkController, SavePokeParty, SerializedPokemon (Core/Extensions/Full) - WazaData: WazaDataSystem, SickContParam - Item: ItemData, ItemManager, ItemTableExtensions (incl. GetHealingItemType) - PokeParty with member management and pokerus stubs - Battle/Logic: WAZADATA wrappers, BTL_ACTION, calc utilities --- Assets/Scripts/Dpr/Battle/Logic/BTL_ACTION.cs | 253 +- Assets/Scripts/Dpr/Battle/Logic/WAZADATA.cs | 166 +- Assets/Scripts/Dpr/Battle/Logic/calc.cs | 944 ++++- Assets/Scripts/Pml/Item/ItemData.cs | 185 +- Assets/Scripts/Pml/Item/ItemManager.cs | 125 +- .../Scripts/Pml/Item/ItemTableExtensions.cs | 237 +- Assets/Scripts/Pml/PokePara/Accessor.cs | 3343 ++++++++++++++--- .../Scripts/Pml/PokePara/BoxMarkController.cs | 17 +- Assets/Scripts/Pml/PokePara/CalcTool.cs | 256 +- Assets/Scripts/Pml/PokePara/CoreDataBlockA.cs | 97 +- Assets/Scripts/Pml/PokePara/CoreDataBlockB.cs | 70 +- Assets/Scripts/Pml/PokePara/CoreDataBlockD.cs | 16 +- Assets/Scripts/Pml/PokePara/CoreParam.cs | 1774 +++++++-- Assets/Scripts/Pml/PokePara/EvolveManager.cs | 229 +- Assets/Scripts/Pml/PokePara/SavePokeParty.cs | 44 +- .../Pml/PokePara/SerializedPokemonCore.cs | 15 +- .../PokePara/SerializedPokemonExtensions.cs | 26 +- .../Pml/PokePara/SerializedPokemonFull.cs | 25 +- Assets/Scripts/Pml/PokeParty.cs | 297 +- Assets/Scripts/Pml/WazaData/SickContParam.cs | 23 +- Assets/Scripts/Pml/WazaData/WazaDataSystem.cs | 233 +- 21 files changed, 6827 insertions(+), 1548 deletions(-) diff --git a/Assets/Scripts/Dpr/Battle/Logic/BTL_ACTION.cs b/Assets/Scripts/Dpr/Battle/Logic/BTL_ACTION.cs index 32d884b52..43e32acfd 100644 --- a/Assets/Scripts/Dpr/Battle/Logic/BTL_ACTION.cs +++ b/Assets/Scripts/Dpr/Battle/Logic/BTL_ACTION.cs @@ -4,85 +4,178 @@ namespace Dpr.Battle.Logic { public static class BTL_ACTION { - // TODO - public static void SetFightParam(ref BTL_ACTION_PARAM p, byte pokeID, WazaNo waza, BtlPokePos targetPos, bool forbidGWaza = false, bool forceGWaza = false) { } - - // TODO - public static void ChangeFightTargetPos(ref BTL_ACTION_PARAM p, BtlPokePos nextTargetPos) { } - - // TODO - public static void FightParamToWazaInfoMode(ref BTL_ACTION_PARAM p) { } - - // TODO - public static bool IsWazaInfoMode(ref BTL_ACTION_PARAM p) { return default; } - - // TODO - public static bool IsFight(ref BTL_ACTION_PARAM p) { return default; } - - // TODO - public static bool IsFightWithG(ref BTL_ACTION_PARAM p) { return default; } - - // TODO - public static bool IsGStart(ref BTL_ACTION_PARAM p) { return default; } - - // TODO - public static bool IsItem(ref BTL_ACTION_PARAM p) { return default; } - - // TODO - public static bool IsCheer(ref BTL_ACTION_PARAM p) { return default; } - - // TODO - public static WazaNo GetWazaID(ref BTL_ACTION_PARAM act) { return default; } - - // TODO - public static BtlPokePos GetWazaTargetPos(ref BTL_ACTION_PARAM act) { return default; } - - // TODO - public static WazaNo GetOriginalWazaID(ref BTL_ACTION_PARAM act) { return default; } - - // TODO - public static void SetItemParam(ref BTL_ACTION_PARAM p, byte pokeID, ushort itemNumber, byte targetID, byte wazaIdx) { } - - // TODO - public static void SetChangeParam(ref BTL_ACTION_PARAM p, byte posIdx, byte memberIdx) { } - - // TODO - public static void SetChangeDepleteParam(ref BTL_ACTION_PARAM p) { } - - // TODO - public static bool IsDeplete(in BTL_ACTION_PARAM p) { return default; } - - // TODO - public static void SetEscapeParam(ref BTL_ACTION_PARAM p, byte pokeID) { } - - // TODO - public static void SetCheer(ref BTL_ACTION_PARAM p) { } - - // TODO - public static void SetSafariBall(ref BTL_ACTION_PARAM p, byte pokeID) { } - - // TODO - public static void SetSafariEsa(ref BTL_ACTION_PARAM p, byte pokeID) { } - - // TODO - public static void SetSafariDoro(ref BTL_ACTION_PARAM p, byte pokeID) { } - - // TODO - public static void SetSafariYousumi(ref BTL_ACTION_PARAM p, byte pokeID) { } - - // TODO - public static void SetNULL(ref BTL_ACTION_PARAM p) { } - - // TODO - public static void SetSkip(ref BTL_ACTION_PARAM p, byte pokeID) { } - - // TODO - public static BtlAction GetAction(in BTL_ACTION_PARAM p) { return default; } - - // TODO - public static void SetRecPlayOver(ref BTL_ACTION_PARAM act) { } - - // TODO - public static void SetRecPlayError(ref BTL_ACTION_PARAM act) { } + public static void SetFightParam(ref BTL_ACTION_PARAM p, byte pokeID, WazaNo waza, BtlPokePos targetPos, bool forbidGWaza = false, bool forceGWaza = false) + { + p.fight_cmd = (byte)BtlAction.BTL_ACTION_FIGHT; + p.fight_pokeID = pokeID; + p.fight_waza = (ushort)waza; + p.fight_targetPos = (byte)targetPos; + p.fight_wazaInfoFlag = false; + p.fight_ultraBurstFlag = false; + p.fight_gFlag = false; + p.fight_forbidGWaza = forbidGWaza; + p.fight_forceGWaza = forceGWaza; + } + + public static void ChangeFightTargetPos(ref BTL_ACTION_PARAM p, BtlPokePos nextTargetPos) + { + if ((byte)nextTargetPos != 5 && p.fight_cmd == (byte)BtlAction.BTL_ACTION_FIGHT) + { + p.fight_targetPos = (byte)nextTargetPos; + } + } + + public static void FightParamToWazaInfoMode(ref BTL_ACTION_PARAM p) + { + if (p.fight_cmd == (byte)BtlAction.BTL_ACTION_FIGHT) + { + p.fight_wazaInfoFlag = true; + } + } + + public static bool IsWazaInfoMode(ref BTL_ACTION_PARAM p) + { + return p.fight_cmd == (byte)BtlAction.BTL_ACTION_FIGHT && p.fight_wazaInfoFlag; + } + + public static bool IsFight(ref BTL_ACTION_PARAM p) + { + return p.gen_cmd == (byte)BtlAction.BTL_ACTION_FIGHT; + } + + public static bool IsFightWithG(ref BTL_ACTION_PARAM p) + { + return p.fight_cmd == (byte)BtlAction.BTL_ACTION_FIGHT && p.fight_gFlag; + } + + public static bool IsGStart(ref BTL_ACTION_PARAM p) + { + return p.gen_cmd == (byte)BtlAction.BTL_ACTION_G_START; + } + + public static bool IsItem(ref BTL_ACTION_PARAM p) + { + return p.gen_cmd == (byte)BtlAction.BTL_ACTION_ITEM; + } + + public static bool IsCheer(ref BTL_ACTION_PARAM p) + { + return p.gen_cmd == (byte)BtlAction.BTL_ACTION_CHEER; + } + + public static WazaNo GetWazaID(ref BTL_ACTION_PARAM act) + { + if (act.fight_cmd != (byte)BtlAction.BTL_ACTION_FIGHT) + { + return WazaNo.NULL; + } + return (WazaNo)act.fight_waza; + } + + public static BtlPokePos GetWazaTargetPos(ref BTL_ACTION_PARAM act) + { + if (act.fight_cmd != (byte)BtlAction.BTL_ACTION_FIGHT) + { + return BtlPokePos.POS_NULL; + } + return (BtlPokePos)act.fight_targetPos; + } + + public static WazaNo GetOriginalWazaID(ref BTL_ACTION_PARAM act) + { + if (act.fight_cmd != (byte)BtlAction.BTL_ACTION_FIGHT) + { + return WazaNo.NULL; + } + return (WazaNo)act.fight_waza; + } + + public static void SetItemParam(ref BTL_ACTION_PARAM p, byte pokeID, ushort itemNumber, byte targetID, byte wazaIdx) + { + p.item_cmd = (byte)BtlAction.BTL_ACTION_ITEM; + p.item_pokeID = pokeID; + p.item_number = itemNumber; + p.item_targetID = targetID; + p.item_param = wazaIdx; + } + + public static void SetChangeParam(ref BTL_ACTION_PARAM p, byte posIdx, byte memberIdx) + { + p.change_cmd = (byte)BtlAction.BTL_ACTION_CHANGE; + p.change_posIdx = posIdx; + p.change_memberIdx = memberIdx; + p.change_depleteFlag = false; + } + + public static void SetChangeDepleteParam(ref BTL_ACTION_PARAM p) + { + p.raw = 0x81f3; + } + + public static bool IsDeplete(in BTL_ACTION_PARAM p) + { + return (p.raw & 0x800f) == 0x8003; + } + + public static void SetEscapeParam(ref BTL_ACTION_PARAM p, byte pokeID) + { + p.escape_cmd = (byte)BtlAction.BTL_ACTION_ESCAPE; + p.escape_pokeID = pokeID; + } + + public static void SetCheer(ref BTL_ACTION_PARAM p) + { + p.raw = p.raw & unchecked((long)0xfffffffffffffe00) | 0x1f7; + } + + public static void SetSafariBall(ref BTL_ACTION_PARAM p, byte pokeID) + { + p.gen_cmd = (byte)BtlAction.BTL_ACTION_SAFARI_BALL; + p.gen_pokeID = pokeID; + } + + public static void SetSafariEsa(ref BTL_ACTION_PARAM p, byte pokeID) + { + p.gen_cmd = (byte)BtlAction.BTL_ACTION_SAFARI_ESA; + p.gen_pokeID = pokeID; + } + + public static void SetSafariDoro(ref BTL_ACTION_PARAM p, byte pokeID) + { + p.gen_cmd = (byte)BtlAction.BTL_ACTION_SAFARI_DORO; + p.gen_pokeID = pokeID; + } + + public static void SetSafariYousumi(ref BTL_ACTION_PARAM p, byte pokeID) + { + p.gen_cmd = (byte)BtlAction.BTL_ACTION_SAFARI_YOUSUMI; + p.gen_pokeID = pokeID; + } + + public static void SetNULL(ref BTL_ACTION_PARAM p) + { + p.raw = 0; + } + + public static void SetSkip(ref BTL_ACTION_PARAM p, byte pokeID) + { + p.gen_cmd = (byte)BtlAction.BTL_ACTION_SKIP; + p.gen_pokeID = pokeID; + } + + public static BtlAction GetAction(in BTL_ACTION_PARAM p) + { + return (BtlAction)(p.raw & 0xf); + } + + public static void SetRecPlayOver(ref BTL_ACTION_PARAM act) + { + act.raw = act.raw & 0x1f0 | (long)BtlAction.BTL_ACTION_RECPLAY_TIMEOVER; + } + + public static void SetRecPlayError(ref BTL_ACTION_PARAM act) + { + act.raw = act.raw & 0x1f0 | (long)BtlAction.BTL_ACTION_RECPLAY_ERROR; + } } } \ No newline at end of file diff --git a/Assets/Scripts/Dpr/Battle/Logic/WAZADATA.cs b/Assets/Scripts/Dpr/Battle/Logic/WAZADATA.cs index 606b0ed59..f52153c5b 100644 --- a/Assets/Scripts/Dpr/Battle/Logic/WAZADATA.cs +++ b/Assets/Scripts/Dpr/Battle/Logic/WAZADATA.cs @@ -5,60 +5,90 @@ namespace Dpr.Battle.Logic { public static class WAZADATA { - // TODO - public static WazaTarget GetWazaTarget(WazaNo id) { return WazaTarget.TARGET_OTHER_SELECT; } + public static WazaTarget GetWazaTarget(WazaNo id) + { + return WazaDataSystem.GetTarget(id); + } - // TODO - public static uint GetHPRecoverRatio(WazaNo id) { return 0; } + public static uint GetHPRecoverRatio(WazaNo id) + { + return WazaDataSystem.GetHPRecoverRatio(id); + } - // TODO - public static byte GetHPReactionRatio(WazaNo id) { return 0; } + public static uint GetHPReactionRatio(WazaNo id) + { + return WazaDataSystem.GetHPReactionRatio(id); + } - // TODO - public static byte GetDamageReactionRatio(WazaNo id) { return 0; } + public static uint GetDamageReactionRatio(WazaNo id) + { + return WazaDataSystem.GetDamageReactionRatio(id); + } - // TODO - public static uint GetDamageRecoverRatio(WazaNo id) { return 0; } + public static uint GetDamageRecoverRatio(WazaNo id) + { + return WazaDataSystem.GetDamageRecoverRatio(id); + } - // TODO - public static uint GetShrinkPer(WazaNo id) { return 0; } + public static uint GetShrinkPer(WazaNo id) + { + return WazaDataSystem.GetShrinkPer(id); + } - // TODO - public static WazaSick GetSick(WazaNo id) { return WazaSick.WAZASICK_NONE; } + public static WazaSick GetSick(WazaNo id) + { + return WazaDataSystem.GetSick(id); + } - // TODO - public static int GetSickPer(WazaNo id) { return 0; } + public static int GetSickPer(WazaNo id) + { + return WazaDataSystem.GetSickPer(id); + } - // TODO - public static byte GetType(WazaNo id) { return 0; } + public static byte GetType(WazaNo id) + { + return WazaDataSystem.GetType(id); + } - // TODO - public static WazaCategory GetCategory(WazaNo id) { return WazaCategory.SIMPLE_DAMAGE; } + public static WazaCategory GetCategory(WazaNo id) + { + return WazaDataSystem.GetCategory(id); + } - // TODO - public static WazaDamageType GetDamageType(WazaNo id) { return WazaDamageType.NONE; } + public static WazaDamageType GetDamageType(WazaNo id) + { + return WazaDataSystem.GetDamageType(id); + } - // TODO - public static SickContParam GetSickCont(WazaNo id) { return default; } + public static SickContParam GetSickCont(WazaNo id) + { + return WazaDataSystem.GetSickCont(id); + } - // TODO public static WazaRankEffect GetRankEffect(WazaNo id, uint idx, out int volume) { - volume = 0; - return WazaRankEffect.NONE; + return WazaDataSystem.GetRankEffect(id, idx, out volume); } - // TODO - public static byte GetRankEffectCount(WazaNo id) { return 0; } + public static byte GetRankEffectCount(WazaNo id) + { + return WazaDataSystem.GetRankEffectCount(id); + } - // TODO - public static int GetRankEffectPer(WazaNo id, uint idx) { return 0; } + public static int GetRankEffectPer(WazaNo id, uint idx) + { + return WazaDataSystem.GetRankEffectPer(id, idx); + } - // TODO - public static uint GetPower(WazaNo id) { return 0; } + public static uint GetPower(WazaNo id) + { + return WazaDataSystem.GetPower(id); + } - // TODO - public static ushort GetHitPer(WazaNo id) { return 0; } + public static ushort GetHitPer(WazaNo id) + { + return WazaDataSystem.GetHitPer(id); + } public static uint GetHitCountMax(WazaNo id) { @@ -70,37 +100,59 @@ public static uint GetHitCountMin(WazaNo id) return WazaDataSystem.GetHitCountMin(id); } - // TODO - public static int GetAISeqNo(WazaNo id) { return 0; } + public static int GetAISeqNo(WazaNo id) + { + return WazaDataSystem.GetAISeqNo(id); + } - // TODO - public static bool GetFlag(WazaNo id, WazaFlag flag) { return false; } + public static bool GetFlag(WazaNo id, WazaFlag flag) + { + return WazaDataSystem.GetFlag(id, flag); + } - // TODO - public static bool IsValid(WazaNo id) { return false; } + public static bool IsValid(WazaNo id) + { + return WazaDataSystem.IsValid(id); + } - // TODO - public static bool IsAlwaysHit(WazaNo id) { return false; } + public static bool IsAlwaysHit(WazaNo id) + { + return WazaDataSystem.IsAlwaysHit(id); + } - // TODO - public static bool IsMustCritical(WazaNo id) { return false; } + public static bool IsMustCritical(WazaNo id) + { + return WazaDataSystem.IsMustCritical(id); + } - // TODO - public static byte GetCriticalRank(WazaNo id) { return 0; } + public static byte GetCriticalRank(WazaNo id) + { + return WazaDataSystem.GetCriticalRank(id); + } - // TODO - public static uint GetMaxPP(WazaNo id, uint ppup_cnt) { return 0; } + public static uint GetMaxPP(WazaNo id, uint ppup_cnt) + { + return WazaDataSystem.GetMaxPP(id, ppup_cnt); + } - // TODO - public static BtlWeather GetWeather(WazaNo id) { return BtlWeather.BTL_WEATHER_NONE; } + public static BtlWeather GetWeather(WazaNo id) + { + return (BtlWeather)WazaDataSystem.GetWeather(id); + } - // TODO - public static int GetPriority(WazaNo id) { return 0; } + public static int GetPriority(WazaNo id) + { + return WazaDataSystem.GetPriority(id); + } - // TODO - public static bool IsDamage(WazaNo id) { return false; } + public static bool IsDamage(WazaNo id) + { + return WazaDataSystem.IsDamage(id); + } - // TODO - public static byte GetGPower(WazaNo wazano) { return 0; } + public static byte GetGPower(WazaNo wazano) + { + return WazaDataSystem.GetGPower(wazano); + } } } \ No newline at end of file diff --git a/Assets/Scripts/Dpr/Battle/Logic/calc.cs b/Assets/Scripts/Dpr/Battle/Logic/calc.cs index ee1acd65b..6c84cab68 100644 --- a/Assets/Scripts/Dpr/Battle/Logic/calc.cs +++ b/Assets/Scripts/Dpr/Battle/Logic/calc.cs @@ -35,136 +35,557 @@ public static class calc private static readonly byte[] CheckCriticalTable = new byte[4] { 1, 2, 8, 16 }; private static readonly byte[] PENALTY_COEF = new byte[9] { 2, 4, 6, 9, 12, 16, 20, 25, 30 }; - // TODO - public static void BITFLG_Construction(byte[] flags) { } + public static void BITFLG_Construction(byte[] flags) + { + for (int i = 0; i < flags.Length; i++) + { + flags[i] = 0; + } + } - // TODO - public static void BITFLG_Set(byte[] flags, uint index) { } + public static void BITFLG_Set(byte[] flags, uint index) + { + byte byteIdx = (byte)(index >> 3); + if (byteIdx < flags.Length) + { + flags[byteIdx] |= (byte)(1 << (int)(index & 7)); + } + } - // TODO - public static bool BITFLG_Check(byte[] flags, uint index) { return false; } + public static bool BITFLG_Check(byte[] flags, uint index) + { + byte byteIdx = (byte)(index >> 3); + if (byteIdx >= flags.Length) + { + return false; + } + return (flags[byteIdx] & (1 << (int)(index & 7))) != 0; + } - // TODO - public static void BITFLG_Off(byte[] flags, uint index) { } + public static void BITFLG_Off(byte[] flags, uint index) + { + byte byteIdx = (byte)(index >> 3); + if (byteIdx < flags.Length) + { + flags[byteIdx] &= (byte)~(1 << (int)(index & 7)); + } + } - // TODO - public static uint ABS(int value) { return 0; } + public static uint ABS(int value) + { + if (value < 0) + return (uint)(-value); + return (uint)value; + } - // TODO - public static void InitSys(Random randSys, bool bSakasaBtl) { } + public static void InitSys(Random randSys, bool bSakasaBtl) + { + g_RandSys = randSys; + g_PublicRand = new Random(); + g_PublicRand.Initialize(); + g_WazaStoreWork = new WazaNo[827]; + g_SakasaBtlFlag = bSakasaBtl; + } - // TODO - public static void ResetSys(ulong randSeed) { } + public static void ResetSys(ulong randSeed) + { + g_RandSys.Initialize(randSeed); + } - // TODO - public static void QuitSys() { } + public static void QuitSys() + { + g_WazaStoreWork = null; + g_RandSys = null; + g_PublicRand = null; + } - // TODO - public static Random GetRandGenerator() { return null; } + public static Random GetRandGenerator() + { + return g_RandSys; + } - // TODO - public static TypeAffinity.AffinityID TypeAff(PokeType wazaType, PokeType pokeType) { return TypeAffinity.AffinityID.TYPEAFF_0; } + public static TypeAffinity.AffinityID TypeAff(PokeType wazaType, PokeType pokeType) + { + return TypeAffinity.CalcAffinity(wazaType, pokeType, g_SakasaBtlFlag); + } - // TODO - public static TypeAffinity.AffinityID TypeAffMul(TypeAffinity.AffinityID aff1, TypeAffinity.AffinityID aff2) { return TypeAffinity.AffinityID.TYPEAFF_0; } + public static TypeAffinity.AffinityID TypeAffMul(TypeAffinity.AffinityID aff1, TypeAffinity.AffinityID aff2) + { + return TypeAffinity.MulAffinity(aff1, aff2); + } - // TODO - public static TypeAffinity.AffinityID TypeAffPair(byte wazaType, PokeTypePair pokeType) { return TypeAffinity.AffinityID.TYPEAFF_0; } + public static TypeAffinity.AffinityID TypeAffPair(byte wazaType, PokeTypePair pokeType) + { + PokeTypePair.Split(pokeType, out byte type1, out byte type2, out byte typeEx); + TypeAffinity.AffinityID aff = TypeAff((PokeType)wazaType, (PokeType)type1); + if (type2 != (byte)PokeType.NULL && type2 != type1) + { + TypeAffinity.AffinityID aff2 = TypeAff((PokeType)wazaType, (PokeType)type2); + aff = TypeAffMul(aff, aff2); + } + if (typeEx != (byte)PokeType.NULL && typeEx != type1 && typeEx != type2) + { + TypeAffinity.AffinityID aff3 = TypeAff((PokeType)wazaType, (PokeType)typeEx); + aff = TypeAffMul(aff, aff3); + } + return aff; + } - // TODO - public static byte GetResistTypes(PokeType type, byte[] dst) { return 0; } + public static byte GetResistTypes(PokeType type, byte[] dst) + { + byte count = 0; + for (int i = 0; i < 0x12; i++) + { + TypeAffinity.AffinityID aff = TypeAff(type, (PokeType)i); + if (aff == TypeAffinity.AffinityID.TYPEAFF_1_2 || aff == TypeAffinity.AffinityID.TYPEAFF_0) + { + dst[count] = (byte)i; + count++; + } + } + return count; + } - // TODO - public static uint DamageBase(uint wazaPower, uint atkPower, uint atkLevel, uint defGuard) { return 0; } + public static uint DamageBase(uint wazaPower, uint atkPower, uint atkLevel, uint defGuard) + { + uint result = 0; + if (defGuard != 0) + { + result = (atkPower * wazaPower * (atkLevel * 2 / 5 + 2)) / defGuard; + } + return result / 50 + 2; + } - // TODO - public static uint AffDamage(uint rawDamage, TypeAffinity.AffinityID aff) { return 0; } + public static uint AffDamage(uint rawDamage, TypeAffinity.AffinityID aff) + { + int val = (int)rawDamage; + switch (aff) + { + case TypeAffinity.AffinityID.TYPEAFF_0: return 0; + case TypeAffinity.AffinityID.TYPEAFF_1_64: return rawDamage >> 6; + case TypeAffinity.AffinityID.TYPEAFF_1_32: return rawDamage >> 5; + case TypeAffinity.AffinityID.TYPEAFF_1_16: return rawDamage >> 4; + case TypeAffinity.AffinityID.TYPEAFF_1_8: return rawDamage >> 3; + case TypeAffinity.AffinityID.TYPEAFF_1_4: return rawDamage >> 2; + case TypeAffinity.AffinityID.TYPEAFF_1_2: return rawDamage >> 1; + case TypeAffinity.AffinityID.TYPEAFF_2: return (uint)(val << 1); + case TypeAffinity.AffinityID.TYPEAFF_4: return (uint)(val << 2); + case TypeAffinity.AffinityID.TYPEAFF_8: return (uint)(val << 3); + case TypeAffinity.AffinityID.TYPEAFF_16: return (uint)(val << 4); + case TypeAffinity.AffinityID.TYPEAFF_32: return (uint)(val << 5); + case TypeAffinity.AffinityID.TYPEAFF_64: return (uint)(val << 6); + default: return rawDamage; + } + } - // TODO - public static uint GetPublicRand(uint range) { return 0; } + public static uint GetPublicRand(uint range) + { + if (g_PublicRand != null) + { + return (uint)g_PublicRand.GetValue(range); + } + return (uint)UnityEngine.Random.Range(0, (float)range); + } - // TODO - public static uint GetRand(uint range) { return 0; } + public static uint GetRand(uint range) + { + return (uint)g_RandSys.GetValue(range); + } - // TODO - public static uint RandRange(uint min, uint max) { return 0; } + public static uint RandRange(uint min, uint max) + { + uint lo = min; + uint hi = max; + if (min > max) + { + lo = max; + hi = min; + } + return lo + GetRand(hi - lo + 1); + } - // TODO - public static uint MulRatio(uint value, int ratio) { return 0; } + public static uint MulRatio(uint value, int ratio) + { + int product = ratio * (int)value; + uint result = (uint)product >> 12; + if ((uint)(product & 0xfff) > 0x800) + { + result++; + } + return result; + } - // TODO - public static uint MulRatio_OverZero(uint value, int ratio) { return 0; } + public static uint MulRatio_OverZero(uint value, int ratio) + { + uint result = MulRatio(value, ratio); + if (result == 0) + { + result = 1; + } + return result; + } - // TODO - public static uint MulRatioInt(uint value, uint ratio) { return 0; } + public static uint MulRatioInt(uint value, uint ratio) + { + uint product = value * ratio; + uint result = product / 100; + if (product % 100 > 49) + { + result = product / 100 + 1; + } + return result; + } - // TODO public static void MakeDefaultWazaSickCont(WazaSick sick, BTL_POKEPARAM attacker, out BTL_SICKCONT cont) { - cont = default(BTL_SICKCONT); + int sickID = (int)sick; + if (sickID < 6) + { + byte pokeID = attacker.GetID(); + cont = MakeDefaultPokeSickCont((Sick)sickID, pokeID); + } + else if (sickID == 6) + { + uint turns = RandRange(2, 4); + byte pokeID = attacker.GetID(); + cont = SICKCONT.MakeTurn(pokeID, (byte)turns); + } + else if (sickID == 7) + { + byte pokeID = attacker.GetID(); + byte pokeID2 = attacker.GetID(); + cont = SICKCONT.MakePoke(pokeID, pokeID2); + } + else + { + byte pokeID = attacker.GetID(); + cont = SICKCONT.MakePermanent(pokeID); + } } - // TODO - public static BTL_SICKCONT MakeWazaSickCont_Poke(byte pokeID, byte causePokeID) { return default(BTL_SICKCONT); } + public static BTL_SICKCONT MakeWazaSickCont_Poke(byte pokeID, byte causePokeID) + { + BTL_SICKCONT cont = default; + cont.type = 3; + cont.causePokeID = causePokeID; + cont.poke_ID = pokeID; + return cont; + } - // TODO - public static BTL_SICKCONT MakeDefaultPokeSickCont(Sick sick, byte causePokeID, bool isCantUseRand = false) { return default(BTL_SICKCONT); } + public static BTL_SICKCONT MakeDefaultPokeSickCont(Sick sick, byte causePokeID, bool isCantUseRand = false) + { + BTL_SICKCONT cont = default; + int sickID = (int)sick; + if (sickID == 2) + { + cont.type = 2; + cont.causePokeID = causePokeID; + byte turns; + if (isCantUseRand) + { + turns = 3; + } + else + { + turns = (byte)RandRange(2, 4); + } + cont.turn_count = turns; + return cont; + } + else if (sickID >= 3 && sickID <= 5) + { + cont.type = 1; + cont.causePokeID = causePokeID; + return cont; + } + else if (sickID == 1) + { + cont.type = 1; + cont.causePokeID = causePokeID; + return cont; + } + else + { + cont.type = 0; + cont.causePokeID = causePokeID; + return cont; + } + } - // TODO - public static ushort StatusRank(ushort defaultVal, byte rank) { return 0; } + public static ushort StatusRank(ushort defaultVal, byte rank) + { + if (rank < StatusRankTable.Length) + { + uint num = StatusRankTable[rank].num; + uint denom = StatusRankTable[rank].denom; + if (denom != 0) + { + return (ushort)((uint)(defaultVal * num) / denom); + } + } + return defaultVal; + } - // TODO - public static uint QuotMaxHP_Zero(BTL_POKEPARAM bpp, uint denom, bool useBeforeGParam = false) { return 0; } + public static uint QuotMaxHP_Zero(BTL_POKEPARAM bpp, uint denom, bool useBeforeGParam = false) + { + if (denom == 0) denom = 1; + BTL_POKEPARAM.ValueID vid = BTL_POKEPARAM.ValueID.BPP_MAX_HP; + if (useBeforeGParam && bpp.IsGMode()) + { + vid = BTL_POKEPARAM.ValueID.BPP_MAX_HP_BEFORE_G; + } + uint maxHP = (uint)bpp.GetValue(vid); + uint result = 0; + if (denom != 0) + { + result = maxHP / denom; + } + return result; + } - // TODO - public static uint QuotMaxHP(BTL_POKEPARAM bpp, uint denom, bool useBeforeGParam = false) { return 0; } + public static uint QuotMaxHP(BTL_POKEPARAM bpp, uint denom, bool useBeforeGParam = false) + { + if (denom == 0) denom = 1; + BTL_POKEPARAM.ValueID vid = BTL_POKEPARAM.ValueID.BPP_MAX_HP; + if (useBeforeGParam && bpp.IsGMode()) + { + vid = BTL_POKEPARAM.ValueID.BPP_MAX_HP_BEFORE_G; + } + uint maxHP = (uint)bpp.GetValue(vid); + uint result = 0; + if (denom != 0) + { + result = maxHP / denom; + } + if (maxHP < denom) + { + result = 1; + } + return result; + } - // TODO - public static byte HitPer(byte defPer, byte rank) { return 0; } + public static byte HitPer(byte defPer, byte rank) + { + if (rank < HitPerTable.Length) + { + uint num = HitPerTable[rank].num; + uint denom = HitPerTable[rank].denom; + uint result = 0; + if (denom != 0) + { + result = (num * (uint)(defPer & 0xff)) / denom; + } + if (result > 99) + { + result = 100; + } + return (byte)result; + } + return defPer; + } - // TODO - public static bool CheckCritical(byte rank, int ratio) { return false; } + public static bool CheckCritical(byte rank, int ratio) + { + if (rank < CheckCriticalTable.Length) + { + uint critVal = 0; + if (ratio != 0) + { + critVal = (uint)CheckCriticalTable[rank] / (uint)ratio; + } + uint critByte = critVal & 0xff; + if (critByte == 0) + { + critByte = 1; + } + return GetRand(critByte) == 0; + } + return false; + } - // TODO - public static int ITEM_GetParam(ushort item, Pml.Item.ItemData.PrmID paramID) { return 0; } + public static int ITEM_GetParam(ushort item, Pml.Item.ItemData.PrmID paramID) + { + return Pml.Item.ItemManager.Instance.GetParam(item, paramID); + } - // TODO - public static bool ITEM_IsBall(ushort itemID) { return false; } + public static bool ITEM_IsBall(ushort itemID) + { + return ITEM_GetParam(itemID, Pml.Item.ItemData.PrmID.ITEM_TYPE) == 5; + } - // TODO - public static bool ITEM_IsReriveItem(ushort itemID) { return false; } + public static bool ITEM_IsReriveItem(ushort itemID) + { + return ITEM_GetParam(itemID, Pml.Item.ItemData.PrmID.DEATH_RCV) != 0; + } - // TODO - public static bool ITEM_IsMail(ushort item) { return false; } + public static bool ITEM_IsMail(ushort item) + { + return ITEM_GetParam(item, Pml.Item.ItemData.PrmID.ITEM_TYPE) == 6; + } - // TODO - public static uint PERSONAL_GetParam(int mons_no, int form_no, ParamID paramID) { return 0; } + public static uint PERSONAL_GetParam(int mons_no, int form_no, ParamID paramID) + { + var data = Pml.Personal.PersonalSystem.GetPersonalData((Pml.MonsNo)mons_no, (ushort)form_no); + return Pml.Personal.PersonalTableExtensions.GetParam(data, paramID); + } - // TODO - public static uint PERSONAL_GetMinExp(int monsno, int formno, byte level) { return 0; } + public static uint PERSONAL_GetMinExp(int monsno, int formno, byte level) + { + Pml.Personal.PersonalSystem.LoadGrowTable((Pml.MonsNo)monsno, (ushort)formno); + return Pml.Personal.PersonalSystem.GetMinExp(level); + } - // TODO - public static bool PERSONAL_IsEvoCancelPokemon(int mons_no, ushort formno, byte level) { return false; } + public static bool PERSONAL_IsEvoCancelPokemon(int mons_no, ushort formno, byte level) + { + Pml.Personal.PersonalSystem.LoadEvolutionTable((Pml.MonsNo)mons_no, formno); + byte routeNum = Pml.Personal.PersonalSystem.GetEvolutionRouteNum(); + for (uint i = 0; i < routeNum; i++) + { + var cond = Pml.Personal.PersonalSystem.GetEvolutionCondition((byte)i); + if ((int)cond == 4) + { + byte evoLevel = Pml.Personal.PersonalSystem.GetEvolveEnableLevel((byte)i); + if (evoLevel <= level) + { + return true; + } + } + } + return false; + } - // TODO - public static bool IsBasicSickID(WazaSick sickID) { return false; } + public static bool IsBasicSickID(WazaSick sickID) + { + return (int)sickID < 6; + } - // TODO - public static ushort RecvWeatherDamage(BTL_POKEPARAM bpp, BtlWeather weather) { return 0; } + public static ushort RecvWeatherDamage(BTL_POKEPARAM bpp, BtlWeather weather) + { + if (weather == BtlWeather.BTL_WEATHER_SNOW) + { + if (bpp.IsMatchType((byte)PokeType.KOORI)) + { + return 0; + } + } + else if (weather == BtlWeather.BTL_WEATHER_SAND) + { + if (bpp.IsMatchType((byte)PokeType.JIMEN)) + { + return 0; + } + if (bpp.IsMatchType((byte)PokeType.HAGANE)) + { + return 0; + } + if (bpp.IsMatchType((byte)PokeType.IWA)) + { + return 0; + } + } + else + { + return 0; + } + uint maxHP = (uint)bpp.GetValue(BTL_POKEPARAM.ValueID.BPP_MAX_HP_BEFORE_G); + uint result = maxHP; + if ((int)maxHP >= 0) + { + result = maxHP; + } + else + { + result = maxHP + 15; + } + result = result >> 4; + if ((result & 0xffff) == 0) + { + result = 1; + } + return (ushort)result; + } - // TODO - public static int GetWeatherDmgRatio(BtlWeather weather, byte wazaType) { return 0; } + public static int GetWeatherDmgRatio(BtlWeather weather, byte wazaType) + { + int result = 0x1000; + switch (weather) + { + case BtlWeather.BTL_WEATHER_SHINE: + case BtlWeather.BTL_WEATHER_DAY: + { + int valB = (wazaType == 10) ? 0x800 : 0x1000; + result = 0x1800; + if (wazaType != 9) + { + result = valB; + } + break; + } + case BtlWeather.BTL_WEATHER_RAIN: + case BtlWeather.BTL_WEATHER_STORM: + { + int valB = (wazaType == 10) ? 0x1800 : 0x1000; + result = 0x800; + if (wazaType != 9) + { + result = valB; + } + break; + } + } + return result; + } - // TODO - public static bool IsShineWeather(BtlWeather weather) { return false; } + public static bool IsShineWeather(BtlWeather weather) + { + if (weather == BtlWeather.BTL_WEATHER_SHINE) + return true; + return weather == BtlWeather.BTL_WEATHER_DAY; + } - // TODO - public static bool IsRainWeather(BtlWeather weather) { return false; } + public static bool IsRainWeather(BtlWeather weather) + { + if (weather == BtlWeather.BTL_WEATHER_RAIN) + return true; + return weather == BtlWeather.BTL_WEATHER_STORM; + } - // TODO public static void WazaSickContToBppSickCont(SickContParam wazaSickCont, BTL_POKEPARAM attacker, out BTL_SICKCONT sickCont) { - sickCont = default(BTL_SICKCONT); + switch (wazaSickCont.type) + { + case 1: + { + byte pokeID = attacker.GetID(); + sickCont = SICKCONT.MakePermanentIncParam(pokeID, (byte)wazaSickCont.turnMax, wazaSickCont.turnMin); + return; + } + case 2: + { + uint turns = RandRange(wazaSickCont.turnMin, wazaSickCont.turnMax); + byte pokeID = attacker.GetID(); + sickCont = SICKCONT.MakeTurn(pokeID, (byte)turns); + return; + } + case 3: + { + byte pokeID = attacker.GetID(); + byte pokeID2 = attacker.GetID(); + sickCont = SICKCONT.MakePoke(pokeID, pokeID2); + return; + } + case 4: + { + byte pokeID = attacker.GetID(); + byte pokeID2 = attacker.GetID(); + uint turns = RandRange(wazaSickCont.turnMin, wazaSickCont.turnMax); + sickCont = SICKCONT.MakePokeTurn(pokeID, pokeID2, (byte)turns); + return; + } + default: + sickCont = SICKCONT.MakeNull(); + return; + } } public static byte HitCountStd(byte numHitMax) @@ -186,65 +607,340 @@ public static byte HitCountStd(byte numHitMax) return numHitMax; } - // TODO - public static WazaSick CheckMentalSick(BTL_POKEPARAM bpp) { return WazaSick.WAZASICK_NONE; } + public static WazaSick CheckMentalSick(BTL_POKEPARAM bpp) + { + int i = 0; + while (true) + { + WazaSick sickID = tables.GetMentalSickID((uint)i); + if (sickID == WazaSick.WAZASICK_NONE) + break; + i++; + if (bpp.CheckSick(sickID)) + { + return sickID; + } + } + return WazaSick.WAZASICK_NONE; + } - // TODO - public static TypeAffinity.AboutAffinityID TypeAffAbout(TypeAffinity.AffinityID aff) { return TypeAffinity.AboutAffinityID.NONE; } + public static TypeAffinity.AboutAffinityID TypeAffAbout(TypeAffinity.AffinityID aff) + { + return TypeAffinity.ConvAboutAffinity(aff); + } - // TODO - public static bool IsOccurPer(uint per) { return false; } + public static bool IsOccurPer(uint per) + { + uint rand = GetRand(100); + return rand < per; + } - // TODO - public static int Roundup(int value, int min) { return 0; } + public static int Roundup(int value, int min) + { + if (value < min) + return min; + return value; + } - // TODO - public static int Rounddown(int val, int max) { return 0; } + public static int Rounddown(int val, int max) + { + if (val > max) + return max; + return val; + } - // TODO - public static int RoundValue(int val, int min, int max) { return 0; } + public static int RoundValue(int val, int min, int max) + { + int result = Roundup(val, min); + result = Rounddown(result, max); + return result; + } - // TODO - public static WazaTarget GetWazaTarget(WazaNo waza, BTL_POKEPARAM attacker) { return WazaTarget.TARGET_OTHER_SELECT; } + public static WazaTarget GetWazaTarget(WazaNo waza, BTL_POKEPARAM attacker) + { + if (waza == (WazaNo)0xae) // Noroi (Curse) + { + if (attacker != null) + { + return attacker.IsMatchType((byte)PokeType.GHOST) ? (WazaTarget)0 : (WazaTarget)7; + } + } + return (WazaTarget)WazaDataSystem.GetTarget(waza); + } - // TODO - public static WazaTarget GetNoroiTargetType(BTL_POKEPARAM attacker) { return WazaTarget.TARGET_OTHER_SELECT; } + public static WazaTarget GetNoroiTargetType(BTL_POKEPARAM attacker) + { + return attacker.IsMatchType((byte)PokeType.GHOST) ? (WazaTarget)0 : (WazaTarget)7; + } - // TODO - public static BtlPokePos DecideWazaTargetAuto(MainModule mainModule, POKECON pokeCon, BTL_POKEPARAM bpp, WazaNo waza, bool IsClient = false) { return BtlPokePos.POS_1ST_0; } + public static BtlPokePos DecideWazaTargetAuto(MainModule mainModule, POKECON pokeCon, BTL_POKEPARAM bpp, WazaNo waza, bool IsClient = false) + { + BtlRule rule = mainModule.GetRule(); + byte pokeID = bpp.GetID(); + BtlPokePos basePos = mainModule.PokeIDtoPokePos(pokeCon, pokeID); + uint wazaTarget = (uint)WazaDataSystem.GetTarget(waza); - // TODO - public static uint PokeIDx6_Pack32bit(byte[] pokeIDList) { return 0; } + if (waza == (WazaNo)0xae) // Noroi (Curse) + { + wazaTarget = (uint)(bpp.IsMatchType((byte)PokeType.GHOST) ? 0 : 7); + } - // TODO - public static void PokeIDx6_Unpack32bit(uint pack, byte[] pokeIDList) { } + if (rule == BtlRule.BTL_RULE_SINGLE) + { + if (wazaTarget > 9) + { + return BtlPokePos.POS_NULL; + } + uint mask = (uint)(1 << (int)(wazaTarget & 0x1f)); + if ((mask & 0x239) != 0) + { + return mainModule.GetOpponentPokePos(basePos, 0); + } + if ((mask & 0x82) != 0) + { + return basePos; + } + return BtlPokePos.POS_NULL; + } + else + { + ExPokePos exPos = new ExPokePos(); + byte[] pokeIDAry = new byte[5]; - // TODO - public static bool is_include(WazaNo[] tbl, uint tblElems, WazaNo wazaID) { return false; } + ExPokePos.ExPosType exPosType; + switch (wazaTarget) + { + case 0: // TARGET_OTHER_SELECT + case 3: // TARGET_ENEMY_SELECT + case 9: // TARGET_ENEMY_RANDOM + exPosType = ExPokePos.ExPosType.AREA_ENEMY; + break; + case 1: // TARGET_FRIEND_USER_SELECT + exPosType = ExPokePos.ExPosType.AREA_MYTEAM; + break; + case 2: // TARGET_FRIEND_SELECT + exPosType = ExPokePos.ExPosType.AREA_FRIENDS; + break; + case 7: // TARGET_USER + return basePos; + default: + return BtlPokePos.POS_NULL; + } + + ExPokePos targetExPos = new ExPokePos(exPosType, basePos); + BtlMultiMode multiMode = mainModule.GetMultiMode(); + byte count = targetExPos.ExpandExistPokeID(rule, multiMode, pokeCon, pokeIDAry); + + if (count != 0) + { + byte randIdx; + if (!IsClient) + { + randIdx = (byte)(GetRand(count) & 0xff); + } + else + { + randIdx = (byte)(GetPublicRand(count) & 0xff); + } + if (randIdx < pokeIDAry.Length) + { + return mainModule.PokeIDtoPokePos(pokeCon, pokeIDAry[randIdx]); + } + } - // TODO - public static WazaNo RandWaza(WazaNo[] omitWazaTbl, ushort tblElems) { return WazaNo.NULL; } + // Fallback: try expanding by pos + BtlPokePos[] posAry = new BtlPokePos[5]; + byte posCount = targetExPos.ExpandPos(rule, multiMode, posAry); - // TODO - public static BtlPokePos DecideWazaTargetAutoForClient(MainModule mainModule, POKECON pokeCon, BTL_POKEPARAM bpp, WazaNo waza, ref ulong pRandContextSaveWork) { return BtlPokePos.POS_1ST_0; } + if (posCount != 0) + { + byte randIdx; + if (!IsClient) + { + randIdx = (byte)(GetRand(posCount) & 0xff); + } + else + { + randIdx = (byte)(GetPublicRand(posCount) & 0xff); + } + if (randIdx < posAry.Length) + { + return posAry[randIdx]; + } + } - // TODO - public static bool RULE_IsNeedSelectTarget(BtlRule rule) { return false; } + return BtlPokePos.POS_NULL; + } + } - // TODO - public static byte RULE_HandPokeIndex(BtlRule rule, byte numCoverPos) { return 0; } + public static uint PokeIDx6_Pack32bit(byte[] pokeIDList) + { + return (uint)( + (pokeIDList[0] & 0x1f) | + ((pokeIDList[1] & 0x1f) << 5) | + ((pokeIDList[2] & 0x1f) << 10) | + ((pokeIDList[3] & 0x1f) << 15) | + ((pokeIDList[4] & 0x1f) << 20) | + ((pokeIDList[5] & 0x1f) << 25) + ); + } - // TODO - public static uint calcWinMoney_Sub(in BSP_TRAINER_DATA trData, in PokeParty party) { return 0; } + public static void PokeIDx6_Unpack32bit(uint pack, byte[] pokeIDList) + { + pokeIDList[0] = (byte)(pack & 0x1f); + pokeIDList[1] = (byte)((pack >> 5) & 0x1f); + pokeIDList[2] = (byte)((pack >> 10) & 0x1f); + pokeIDList[3] = (byte)((pack >> 15) & 0x1f); + pokeIDList[4] = (byte)((pack >> 20) & 0x1f); + pokeIDList[5] = (byte)((pack >> 25) & 0x1f); + } - // TODO - public static uint CalcWinMoney(BATTLE_SETUP_PARAM sp) { return 0; } + public static bool is_include(WazaNo[] tbl, uint tblElems, WazaNo wazaID) + { + for (uint i = 0; i < tblElems; i++) + { + if (tbl[i] == wazaID) + { + return true; + } + } + return false; + } - // TODO - public static uint CalcLoseMoney(BATTLE_SETUP_PARAM sp, POKECON pokeCon) { return 0; } + public static WazaNo RandWaza(WazaNo[] omitWazaTbl, ushort tblElems) + { + ushort storeCount = 0; - // TODO - private static uint CalcPenaltyMoney(uint level_max) { return 0; } + if (tblElems != 0) + { + for (ushort wazaNo = 1; wazaNo <= (ushort)WazaNo.MAX - 1; wazaNo++) + { + bool found = false; + for (ushort j = 0; j < tblElems; j++) + { + if ((uint)omitWazaTbl[j] == wazaNo) + { + found = true; + break; + } + } + if (!found) + { + g_WazaStoreWork[storeCount] = (WazaNo)wazaNo; + storeCount++; + } + } + } + else + { + for (ushort wazaNo = 1; wazaNo <= (ushort)WazaNo.MAX - 1; wazaNo++) + { + g_WazaStoreWork[storeCount] = (WazaNo)wazaNo; + storeCount++; + } + } + + if (storeCount == 0) + { + return WazaNo.NULL; + } + + ushort randIdx = (ushort)(GetRand(storeCount) & 0xffff); + return g_WazaStoreWork[randIdx]; + } + + public static BtlPokePos DecideWazaTargetAutoForClient(MainModule mainModule, POKECON pokeCon, BTL_POKEPARAM bpp, WazaNo waza, ref ulong pRandContextSaveWork) + { + return DecideWazaTargetAuto(mainModule, pokeCon, bpp, waza, true); + } + + public static bool RULE_IsNeedSelectTarget(BtlRule rule) + { + return rule != 0; + } + + public static byte RULE_HandPokeIndex(BtlRule rule, byte numCoverPos) + { + return numCoverPos; + } + + public static uint calcWinMoney_Sub(in BSP_TRAINER_DATA trData, in PokeParty party) + { + if (party == null) + { + return 0; + } + if (trData == null || party.GetMemberCount() == 0) + { + return 0; + } + Pml.PokePara.PokemonParam lastMember = party.GetMemberPointerConst(party.GetMemberCount() - 1); + byte gold = trData.GetGoldParam(); + uint level = lastMember.GetLevel(); + return (uint)(gold * level * 4); + } + + public static uint CalcWinMoney(BATTLE_SETUP_PARAM sp) + { + if (sp.competitor != BtlCompetitor.BTL_COMPETITOR_TRAINER) + { + return 0; + } + + uint money1 = 0; + if (sp.tr_data[1] != null && sp.party[1] != null && sp.party[1].GetMemberCount() != 0) + { + Pml.PokePara.PokemonParam lastMember = sp.party[1].GetMemberPointerConst(sp.party[1].GetMemberCount() - 1); + byte gold = sp.tr_data[1].GetGoldParam(); + uint level = lastMember.GetLevel(); + money1 = (uint)(gold * level * 4); + } + + uint money2 = 0; + if (sp.tr_data.Length > 3 && sp.tr_data[3] != null && sp.party.Length > 3 && sp.party[3] != null) + { + if (sp.party[3].GetMemberCount() != 0 && sp.tr_data[3] != null) + { + Pml.PokePara.PokemonParam lastMember = sp.party[3].GetMemberPointerConst(sp.party[3].GetMemberCount() - 1); + byte gold = sp.tr_data[3].GetGoldParam(); + uint level = lastMember.GetLevel(); + money2 = (uint)(gold * level * 4); + } + } + + return money1 + money2; + } + + public static uint CalcLoseMoney(BATTLE_SETUP_PARAM sp, POKECON pokeCon) + { + BTL_PARTY btlParty = pokeCon.GetPartyDataConst(0); + byte memberCount = (byte)btlParty.GetMemberCount(); + + uint maxLevel = 0; + for (uint i = 0; i < memberCount; i++) + { + BTL_POKEPARAM member = btlParty.GetMemberDataConst((byte)i); + uint level = (uint)member.GetValue(BTL_POKEPARAM.ValueID.BPP_LEVEL); + if (level > maxLevel) + { + maxLevel = level; + } + } + + return CalcPenaltyMoney(maxLevel); + } + + private static uint CalcPenaltyMoney(uint level_max) + { + byte badge = PlayerWork.badge; + uint penalty = level_max * PENALTY_COEF[badge] * 4; + uint money = (uint)PlayerWork.GetMoney(); + if (money <= penalty) + { + return money; + } + return penalty; + } public class ESCAPEINFO { diff --git a/Assets/Scripts/Pml/Item/ItemData.cs b/Assets/Scripts/Pml/Item/ItemData.cs index 336a2deaf..2d4715706 100644 --- a/Assets/Scripts/Pml/Item/ItemData.cs +++ b/Assets/Scripts/Pml/Item/ItemData.cs @@ -37,86 +37,161 @@ public static int GetParam(ushort itemno, PrmID prmID) return ItemManager.Instance.GetParam(itemno, prmID, true); } - // TODO - public static uint GetHealingItemType(ushort itemno) { return 0; } + public static uint GetHealingItemType(ushort itemno) + { + var item = ItemManager.Instance.Get(itemno); + return item.GetHealingItemType(); + } - // TODO - public static bool IsNeedSelectSkill(ushort itemno) { return false; } + public static bool IsNeedSelectSkill(ushort itemno) + { + var item = ItemManager.Instance.Get(itemno); + return item.IsNeedSelectSkill(); + } - // TODO - public static bool IsDeathRecoverAllItem(ushort itemno) { return false; } + public static bool IsDeathRecoverAllItem(ushort itemno) + { + var item = ItemManager.Instance.Get(itemno); + return item.IsDeathRecoverAllItem(); + } - // TODO - public static bool IsSale(ushort itemno) { return false; } + public static bool IsSale(ushort itemno) + { + var item = ItemManager.Instance.Get(itemno); + return item.IsSale(); + } - // TODO - public static bool IsEventItem(ushort itemno) { return false; } + public static bool IsEventItem(ushort itemno) + { + var item = ItemManager.Instance.Get(itemno); + return item.IsEventItem(); + } - // TODO - public static int GetGroupId(ushort itemno) { return 0; } + public static int GetGroupId(ushort itemno) + { + var item = ItemManager.Instance.Get(itemno); + return item.GetGroupId(); + } - // TODO - public static BallId GetBallID(ushort itemno) { return BallId.NULL; } + public static BallId GetBallID(ushort itemno) + { + return ItemManager.Instance.ItemID2BallID(itemno); + } - // TODO - public static ushort BallId2ItemId(BallId ballId) { return 0; } + public static ushort BallId2ItemId(BallId ballId) + { + return ItemManager.Instance.BallID2ItemID(ballId); + } - // TODO - public static bool IsWazaMachine(ushort itemno) { return false; } + public static bool IsWazaMachine(ushort itemno) + { + var item = ItemManager.Instance.Get(itemno); + return item.IsWazaMachine(); + } - // TODO - public static WazaNo GetWazaNo(ushort itemno) { return WazaNo.NULL; } + public static WazaNo GetWazaNo(ushort itemno) + { + return ItemManager.Instance.GetWazaNo(itemno); + } - // TODO - public static uint GetWazaMashineNo(ushort item) { return 0; } + public static uint GetWazaMashineNo(ushort item) + { + var sheetItem = ItemManager.Instance.Get(item); + return sheetItem.GetWazaMashineNo(); + } - // TODO - public static uint GetWazaMashineMax() { return 0; } + public static uint GetWazaMashineMax() + { + return ItemManager.Instance.GetWazaMachineItemNum(); + } - // TODO - public static WazaNo GetWazaMashineWaza(byte machine_no) { return WazaNo.NULL; } + public static WazaNo GetWazaMashineWaza(byte machine_no) + { + return ItemManager.Instance.WazaMachineIDToWazaID(machine_no); + } - // TODO - public static ItemNo GetWazaMashineItemNo(byte machine_no) { return ItemNo.DUMMY_DATA; } + public static ItemNo GetWazaMashineItemNo(byte machine_no) + { + return ItemManager.Instance.WazaMachineIDToItemNo(machine_no); + } - // TODO - public static bool IsWazaRecord(ushort itemno) { return false; } + public static bool IsWazaRecord(ushort itemno) + { + var item = ItemManager.Instance.Get(itemno); + return item.IsWazaRecord(); + } - // TODO - public static bool IsNuts(ushort itemno) { return false; } + public static bool IsNuts(ushort itemno) + { + var item = ItemManager.Instance.Get(itemno); + return item.IsNuts(); + } - // TODO - public static byte GetNutsNo(ushort itemno) { return 0; } + public static byte GetNutsNo(ushort itemno) + { + var item = ItemManager.Instance.Get(itemno); + return item.GetNutsNo(); + } - // TODO - public static ushort NutsIDToItemNo(byte nutsid) { return 0; } + public static ushort NutsIDToItemNo(byte nutsid) + { + ushort itemNo; + if (ItemManager.Instance.GroupIdToItemNo((byte)ItemGroup.NUTS, nutsid, out itemNo)) + return itemNo; + return 0; + } - // TODO - public static bool IsGroupOf(ushort itemno, byte itemgroup) { return false; } + public static bool IsGroupOf(ushort itemno, byte itemgroup) + { + return ItemManager.Instance.IsGroupOf(itemno, itemgroup); + } - // TODO - public static bool IsMegaStone(ushort itemno) { return false; } + public static bool IsMegaStone(ushort itemno) + { + var item = ItemManager.Instance.Get(itemno); + return item.IsMegaStone(); + } - // TODO - public static bool IsJewel(ushort itemno) { return false; } + public static bool IsJewel(ushort itemno) + { + var item = ItemManager.Instance.Get(itemno); + return item.IsJewel(); + } - // TODO - public static bool IsPiece(ushort itemno) { return false; } + public static bool IsPiece(ushort itemno) + { + var item = ItemManager.Instance.Get(itemno); + return item.IsPiece(); + } - // TODO - public static bool IsBeads(ushort itemno) { return false; } + public static bool IsBeads(ushort itemno) + { + var item = ItemManager.Instance.Get(itemno); + return item.IsBeads(); + } - // TODO - public static bool IsHeart(ushort itemno) { return false; } + public static bool IsHeart(ushort itemno) + { + var item = ItemManager.Instance.Get(itemno); + return item.IsHeart(); + } - // TODO - public static bool CanPokeHave(ushort itemno) { return false; } + public static bool CanPokeHave(ushort itemno) + { + var item = ItemManager.Instance.Get(itemno); + return item.CanPokeHave(); + } - // TODO - public static bool IsValid(ushort item) { return false; } + public static bool IsValid(ushort item) + { + return ItemManager.Instance.GetParam(item, PrmID.INACTIVE, false) == 0; + } - // TODO - public static uint GetTypeSortNumber(ushort itemno) { return 0; } + public static uint GetTypeSortNumber(ushort itemno) + { + var item = ItemManager.Instance.Get(itemno); + return item.GetTypeSortNumber(); + } public enum PrmID : int { @@ -281,4 +356,4 @@ public enum FieldFunctionType : int ITEMUSE_FLD_DS_PLAYER = 29, } } -} \ No newline at end of file +} diff --git a/Assets/Scripts/Pml/Item/ItemManager.cs b/Assets/Scripts/Pml/Item/ItemManager.cs index c92161e19..80136547b 100644 --- a/Assets/Scripts/Pml/Item/ItemManager.cs +++ b/Assets/Scripts/Pml/Item/ItemManager.cs @@ -31,44 +31,121 @@ public int GetParam(ushort itemno, ItemData.PrmID prmID, bool isCheckActive = tr return m_alldata.Item[0].GetParam(prmID); } - // TODO - public BallId ItemID2BallID(ushort itemno) { return BallId.NULL; } + public BallId ItemID2BallID(ushort itemno) + { + var item = Get(itemno); + return item.GetBallID(); + } + + public ushort BallID2ItemID(BallId ballid) + { + if (ballid == BallId.NULL) + return (ushort)ItemNo.DUMMY_DATA; - // TODO - public ushort BallID2ItemID(BallId ballid) { return 0; } + for (int i = 0; i < m_alldata.Item.Length; i++) + { + var item = m_alldata.Item[i]; + if (item.GetBallID() == ballid) + return (ushort)i; + } - // TODO - public WazaNo GetWazaNo(ushort itemno) { return WazaNo.NULL; } + GFL.ASSERT(false, "Failed to BallID2ItemID()"); + return (ushort)ItemNo.DUMMY_DATA; + } + + public WazaNo GetWazaNo(ushort itemno) + { + var item = Get(itemno); + if (!item.IsWazaMachine()) + return WazaNo.NULL; + + for (int i = 0; i < m_alldata.WazaMachine.Length; i++) + { + if (m_alldata.WazaMachine[i].itemNo == itemno) + return (WazaNo)m_alldata.WazaMachine[i].wazaNo; + } - // TODO - private byte ItemNoToWazaMachineID(ushort itemno) { return 0; } + return WazaNo.NULL; + } - // TODO - public WazaNo WazaMachineIDToWazaID(byte machine_no) { return WazaNo.NULL; } + private byte ItemNoToWazaMachineID(ushort itemno) + { + return (byte)Get(itemno).GetWazaMashineNo(); + } - // TODO - public ItemNo WazaMachineIDToItemNo(byte machine_no) { return ItemNo.DUMMY_DATA; } + public WazaNo WazaMachineIDToWazaID(byte machine_no) + { + for (int i = 0; i < m_alldata.WazaMachine.Length; i++) + { + if (m_alldata.WazaMachine[i].machineNo == machine_no) + return (WazaNo)m_alldata.WazaMachine[i].wazaNo; + } - // TODO - public uint GetWazaMachineItemNum() { return 0; } + return WazaNo.NULL; + } - // TODO - private int GetIconId(ushort itemno) { return 0; } + public ItemNo WazaMachineIDToItemNo(byte machine_no) + { + for (int i = 0; i < m_alldata.WazaMachine.Length; i++) + { + if (m_alldata.WazaMachine[i].machineNo == machine_no) + return (ItemNo)m_alldata.WazaMachine[i].itemNo; + } - // TODO - public bool IsGroupOf(ushort itemno, byte itemgroup) { return false; } + return ItemNo.DUMMY_DATA; + } + + public uint GetWazaMachineItemNum() + { + return (uint)m_alldata.WazaMachine.Length; + } + + private int GetIconId(ushort itemno) + { + return GetParam(itemno, ItemData.PrmID.ICONID); + } + + public bool IsGroupOf(ushort itemno, byte itemgroup) + { + var item = Get(itemno); + return item.IsGroupOf(itemgroup); + } - // TODO public bool GroupIdToItemNo(byte itemgroup, byte groupid, out ushort o_pItemNo) { + for (int i = 0; i < m_alldata.Item.Length; i++) + { + var item = m_alldata.Item[i]; + if (item.group == itemgroup && item.group_id == groupid) + { + o_pItemNo = (ushort)i; + return true; + } + } + o_pItemNo = 0; return false; } - // TODO - public ItemTable.SheetItem Get(ushort itemno, bool isCheckActive = true) { return null; } + public ItemTable.SheetItem Get(ushort itemno, bool isCheckActive = true) + { + for (int i = 0; i < m_alldata.Item.Length; i++) + { + var item = m_alldata.Item[i]; + if (itemno == item.no) + { + if (item.no == 0 || !isCheckActive || item.GetParam(ItemData.PrmID.INACTIVE) == 0) + return item; + break; + } + } + + return m_alldata.Item[0]; + } - // TODO - public static bool IsStrangeBall(BallId ballid) { return false; } + public static bool IsStrangeBall(BallId ballid) + { + return ballid >= BallId.PAAKUBOORU; + } } -} \ No newline at end of file +} diff --git a/Assets/Scripts/Pml/Item/ItemTableExtensions.cs b/Assets/Scripts/Pml/Item/ItemTableExtensions.cs index 7ea78cf41..042fd1f4a 100644 --- a/Assets/Scripts/Pml/Item/ItemTableExtensions.cs +++ b/Assets/Scripts/Pml/Item/ItemTableExtensions.cs @@ -171,7 +171,7 @@ public static int GetWorkRecoverItem(this ItemTable.SheetItem prm, ItemData.PrmI return ((int)prm.flags0 & ItemData.FLAG0_MASK_ALLPP_RCV) != 0 ? 1 : 0; case ItemData.PrmID.HP_RCV: - if (prm.GetWorkRecoverItem(ItemData.PrmID.DEATH_RCV) != 1 || prm.GetWorkRecoverItem(ItemData.PrmID.ALL_DEATH_RCV) != 1) + if (((int)prm.flags0 & (ItemData.FLAG0_MASK_DEATH_RCV | ItemData.FLAG0_MASK_ALLDEATH_RCV)) != 0) return 0; return prm.wk_prm_hp_rcv != 0 ? 1 : 0; @@ -244,64 +244,217 @@ public static int GetWorkRecoverItem(this ItemTable.SheetItem prm, ItemData.PrmI } } - // TODO - public static uint GetHealingItemType(this ItemTable.SheetItem item) { return 0; } + public static uint GetHealingItemType(this ItemTable.SheetItem item) + { + int flags0 = (int)item.flags0; + + // Not WORK_TYPE → ETC + if ((flags0 & ItemData.FLAG0_MASK_WORK_TYPE) == 0) + return (uint)ItemData.ItemType.ETC; + + // ALLDEATH_RCV + if ((flags0 & ItemData.FLAG0_MASK_ALLDEATH_RCV) != 0) + return (uint)ItemData.ItemType.ALLDETH_RCV; + + // LV_UP + if ((flags0 & ItemData.FLAG0_MASK_LV_UP) != 0) + return (uint)ItemData.ItemType.LV_UP; + + // Build composite from 6 status cure flags + int statusCure = 0; + if ((flags0 & ItemData.FLAG0_MASK_SLEEP_RCV) != 0) statusCure |= 1; + if ((flags0 & ItemData.FLAG0_MASK_POISON_RCV) != 0) statusCure |= 2; + if ((flags0 & ItemData.FLAG0_MASK_BURN_RCV) != 0) statusCure |= 4; + if ((flags0 & ItemData.FLAG0_MASK_ICE_RCV) != 0) statusCure |= 8; + if ((flags0 & ItemData.FLAG0_MASK_PARALAYZE_RCV) != 0) statusCure |= 16; + if ((flags0 & ItemData.FLAG0_MASK_PANIC_RCV) != 0) statusCure |= 32; + + if (statusCure <= 8) + { + switch (statusCure) + { + case 1: return (uint)ItemData.ItemType.NEMURI_RCV; + case 2: return (uint)ItemData.ItemType.DOKU_RCV; + case 4: return (uint)ItemData.ItemType.YAKEDO_RCV; + case 8: return (uint)ItemData.ItemType.KOORI_RCV; + } + } + else + { + if (statusCure == 16) + return (uint)ItemData.ItemType.MAHI_RCV; + if (statusCure == 32) + return (uint)ItemData.ItemType.KONRAN_RCV; + if (statusCure == 0x3f) + { + if ((flags0 & (ItemData.FLAG0_MASK_DEATH_RCV | ItemData.FLAG0_MASK_ALLDEATH_RCV)) != 0) + return (uint)ItemData.ItemType.ALL_ST_RCV; + if (item.wk_prm_hp_rcv != 0) + return (uint)ItemData.ItemType.HP_RCV; + return (uint)ItemData.ItemType.ALL_ST_RCV; + } + } + + // MEROMERO_RCV + if ((flags0 & ItemData.FLAG0_MASK_MEROMERO_RCV) != 0) + return (uint)ItemData.ItemType.MEROMERO_RCV; + + // HP_RCV (only if no death recovery) + if ((flags0 & (ItemData.FLAG0_MASK_DEATH_RCV | ItemData.FLAG0_MASK_ALLDEATH_RCV)) == 0 + && item.wk_prm_hp_rcv != 0) + return (uint)ItemData.ItemType.HP_RCV; + + // DEATH_RCV + if ((flags0 & ItemData.FLAG0_MASK_DEATH_RCV) != 0) + return (uint)ItemData.ItemType.DEATH_RCV; - // TODO - public static bool IsNeedSelectSkill(this ItemTable.SheetItem item) { return false; } + // Stat increases/decreases (signed exp values) + if (item.wk_prm_hp_exp > 0) return (uint)ItemData.ItemType.HP_UP; + if (item.wk_prm_hp_exp < 0) return (uint)ItemData.ItemType.HP_DOWN; - // TODO - public static bool IsDeathRecoverAllItem(this ItemTable.SheetItem item) { return false; } + if (item.wk_prm_pow_exp > 0) return (uint)ItemData.ItemType.ATC_UP; + if (item.wk_prm_pow_exp < 0) return (uint)ItemData.ItemType.ATC_DOWN; - // TODO - public static bool IsSale(this ItemTable.SheetItem item) { return false; } + if (item.wk_prm_def_exp > 0) return (uint)ItemData.ItemType.DEF_UP; + if (item.wk_prm_def_exp < 0) return (uint)ItemData.ItemType.DEF_DOWN; - // TODO - public static bool IsEventItem(this ItemTable.SheetItem item) { return false; } + if (item.wk_prm_spa_exp > 0) return (uint)ItemData.ItemType.SPA_UP; + if (item.wk_prm_spa_exp < 0) return (uint)ItemData.ItemType.SPA_DOWN; - // TODO - public static int GetGroupId(this ItemTable.SheetItem item) { return 0; } + if (item.wk_prm_agi_exp > 0) return (uint)ItemData.ItemType.AGI_UP; + if (item.wk_prm_agi_exp < 0) return (uint)ItemData.ItemType.AGI_DOWN; - // TODO - public static BallId GetBallID(this ItemTable.SheetItem item) { return BallId.NULL; } + if (item.wk_prm_spd_exp > 0) return (uint)ItemData.ItemType.SPD_UP; + if (item.wk_prm_spd_exp < 0) return (uint)ItemData.ItemType.SPD_DOWN; - // TODO - public static bool IsWazaMachine(this ItemTable.SheetItem item) { return false; } + // EVOLUTION + if ((flags0 & ItemData.FLAG0_MASK_EVOLUTION) != 0) + return (uint)ItemData.ItemType.EVO; - // TODO - public static uint GetWazaMashineNo(this ItemTable.SheetItem item) { return 0; } + // PP_UP + if ((flags0 & ItemData.FLAG0_MASK_PP_UP) != 0) + return (uint)ItemData.ItemType.PP_UP; - // TODO - public static bool IsWazaRecord(this ItemTable.SheetItem item) { return false; } + // PP_3UP + if ((flags0 & ItemData.FLAG0_MASK_PP_3UP) != 0) + return (uint)ItemData.ItemType.PP_3UP; - // TODO - public static bool IsNuts(this ItemTable.SheetItem item) { return false; } + // PP_RCV + if ((flags0 & ItemData.FLAG0_MASK_PP_RCV) != 0) + return (uint)ItemData.ItemType.PP_RCV; - // TODO - public static byte GetNutsNo(this ItemTable.SheetItem item) { return 0; } + // ALLPP_RCV → PP_RCV type + if ((flags0 & ItemData.FLAG0_MASK_ALLPP_RCV) != 0) + return (uint)ItemData.ItemType.PP_RCV; + + return (uint)ItemData.ItemType.ETC; + } + + public static bool IsNeedSelectSkill(this ItemTable.SheetItem item) + { + uint healType = item.GetHealingItemType(); + if (healType == (uint)ItemData.ItemType.PP_UP || healType == (uint)ItemData.ItemType.PP_3UP) + return true; + if (healType != (uint)ItemData.ItemType.PP_RCV) + return false; + return item.GetParam(ItemData.PrmID.PP_RCV) != 0; + } + + public static bool IsDeathRecoverAllItem(this ItemTable.SheetItem item) + { + return ((int)item.flags0 & ItemData.FLAG0_MASK_WORK_TYPE) != 0 + && ((int)item.flags0 & ItemData.FLAG0_MASK_ALLDEATH_RCV) != 0; + } - // TODO - public static bool IsGroupOf(this ItemTable.SheetItem item, byte itemgroup) { return false; } + public static bool IsSale(this ItemTable.SheetItem item) + { + return ((int)item.flags0 & ItemData.FLAG0_MASK_IMP) == 0 && item.price != 0; + } - // TODO - public static bool IsMegaStone(this ItemTable.SheetItem item) { return false; } + public static bool IsEventItem(this ItemTable.SheetItem item) + { + return item.type == Pml.ItemType.EVENT; + } - // TODO - public static bool IsJewel(this ItemTable.SheetItem item) { return false; } + public static int GetGroupId(this ItemTable.SheetItem item) + { + return item.group_id; + } - // TODO - public static bool IsPiece(this ItemTable.SheetItem item) { return false; } + public static BallId GetBallID(this ItemTable.SheetItem item) + { + if (item.group != ItemGroup.BALL) + return BallId.NULL; + return (BallId)(item.group_id + 1); + } - // TODO - public static bool IsBeads(this ItemTable.SheetItem item) { return false; } + public static bool IsWazaMachine(this ItemTable.SheetItem item) + { + return item.group == ItemGroup.WAZA_MACHINE; + } - // TODO - public static bool IsHeart(this ItemTable.SheetItem item) { return false; } + public static uint GetWazaMashineNo(this ItemTable.SheetItem item) + { + if (!item.IsWazaMachine()) + return ItemData.ITEM_WAZAMACHINE_ERROR; + return (uint)item.group_id; + } - // TODO - public static bool CanPokeHave(this ItemTable.SheetItem item) { return false; } + public static bool IsWazaRecord(this ItemTable.SheetItem item) + { + return item.IsWazaMachine() && ((int)item.flags0 & ItemData.FLAG0_MASK_IMP) == 0; + } - // TODO - public static uint GetTypeSortNumber(this ItemTable.SheetItem item) { return 0; } + public static bool IsNuts(this ItemTable.SheetItem item) + { + return item.group == ItemGroup.NUTS; + } + + public static byte GetNutsNo(this ItemTable.SheetItem item) + { + if (!item.IsNuts()) + return ItemData.NUTS_ID_ERROR; + return item.group_id; + } + + public static bool IsGroupOf(this ItemTable.SheetItem item, byte itemgroup) + { + return item.group == itemgroup; + } + + public static bool IsMegaStone(this ItemTable.SheetItem item) + { + return item.group == ItemGroup.MEGA_STONE; + } + + public static bool IsJewel(this ItemTable.SheetItem item) + { + return item.group == ItemGroup.JEWEL; + } + + public static bool IsPiece(this ItemTable.SheetItem item) + { + return item.group == ItemGroup.PIECE; + } + + public static bool IsBeads(this ItemTable.SheetItem item) + { + return item.group == ItemGroup.BEADS; + } + + public static bool IsHeart(this ItemTable.SheetItem item) + { + return item.group == ItemGroup.HEART; + } + + public static bool CanPokeHave(this ItemTable.SheetItem item) + { + return ((int)item.flags0 & ItemData.FLAG0_MASK_SET_TO_POKE) != 0; + } + + public static uint GetTypeSortNumber(this ItemTable.SheetItem item) + { + return (uint)(((uint)item.type << 28) | ((uint)item.sort << 16)) + (uint)(short)item.no; + } } -} \ No newline at end of file +} diff --git a/Assets/Scripts/Pml/PokePara/Accessor.cs b/Assets/Scripts/Pml/PokePara/Accessor.cs index b812249f3..7e5fbb90c 100644 --- a/Assets/Scripts/Pml/PokePara/Accessor.cs +++ b/Assets/Scripts/Pml/PokePara/Accessor.cs @@ -1,9 +1,11 @@ -namespace Pml.PokePara +using System; +using System.Runtime.InteropServices; +using Pml; + +namespace Pml.PokePara { public class Accessor { - // TODO: cctor - private const uint CORE_DATA_SIZE = 328; private const uint CALC_DATA_SIZE = 16; public const uint FULL_SERIALIZE_DATA_SIZE = 344; @@ -31,49 +33,153 @@ public class Accessor private const byte POS2 = 1; private const byte POS3 = 2; private const byte POS4 = 3; - private static readonly byte[][] BLOCK_POS_TABLE; + private static readonly byte[][] BLOCK_POS_TABLE = GenerateBlockPosTable(); + + private static byte[][] GenerateBlockPosTable() + { + byte[][] order = new byte[24][] + { + new byte[] { 0, 1, 2, 3 }, + new byte[] { 0, 1, 3, 2 }, + new byte[] { 0, 2, 1, 3 }, + new byte[] { 0, 2, 3, 1 }, + new byte[] { 0, 3, 1, 2 }, + new byte[] { 0, 3, 2, 1 }, + new byte[] { 1, 0, 2, 3 }, + new byte[] { 1, 0, 3, 2 }, + new byte[] { 1, 2, 0, 3 }, + new byte[] { 1, 2, 3, 0 }, + new byte[] { 1, 3, 0, 2 }, + new byte[] { 1, 3, 2, 0 }, + new byte[] { 2, 0, 1, 3 }, + new byte[] { 2, 0, 3, 1 }, + new byte[] { 2, 1, 0, 3 }, + new byte[] { 2, 1, 3, 0 }, + new byte[] { 2, 3, 0, 1 }, + new byte[] { 2, 3, 1, 0 }, + new byte[] { 3, 0, 1, 2 }, + new byte[] { 3, 0, 2, 1 }, + new byte[] { 3, 1, 0, 2 }, + new byte[] { 3, 1, 2, 0 }, + new byte[] { 3, 2, 0, 1 }, + new byte[] { 3, 2, 1, 0 }, + }; + + byte[][] table = new byte[32][]; + for (int i = 0; i < 32; i++) + table[i] = order[i % 24]; + + return table; + } - // TODO public static void Initialize() { } - // TODO - public void AttachDecodedData(byte[] coreData, byte[] calcData) { } + public void AttachDecodedData(byte[] coreData, byte[] calcData) + { + m_pCoreData = coreData; + m_pCalcData = calcData; + m_accessState.isEncoded = false; + m_accessState.isFastMode = false; + UpdateChecksumAndEncode(); + } + + public void AttachEncodedData(byte[] coreData, byte[] calcData) + { + m_pCoreData = coreData; + m_pCalcData = calcData; + m_accessState.isEncoded = true; + m_accessState.isFastMode = false; + } + + public bool HaveCalcData() + { + return m_pCalcData != null; + } - // TODO - public void AttachEncodedData(byte[] coreData, byte[] calcData) { } + public void ClearData() + { + if (m_pCoreData != null) + Array.Clear(m_pCoreData, 0, m_pCoreData.Length); - // TODO - public bool HaveCalcData() { return false; } + if (m_pCalcData != null) + Array.Clear(m_pCalcData, 0, m_pCalcData.Length); - // TODO - public void ClearData() { } + m_accessState.isEncoded = false; + m_accessState.isFastMode = false; + UpdateChecksumAndEncode(); + } - // TODO - public void ClearCalcData() { } + public void ClearCalcData() + { + if (m_pCalcData != null) + Array.Clear(m_pCalcData, 0, m_pCalcData.Length); + } - // TODO - public void StartFastMode() { } + public void StartFastMode() + { + DecodeAndCheckIllegalWrite(); + m_accessState.isFastMode = true; + } - // TODO - public void EndFastMode() { } + public void EndFastMode() + { + m_accessState.isFastMode = false; + UpdateChecksumAndEncode(); + } - // TODO - public bool IsFastMode() { return false; } + public bool IsFastMode() + { + return m_accessState.isFastMode; + } - // TODO - public bool IsEncoded() { return false; } + public bool IsEncoded() + { + return m_accessState.isEncoded; + } - // TODO - public void Serialize_FullData(byte[] buffer) { } + public void Serialize_FullData(byte[] buffer) + { + unsafe + { + fixed (byte* dst = buffer) + { + Serialize(dst, dst + CORE_SERIALIZE_DATA_SIZE); + } + } + } - // TODO - public void Serialize_CoreData(byte[] buffer) { } + public void Serialize_CoreData(byte[] buffer) + { + unsafe + { + fixed (byte* dst = buffer) + { + Serialize(dst, null); + } + } + } - // TODO - public void Deserialize_FullData(byte[] serializedData) { } + public void Deserialize_FullData(byte[] serializedData) + { + unsafe + { + fixed (byte* src = serializedData) + { + Deserialize(src, src + CORE_SERIALIZE_DATA_SIZE); + } + } + } - // TODO - public void Deserialize_CoreData(byte[] serializedData) { } + public void Deserialize_CoreData(byte[] serializedData) + { + unsafe + { + fixed (byte* src = serializedData) + { + Deserialize(src, null); + } + } + } public unsafe void Serialize_FullData(void* buffer) { @@ -95,707 +201,2956 @@ public unsafe void Deserialize_CoreData(void* serializedData) Deserialize(serializedData, null); } - // TODO - public uint GetPersonalRnd() { return 0; } + // ============================================= + // Getters - Header + // ============================================= - // TODO - public uint GetColorRnd() { return 0; } + public uint GetPersonalRnd() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var header = GetCoreDataHeader(addr); + return header->personalRnd; + } + } + } - // TODO - public uint GetCheckSum() { return 0; } + public uint GetCheckSum() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var header = GetCoreDataHeader(addr); + return header->checksum; + } + } + } - // TODO - public bool IsFuseiTamago() { return false; } + public bool IsFuseiTamago() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var header = GetCoreDataHeader(addr); + return header->fuseiTamagoFlag; + } + } + } - // TODO - public uint GetSick() { return 0; } + // ============================================= + // Getters - BlockA + // ============================================= - // TODO - public MonsNo GetMonsNo() { return MonsNo.NULL; } + public MonsNo GetMonsNo() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, false); + return (MonsNo)block->monsno; + } + } + } - // TODO - public uint GetItemNo() { return 0; } + public uint GetItemNo() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, false); + return block->itemno; + } + } + } - // TODO - public uint GetID() { return 0; } + public uint GetID() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, false); + return block->id; + } + } + } - // TODO - public uint GetExp() { return 0; } + public uint GetExp() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, false); + return block->exp; + } + } + } - // TODO - public uint GetFriendship() { return 0; } + public TokuseiNo GetTokuseiNo() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, false); + return (TokuseiNo)block->tokuseino; + } + } + } - // TODO - public TokuseiNo GetTokuseiNo() { return TokuseiNo.NULL; } + public ushort GetBoxMark() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, false); + return block->boxMark; + } + } + } - // TODO - public ushort GetBoxMark() { return 0; } + public uint GetColorRnd() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, false); + return block->colorRnd; + } + } + } - // TODO - public uint GetLangId() { return 0; } + public uint GetSeikaku() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, false); + return block->seikaku; + } + } + } - // TODO - public uint GetEffortHp() { return 0; } + public uint GetSeikakuHosei() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, false); + return block->seikakuHosei; + } + } + } - // TODO - public uint GetEffortAtk() { return 0; } + public ushort GetFormNo() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, false); + return block->formNo; + } + } + } - // TODO - public uint GetEffortDef() { return 0; } + public uint GetEffortHp() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, false); + return block->effortHp; + } + } + } - // TODO - public uint GetEffortSpAtk() { return 0; } + public uint GetEffortAtk() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, false); + return block->effortAtk; + } + } + } - // TODO - public uint GetEffortSpDef() { return 0; } + public uint GetEffortDef() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, false); + return block->effortDef; + } + } + } + + public uint GetEffortAgi() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, false); + return block->effortAgi; + } + } + } + + public uint GetEffortSpAtk() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, false); + return block->effortSpatk; + } + } + } + + public uint GetEffortSpDef() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, false); + return block->effortSpdef; + } + } + } + + public byte GetStyle() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, false); + return block->style; + } + } + } + + public byte GetBeautiful() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, false); + return block->beautiful; + } + } + } - // TODO - public uint GetEffortAgi() { return 0; } + public byte GetCute() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, false); + return block->cute; + } + } + } + + public byte GetClever() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, false); + return block->clever; + } + } + } + + public byte GetStrong() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, false); + return block->strong; + } + } + } - // TODO - public byte GetStyle() { return 0; } + public byte GetFur() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, false); + return block->fur; + } + } + } + + public uint GetPokerus() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, false); + return block->pokerus; + } + } + } + + public bool IsTokusei1() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, false); + return block->tokusei1Flag; + } + } + } - // TODO - public byte GetBeautiful() { return 0; } + public bool IsTokusei2() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, false); + return block->tokusei2Flag; + } + } + } + + public bool IsTokusei3() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, false); + return block->tokusei3Flag; + } + } + } + + public bool IsFavorite() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, false); + return block->favoriteFlag; + } + } + } + + public bool IsSpecialGEnable() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, false); + return block->special_g_flag; + } + } + } + + public bool IsEventPokemon() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, false); + return block->eventGetFlag; + } + } + } + + public bool GetOfficialBattleEnableFlag() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, false); + return block->officialBattleEnableFlag; + } + } + } + + public Sex GetSex() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, false); + return (Sex)block->sex; + } + } + } + + public byte GetCampFriendship() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, false); + return (byte)block->camp_friendship; + } + } + } + + public bool GetDprIllegalFlag() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, false); + return block->dpr_illegal_flag; + } + } + } + + public byte GetTalentHeight() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, false); + return block->talentHeight; + } + } + } + + public byte GetTalentWeight() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, false); + return block->talentWeight; + } + } + } - // TODO - public byte GetCute() { return 0; } + public bool HaveRibbon(uint ribbonNo) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, false); + if (ribbonNo <= MAX_RIBBON_NO_ON_RIBBON_FIELD_1) + return (block->ribbonA & (1u << (int)(ribbonNo - MIN_RIBBON_NO_ON_RIBBON_FIELD_1))) != 0; + else if (ribbonNo <= MAX_RIBBON_NO_ON_RIBBON_FIELD_2) + return (block->ribbonB & (1u << (int)(ribbonNo - MIN_RIBBON_NO_ON_RIBBON_FIELD_2))) != 0; + else if (ribbonNo <= MAX_RIBBON_NO_ON_RIBBON_FIELD_3) + return (block->ribbonC & (1u << (int)(ribbonNo - MIN_RIBBON_NO_ON_RIBBON_FIELD_3))) != 0; + else if (ribbonNo <= MAX_RIBBON_NO_ON_RIBBON_FIELD_4) + return (block->ribbonD & (1u << (int)(ribbonNo - MIN_RIBBON_NO_ON_RIBBON_FIELD_4))) != 0; + + return false; + } + } + } - // TODO - public byte GetClever() { return 0; } + public uint GetLumpingRibbon(LumpingRibbon ribbonId) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, false); + switch (ribbonId) + { + case LumpingRibbon.A: + return block->lumpingRibbonA; + case LumpingRibbon.B: + return block->lumpingRibbonB; + default: + return 0; + } + } + } + } - // TODO - public byte GetStrong() { return 0; } + // ============================================= + // Getters - BlockB + // ============================================= - // TODO - public byte GetFur() { return 0; } + public uint GetSick() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockB(addr, false); + return block->sick; + } + } + } - // TODO - public bool HaveRibbon(uint ribbonNo) { return false; } + public WazaNo GetWazaNo(byte wazaIndex) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockB(addr, false); + if (wazaIndex < PmlConstants.MAX_WAZA_NUM) + return (WazaNo)block->waza[wazaIndex]; + return WazaNo.NULL; + } + } + } - // TODO - public uint GetLumpingRibbon(LumpingRibbon ribbonId) { return default; } + public byte GetPP(byte wazaIndex) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockB(addr, false); + if (wazaIndex < PmlConstants.MAX_WAZA_NUM) + return block->pp[wazaIndex]; + return 0; + } + } + } - // TODO - public byte GetEquipRibbonNo() { return 0; } + public byte GetWazaPPUpCount(byte wazaIndex) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockB(addr, false); + if (wazaIndex < PmlConstants.MAX_WAZA_NUM) + return block->pointupUsedCount[wazaIndex]; + return 0; + } + } + } - // TODO - public WazaNo GetWazaNo(byte wazaIndex) { return WazaNo.NULL; } + public WazaNo GetTamagoWazaNo(byte index) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockB(addr, false); + if (index < PmlConstants.MAX_WAZA_NUM) + return (WazaNo)block->tamagoWaza[index]; + return WazaNo.NULL; + } + } + } - // TODO - public byte GetPP(byte wazaIndex) { return 0; } + public uint GetHp() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockB(addr, false); + return block->hp; + } + } + } - // TODO - public byte GetWazaPPUpCount(byte wazaIndex) { return 0; } + public uint GetTalentHp() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockB(addr, false); + return block->talentHp; + } + } + } - // TODO - public WazaNo GetTamagoWazaNo(byte index) { return WazaNo.NULL; } + public uint GetTalentAtk() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockB(addr, false); + return block->talentAtk; + } + } + } - // TODO - public uint GetTalentHp() { return 0; } + public uint GetTalentDef() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockB(addr, false); + return block->talentDef; + } + } + } - // TODO - public uint GetTalentAtk() { return 0; } + public uint GetTalentSpAtk() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockB(addr, false); + return block->talentSpatk; + } + } + } - // TODO - public uint GetTalentDef() { return 0; } + public uint GetTalentSpDef() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockB(addr, false); + return block->talentSpdef; + } + } + } - // TODO - public uint GetTalentSpAtk() { return 0; } + public uint GetTalentAgi() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockB(addr, false); + return block->talentAgi; + } + } + } - // TODO - public uint GetTalentSpDef() { return 0; } + public uint GetEffortG() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockB(addr, false); + return block->effortG; + } + } + } - // TODO - public uint GetTalentAgi() { return 0; } + public bool IsTamago() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockB(addr, false); + return block->tamagoFlag; + } + } + } - // TODO - public uint GetEffortG() { return 0; } + public bool HaveNickName() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockB(addr, false); + return block->nicknameFlag; + } + } + } - // TODO - public bool IsEventPokemon() { return false; } + public string GetNickName() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockB(addr, false); + return new string(block->nickname); + } + } + } - // TODO - public bool GetOfficialBattleEnableFlag() { return false; } + public uint GetPalma() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockB(addr, false); + return block->palma; + } + } + } - // TODO - public Sex GetSex() { return Sex.MALE; } + // ============================================= + // Getters - BlockC + // ============================================= - // TODO - public ushort GetFormNo() { return 0; } + public string GetPastParentsName() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockC(addr, false); + return new string(block->pastParentsName); + } + } + } - // TODO - public uint GetSeikaku() { return 0; } + public Sex GetPastParentsSex() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockC(addr, false); + return (Sex)block->pastParentsSex; + } + } + } - // TODO - public uint GetSeikakuHosei() { return 0; } + public byte GetPastParentsLangID() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockC(addr, false); + return block->pastParentLangID; + } + } + } - // TODO - public bool IsTokusei1() { return false; } + public bool GetOwnedOthersFlag() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockC(addr, false); + return block->ownedByOthers != 0; + } + } + } - // TODO - public bool IsTokusei2() { return false; } + public ushort GetOthersFriendshipTrainerID() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockC(addr, false); + return block->othersFriendshipTrainerId; + } + } + } - // TODO - public bool IsTokusei3() { return false; } + public byte GetOthersFriendship() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockC(addr, false); + return block->othersFriendship; + } + } + } - // TODO - public bool IsFavorite() { return false; } + public byte GetOthersMemoriesLevel() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockC(addr, false); + return block->othersMemoriesLevel; + } + } + } - // TODO - public bool IsSpecialGEnable() { return false; } + public byte GetOthersMemoriesCode() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockC(addr, false); + return block->othersMemoriesCode; + } + } + } - // TODO - public bool IsTamago() { return false; } + public ushort GetOthersMemoriesData() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockC(addr, false); + return block->othersMemoriesData; + } + } + } - // TODO - public bool HaveNickName() { return false; } + public byte GetOthersMemoriesFeel() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockC(addr, false); + return block->othersMemoriesFeel; + } + } + } - // TODO - public string GetNickName() { return ""; } + public bool GetPokeJobFlag(byte jobIndex) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockC(addr, false); + CalcPokeJobBitPos(out byte arrayIndex, out byte bitFlag, jobIndex); + if (arrayIndex < CoreDataBlockC.POKEJOB_LEN) + return (block->pokejob[arrayIndex] & bitFlag) != 0; + return false; + } + } + } - // TODO - public uint GetCassetteVersion() { return 0; } + public byte GetEnjoy() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockC(addr, false); + return block->enjoy; + } + } + } - // TODO - public string GetOyaName() { return ""; } + public byte GetNadenadeValue() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockC(addr, false); + return block->nadeNadeValue; + } + } + } - // TODO - public uint GetTamagoGetYear() { return 0; } + public uint GetCassetteVersion() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockC(addr, false); + return block->getCassette; + } + } + } - // TODO - public uint GetTamagoGetMonth() { return 0; } + public byte GetBattleRomMark() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockC(addr, false); + return block->battleRomMark; + } + } + } - // TODO - public uint GetTamagoGetDay() { return 0; } + public uint GetLangId() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockC(addr, false); + return block->langId; + } + } + } - // TODO - public uint GetBirthYear() { return 0; } + public uint GetMultiPurposeWork() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockC(addr, false); + return block->multiWork; + } + } + } - // TODO - public uint GetBirthMonth() { return 0; } + public byte GetEquipRibbonNo() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockC(addr, false); + return block->equipRibbon; + } + } + } - // TODO - public uint GetBirthDay() { return 0; } + // ============================================= + // Getters - BlockD + // ============================================= - // TODO - public uint GetGetPlace() { return 0; } + public string GetOyaName() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockD(addr, false); + return new string(block->parentsName); + } + } + } - // TODO - public uint GetBirthPlace() { return 0; } + public uint GetFriendship() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var blockC = GetCoreDataBlockC(addr, false); + if (blockC->ownedByOthers != 0) + return blockC->othersFriendship; + + var block = GetCoreDataBlockD(addr, false); + return block->friendship; + } + } + } - // TODO - public uint GetPokerus() { return 0; } + public byte GetOriginalFriendship() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockD(addr, false); + return block->friendship; + } + } + } - // TODO - public uint GetGetBall() { return 0; } + public byte GetMemoriesLevel() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockD(addr, false); + return block->memories_level; + } + } + } - // TODO - public uint GetGetLevel() { return 0; } + public byte GetMemoriesCode() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockD(addr, false); + return block->memories_code; + } + } + } - // TODO - public Sex GetOyasex() { return Sex.MALE; } + public ushort GetMemoriesData() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockD(addr, false); + return block->memories_data; + } + } + } - // TODO - public uint GetLevel() { return 0; } + public byte GetMemoriesFeel() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockD(addr, false); + return block->memories_feel; + } + } + } - // TODO - public uint GetHp() { return 0; } + public uint GetTamagoGetYear() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockD(addr, false); + return block->eggGetYear; + } + } + } - // TODO - public uint GetMaxHp() { return 0; } + public uint GetTamagoGetMonth() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockD(addr, false); + return block->eggGetMonth; + } + } + } - // TODO - public uint GetAtk() { return 0; } + public uint GetTamagoGetDay() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockD(addr, false); + return block->eggGetDay; + } + } + } - // TODO - public uint GetDef() { return 0; } + public uint GetBirthYear() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockD(addr, false); + return block->firstContactYear; + } + } + } - // TODO - public uint GetSpAtk() { return 0; } + public uint GetBirthMonth() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockD(addr, false); + return block->firstContactMonth; + } + } + } - // TODO - public uint GetSpDef() { return 0; } + public uint GetBirthDay() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockD(addr, false); + return block->firstContactDay; + } + } + } - // TODO - public uint GetAgi() { return 0; } + public uint GetGetPlace() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockD(addr, false); + return block->getPlace; + } + } + } - // TODO - public GState GetGState() { return GState.NONE; } + public uint GetBirthPlace() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockD(addr, false); + return block->birthPlace; + } + } + } - // TODO - public byte GetEnjoy() { return 0; } + public uint GetGetBall() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockD(addr, false); + return block->getBall; + } + } + } - // TODO - public byte GetNadenadeValue() { return 0; } + public uint GetGetLevel() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockD(addr, false); + return block->getLevel; + } + } + } - // TODO - public ushort GetOthersFriendshipTrainerID() { return 0; } + public Sex GetOyasex() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockD(addr, false); + return (Sex)block->parentsSex; + } + } + } - // TODO - public bool GetOwnedOthersFlag() { return false; } + public byte GetTrainingFlag() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockD(addr, false); + return block->trainingFlag; + } + } + } - // TODO - public byte GetOriginalFriendship() { return 0; } + public bool GetWazaRecordFlag(byte recordIndex) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockD(addr, false); + CalcWazaRecordBitPos(out byte arrayIndex, out byte bitFlag, recordIndex); + if (arrayIndex < CoreDataBlockD.WAZA_RECORD_FLAG_LEN) + return (block->wazaRecordFlag[arrayIndex] & bitFlag) != 0; + return false; + } + } + } - // TODO - public byte GetOthersFriendship() { return 0; } + public ulong GetBankUniqueID() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockD(addr, false); + ulong value = 0; + for (int i = 0; i < CoreDataBlockD.BANK_UNIQUE_ID_LEN; i++) + value |= (ulong)block->bankUniqueID[i] << (i * 8); + return value; + } + } + } - // TODO - public byte GetMemoriesLevel() { return 0; } + public bool CompareOyaName(string cmpName) + { + return GetOyaName() == cmpName; + } - // TODO - public byte GetMemoriesCode() { return 0; } + // ============================================= + // Getters - CalcData + // ============================================= - // TODO - public ushort GetMemoriesData() { return 0; } + public uint GetLevel() + { + unsafe + { + fixed (byte* addr = m_pCalcData) + { + var calc = GetCalcData(addr, false); + return calc->level; + } + } + } - // TODO - public byte GetMemoriesFeel() { return 0; } + public uint GetMaxHp() + { + unsafe + { + fixed (byte* addr = m_pCalcData) + { + var calc = GetCalcData(addr, false); + return calc->maxHp; + } + } + } - // TODO - public byte GetOthersMemoriesLevel() { return 0; } + public uint GetAtk() + { + unsafe + { + fixed (byte* addr = m_pCalcData) + { + var calc = GetCalcData(addr, false); + return calc->atk; + } + } + } - // TODO - public byte GetOthersMemoriesCode() { return 0; } + public uint GetDef() + { + unsafe + { + fixed (byte* addr = m_pCalcData) + { + var calc = GetCalcData(addr, false); + return calc->def; + } + } + } - // TODO - public ushort GetOthersMemoriesData() { return 0; } + public uint GetSpAtk() + { + unsafe + { + fixed (byte* addr = m_pCalcData) + { + var calc = GetCalcData(addr, false); + return calc->spatk; + } + } + } - // TODO - public byte GetOthersMemoriesFeel() { return 0; } + public uint GetSpDef() + { + unsafe + { + fixed (byte* addr = m_pCalcData) + { + var calc = GetCalcData(addr, false); + return calc->spdef; + } + } + } - // TODO - public string GetPastParentsName() { return ""; } + public uint GetAgi() + { + unsafe + { + fixed (byte* addr = m_pCalcData) + { + var calc = GetCalcData(addr, false); + return calc->agi; + } + } + } - // TODO - public Sex GetPastParentsSex() { return Sex.NUM; } + public GState GetGState() + { + unsafe + { + fixed (byte* addr = m_pCalcData) + { + var calc = GetCalcData(addr, false); + return (GState)calc->gState; + } + } + } - // TODO - public byte GetPastParentsLangID() { return 0; } + // ============================================= + // Setters - Header + // ============================================= - // TODO - public bool CompareOyaName(string cmpName) { return false; } + public void SetPersonalRnd(uint rnd) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var header = GetCoreDataHeader(addr); + header->personalRnd = rnd; + } + } + } - // TODO - public uint GetMultiPurposeWork() { return 0; } + public void SetCheckSum(ushort checksum) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var header = GetCoreDataHeader(addr); + header->checksum = checksum; + } + } + } - // TODO - public byte GetTrainingFlag() { return 0; } + public void SetFuseiTamagoFlag(bool flag) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var header = GetCoreDataHeader(addr); + header->fuseiTamagoFlag = flag; + } + } + } - // TODO - public bool GetWazaRecordFlag(byte recordIndex) { return false; } + // ============================================= + // Setters - BlockA + // ============================================= - // TODO - public bool GetPokeJobFlag(byte jobIndex) { return false; } + public void SetMonsNo(uint monsno) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, true); + block->monsno = (ushort)monsno; + } + } + } - // TODO - public byte GetCampFriendship() { return 0; } + public void SetItemNo(ushort itemno) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, true); + block->itemno = itemno; + } + } + } - // TODO - public uint GetPalma() { return 0; } + public void SetID(uint id) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, true); + block->id = id; + } + } + } - // TODO - public byte GetTalentHeight() { return 0; } + public void SetExp(uint exp) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, true); + block->exp = exp; + } + } + } - // TODO - public byte GetTalentWeight() { return 0; } + public void SetTokuseiNo(uint tokusei) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, true); + block->tokuseino = (ushort)tokusei; + } + } + } - // TODO - public byte GetBattleRomMark() { return 0; } + public void SetBoxMark(ushort mark) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, true); + block->boxMark = mark; + } + } + } - // TODO - public void SetDprIllegalFlag(bool flag) { } + public void SetColorRnd(uint rnd) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, true); + block->colorRnd = rnd; + } + } + } - // TODO - public bool GetDprIllegalFlag() { return false; } + public void SetSeikaku(uint seikaku) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, true); + block->seikaku = (byte)seikaku; + } + } + } - // TODO - public void SetPersonalRnd(uint rnd) { } + public void SetSeikakuHosei(uint seikaku) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, true); + block->seikakuHosei = (byte)seikaku; + } + } + } - // TODO - public void SetColorRnd(uint rnd) { } + public void SetFormNo(ushort formno) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, true); + block->formNo = formno; + } + } + } - // TODO - public void SetSick(uint sick) { } + public void SetEffortHp(byte value) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, true); + block->effortHp = value; + } + } + } - // TODO - public void SetFuseiTamagoFlag(bool flag) { } + public void SetEffortAtk(byte value) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, true); + block->effortAtk = value; + } + } + } - // TODO - public void SetCheckSum(ushort checksum) { } + public void SetEffortDef(byte value) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, true); + block->effortDef = value; + } + } + } - // TODO - public void SetMonsNo(uint monsno) { } + public void SetEffortAgi(byte value) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, true); + block->effortAgi = value; + } + } + } - // TODO - public void SetItemNo(ushort itemno) { } + public void SetEffortSpAtk(byte value) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, true); + block->effortSpatk = value; + } + } + } - // TODO - public void SetID(uint id) { } + public void SetEffortSpDef(byte value) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, true); + block->effortSpdef = value; + } + } + } - // TODO - public void SetExp(uint exp) { } + public void SetStyle(byte style) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, true); + block->style = style; + } + } + } - // TODO - public void SetFriendship(byte friendship) { } + public void SetBeautiful(byte beautiful) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, true); + block->beautiful = beautiful; + } + } + } - // TODO - public void SetTokuseiNo(uint tokusei) { } + public void SetCute(byte cute) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, true); + block->cute = cute; + } + } + } - // TODO - public void SetBoxMark(ushort mark) { } + public void SetClever(byte clever) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, true); + block->clever = clever; + } + } + } - // TODO - public void SetLangId(byte langId) { } + public void SetStrong(byte strong) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, true); + block->strong = strong; + } + } + } - // TODO - public void SetEffortHp(byte value) { } + public void SetFur(byte fur) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, true); + block->fur = fur; + } + } + } - // TODO - public void SetEffortAtk(byte value) { } + public void SetPokerus(byte pokerus) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, true); + block->pokerus = pokerus; + } + } + } - // TODO - public void SetEffortDef(byte value) { } + public void SetRibbon(uint ribbonNo) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, true); + if (ribbonNo <= MAX_RIBBON_NO_ON_RIBBON_FIELD_1) + block->ribbonA |= (1u << (int)(ribbonNo - MIN_RIBBON_NO_ON_RIBBON_FIELD_1)); + else if (ribbonNo <= MAX_RIBBON_NO_ON_RIBBON_FIELD_2) + block->ribbonB |= (1u << (int)(ribbonNo - MIN_RIBBON_NO_ON_RIBBON_FIELD_2)); + else if (ribbonNo <= MAX_RIBBON_NO_ON_RIBBON_FIELD_3) + block->ribbonC |= (1u << (int)(ribbonNo - MIN_RIBBON_NO_ON_RIBBON_FIELD_3)); + else if (ribbonNo <= MAX_RIBBON_NO_ON_RIBBON_FIELD_4) + block->ribbonD |= (1u << (int)(ribbonNo - MIN_RIBBON_NO_ON_RIBBON_FIELD_4)); + } + } + } - // TODO - public void SetEffortSpAtk(byte value) { } + public void RemoveRibbon(uint ribbonNo) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, true); + if (ribbonNo <= MAX_RIBBON_NO_ON_RIBBON_FIELD_1) + block->ribbonA &= ~(1u << (int)(ribbonNo - MIN_RIBBON_NO_ON_RIBBON_FIELD_1)); + else if (ribbonNo <= MAX_RIBBON_NO_ON_RIBBON_FIELD_2) + block->ribbonB &= ~(1u << (int)(ribbonNo - MIN_RIBBON_NO_ON_RIBBON_FIELD_2)); + else if (ribbonNo <= MAX_RIBBON_NO_ON_RIBBON_FIELD_3) + block->ribbonC &= ~(1u << (int)(ribbonNo - MIN_RIBBON_NO_ON_RIBBON_FIELD_3)); + else if (ribbonNo <= MAX_RIBBON_NO_ON_RIBBON_FIELD_4) + block->ribbonD &= ~(1u << (int)(ribbonNo - MIN_RIBBON_NO_ON_RIBBON_FIELD_4)); + } + } + } - // TODO - public void SetEffortSpDef(byte value) { } + public void RemoveAllRibbon() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, true); + block->ribbonA = 0; + block->ribbonB = 0; + block->ribbonC = 0; + block->ribbonD = 0; + block->lumpingRibbonA = 0; + block->lumpingRibbonB = 0; + } + } + } - // TODO - public void SetEffortAgi(byte value) { } + public void SetLumpingRibbon(LumpingRibbon ribbonId, uint num) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, true); + switch (ribbonId) + { + case LumpingRibbon.A: + block->lumpingRibbonA = (byte)num; + break; + case LumpingRibbon.B: + block->lumpingRibbonB = (byte)num; + break; + } + } + } + } - // TODO - public void SetStyle(byte style) { } + public void SetTokusei1Flag(bool flag) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, true); + block->tokusei1Flag = flag; + } + } + } - // TODO - public void SetBeautiful(byte beautiful) { } + public void SetTokusei2Flag(bool flag) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, true); + block->tokusei2Flag = flag; + } + } + } - // TODO - public void SetCute(byte cute) { } + public void SetTokusei3Flag(bool flag) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, true); + block->tokusei3Flag = flag; + } + } + } - // TODO - public void SetClever(byte clever) { } + public void SetFavoriteFlag(bool flag) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, true); + block->favoriteFlag = flag; + } + } + } - // TODO - public void SetStrong(byte strong) { } + public void SetSpecialGFlag(bool flag) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, true); + block->special_g_flag = flag; + } + } + } - // TODO - public void SetFur(byte fur) { } + public void SetEventPokemonFlag(bool flag) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, true); + block->eventGetFlag = flag; + } + } + } - // TODO - public void SetRibbon(uint ribbonNo) { } + public void SetOfficialBattleEnableFlag(bool flag) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, true); + block->officialBattleEnableFlag = flag; + } + } + } - // TODO - public void RemoveRibbon(uint ribbonNo) { } + public void SetSex(Sex sex) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, true); + block->sex = (byte)sex; + } + } + } - // TODO - public void SetLumpingRibbon(LumpingRibbon ribbonId, uint num) { } + public void SetCampFriendship(byte value) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, true); + block->camp_friendship = value; + } + } + } - // TODO - public void SetEquipRibbonNo(byte ribbonNo) { } + public void SetDprIllegalFlag(bool flag) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, true); + block->dpr_illegal_flag = flag; + } + } + } - // TODO - public void SetWazaNo(byte wazaIndex, uint wazano) { } + public void SetTalentHeight(byte value) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, true); + block->talentHeight = value; + } + } + } - // TODO - public void SetPP(byte wazaIndex, byte pp) { } + public void SetTalentWeight(byte value) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockA(addr, true); + block->talentWeight = value; + } + } + } - // TODO - public void SetWazaPPUpCount(byte wazaIndex, byte count) { } + // ============================================= + // Setters - BlockB + // ============================================= - // TODO - public void SetTamagoWazaNo(byte index, uint wazano) { } + public void SetSick(uint sick) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockB(addr, true); + block->sick = sick; + } + } + } - // TODO - public void SetTalentHp(byte value) { } + public void SetWazaNo(byte wazaIndex, uint wazano) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockB(addr, true); + if (wazaIndex < PmlConstants.MAX_WAZA_NUM) + block->waza[wazaIndex] = (ushort)wazano; + } + } + } - // TODO - public void SetTalentAtk(byte value) { } + public void SetPP(byte wazaIndex, byte pp) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockB(addr, true); + if (wazaIndex < PmlConstants.MAX_WAZA_NUM) + block->pp[wazaIndex] = pp; + } + } + } - // TODO - public void SetTalentDef(byte value) { } + public void SetWazaPPUpCount(byte wazaIndex, byte count) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockB(addr, true); + if (wazaIndex < PmlConstants.MAX_WAZA_NUM) + block->pointupUsedCount[wazaIndex] = count; + } + } + } - // TODO - public void SetTalentSpAtk(byte value) { } + public void SetTamagoWazaNo(byte index, uint wazano) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockB(addr, true); + if (index < PmlConstants.MAX_WAZA_NUM) + block->tamagoWaza[index] = (ushort)wazano; + } + } + } - // TODO - public void SetTalentSpDef(byte value) { } + public void SetHp(ushort hp) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockB(addr, true); + block->hp = hp; + } + } + } - // TODO - public void SetTalentAgi(byte value) { } + public void SetTalentHp(byte value) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockB(addr, true); + block->talentHp = value; + } + } + } - // TODO - public void SetEffortG(byte value) { } + public void SetTalentAtk(byte value) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockB(addr, true); + block->talentAtk = value; + } + } + } - // TODO - public void SetEventPokemonFlag(bool flag) { } + public void SetTalentDef(byte value) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockB(addr, true); + block->talentDef = value; + } + } + } - // TODO - public void SetOfficialBattleEnableFlag(bool flag) { } + public void SetTalentSpAtk(byte value) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockB(addr, true); + block->talentSpatk = value; + } + } + } - // TODO - public void SetSex(Sex sex) { } + public void SetTalentSpDef(byte value) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockB(addr, true); + block->talentSpdef = value; + } + } + } - // TODO - public void SetFormNo(ushort formno) { } + public void SetTalentAgi(byte value) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockB(addr, true); + block->talentAgi = value; + } + } + } - // TODO - public void SetSeikaku(uint seikaku) { } + public void SetEffortG(byte value) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockB(addr, true); + block->effortG = value; + } + } + } - // TODO - public void SetSeikakuHosei(uint seikaku) { } + public void SetTamagoFlag(bool flag) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockB(addr, true); + block->tamagoFlag = flag; + } + } + } - // TODO - public void SetTamagoFlag(bool flag) { } + public void SetNickNameFlag(bool flag) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockB(addr, true); + block->nicknameFlag = flag; + } + } + } - // TODO - public void SetTokusei1Flag(bool flag) { } + public void SetNickName(string nickName) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockB(addr, true); + copyString(block->nickname, nickName, PmlConstants.MONS_NAME_BUFFER_SIZE); + } + } + } - // TODO - public void SetTokusei2Flag(bool flag) { } + public void SetPalma(uint value) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockB(addr, true); + block->palma = value; + } + } + } - // TODO - public void SetTokusei3Flag(bool flag) { } + // ============================================= + // Setters - BlockC + // ============================================= - // TODO - public void SetFavoriteFlag(bool flag) { } + public void SetPastParentsName(string name) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockC(addr, true); + copyString(block->pastParentsName, name, PmlConstants.PERSON_NAME_BUFFER_SIZE); + } + } + } - // TODO - public void SetSpecialGFlag(bool flag) { } + public void SetPastParentsSex(Sex sex) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockC(addr, true); + block->pastParentsSex = (byte)sex; + } + } + } - // TODO - private unsafe void copyString(char* dst, string _src, int dst_len) { } + public void SetPastParentsLangID(byte langID) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockC(addr, true); + block->pastParentLangID = langID; + } + } + } - // TODO - public void SetNickName(string nickName) { } + public void SetOwnedOthersFlag(bool flag) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockC(addr, true); + block->ownedByOthers = (byte)(flag ? 1 : 0); + } + } + } - // TODO - public void SetNickNameFlag(bool flag) { } + public void SetOthersFriendshipTrainerID(ushort trainerId) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockC(addr, true); + block->othersFriendshipTrainerId = trainerId; + } + } + } - // TODO - public void SetCassetteVersion(uint version) { } + public void SetOthersFriendship(byte friendship) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockC(addr, true); + block->othersFriendship = friendship; + } + } + } - // TODO - public void SetOyaName(string oyaName) { } + public void SetOthersMemoriesLevel(byte level) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockC(addr, true); + block->othersMemoriesLevel = level; + } + } + } - // TODO - public void SetTamagoGetYear(byte year) { } + public void SetOthersMemoriesCode(byte code) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockC(addr, true); + block->othersMemoriesCode = code; + } + } + } - // TODO - public void SetTamagoGetMonth(byte month) { } + public void SetOthersMemoriesData(ushort data) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockC(addr, true); + block->othersMemoriesData = data; + } + } + } - // TODO - public void SetTamagoGetDay(byte day) { } + public void SetOthersMemoriesFeel(byte feel) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockC(addr, true); + block->othersMemoriesFeel = feel; + } + } + } - // TODO - public void SetBirthYear(byte year) { } + public void SetPokeJobFlag(byte jobIndex, bool set) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockC(addr, true); + CalcPokeJobBitPos(out byte arrayIndex, out byte bitFlag, jobIndex); + if (arrayIndex < CoreDataBlockC.POKEJOB_LEN) + { + if (set) + block->pokejob[arrayIndex] |= bitFlag; + else + block->pokejob[arrayIndex] &= (byte)~bitFlag; + } + } + } + } - // TODO - public void SetBirthMonth(byte month) { } + public void ClearPokeJobFlag() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockC(addr, true); + for (int i = 0; i < CoreDataBlockC.POKEJOB_LEN; i++) + block->pokejob[i] = 0; + } + } + } - // TODO - public void SetBirthDay(byte day) { } + public void SetEnjoy(byte enjoy) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockC(addr, true); + block->enjoy = enjoy; + } + } + } - // TODO - public void SetGetPlace(ushort place) { } + public void SetNadenadeValue(byte value) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockC(addr, true); + block->nadeNadeValue = value; + } + } + } - // TODO - public void SetBirthPlace(ushort place) { } + public void SetCassetteVersion(uint version) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockC(addr, true); + block->getCassette = (byte)version; + } + } + } - // TODO - public void SetPokerus(byte pokerus) { } + public void SetBattleRomMark(byte value) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockC(addr, true); + block->battleRomMark = value; + } + } + } - // TODO - public void SetGetBall(byte ball) { } + public void SetLangId(byte langId) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockC(addr, true); + block->langId = langId; + } + } + } - // TODO - public void SetGetLevel(byte level) { } + public void SetMultiPurposeWork(uint value) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockC(addr, true); + block->multiWork = value; + } + } + } - // TODO - public void SetOyasex(Sex sex) { } + public void SetEquipRibbonNo(byte ribbonNo) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockC(addr, true); + block->equipRibbon = ribbonNo; + } + } + } - // TODO - public void SetLevel(byte level) { } + // ============================================= + // Setters - BlockD + // ============================================= - // TODO - public void SetMaxHp(ushort maxHp) { } + public void SetOyaName(string oyaName) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockD(addr, true); + copyString(block->parentsName, oyaName, PmlConstants.PERSON_NAME_BUFFER_SIZE); + } + } + } - // TODO - public void SetHp(ushort hp) { } + public void SetFriendship(byte friendship) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var blockC = GetCoreDataBlockC(addr, false); + if (blockC->ownedByOthers != 0) + { + var blockCW = GetCoreDataBlockC(addr, true); + blockCW->othersFriendship = friendship; + } + else + { + var block = GetCoreDataBlockD(addr, true); + block->friendship = friendship; + } + } + } + } - // TODO - public void SetAtk(ushort atk) { } + public void SetOriginalFriendship(byte friendship) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockD(addr, true); + block->friendship = friendship; + } + } + } - // TODO - public void SetDef(ushort def) { } + public void SetMemoriesLevel(byte level) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockD(addr, true); + block->memories_level = level; + } + } + } - // TODO - public void SetSpAtk(ushort spatk) { } + public void SetMemoriesCode(byte code) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockD(addr, true); + block->memories_code = code; + } + } + } - // TODO - public void SetSpDef(ushort spdef) { } + public void SetMemoriesData(ushort data) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockD(addr, true); + block->memories_data = data; + } + } + } - // TODO - public void SetAgi(ushort agi) { } + public void SetMemoriesFeel(byte feel) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockD(addr, true); + block->memories_feel = feel; + } + } + } - // TODO - public void SetGState(GState state) { } + public void SetTamagoGetYear(byte year) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockD(addr, true); + block->eggGetYear = year; + } + } + } - // TODO - public void SetEnjoy(byte enjoy) { } + public void SetTamagoGetMonth(byte month) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockD(addr, true); + block->eggGetMonth = month; + } + } + } - // TODO - public void SetNadenadeValue(byte value) { } + public void SetTamagoGetDay(byte day) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockD(addr, true); + block->eggGetDay = day; + } + } + } - // TODO - public void SetOthersFriendshipTrainerID(ushort trainerId) { } + public void SetBirthYear(byte year) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockD(addr, true); + block->firstContactYear = year; + } + } + } - // TODO - public void SetOwnedOthersFlag(bool flag) { } + public void SetBirthMonth(byte month) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockD(addr, true); + block->firstContactMonth = month; + } + } + } - // TODO - public void SetOriginalFriendship(byte friendship) { } + public void SetBirthDay(byte day) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockD(addr, true); + block->firstContactDay = day; + } + } + } - // TODO - public void SetOthersFriendship(byte friendship) { } + public void SetGetPlace(ushort place) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockD(addr, true); + block->getPlace = place; + } + } + } - // TODO - public void SetMemoriesLevel(byte level) { } + public void SetBirthPlace(ushort place) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockD(addr, true); + block->birthPlace = place; + } + } + } - // TODO - public void SetMemoriesCode(byte code) { } + public void SetGetBall(byte ball) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockD(addr, true); + block->getBall = ball; + } + } + } - // TODO - public void SetMemoriesData(ushort data) { } + public void SetGetLevel(byte level) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockD(addr, true); + block->getLevel = level; + } + } + } - // TODO - public void SetMemoriesFeel(byte feel) { } + public void SetOyasex(Sex sex) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockD(addr, true); + block->parentsSex = (byte)sex; + } + } + } - // TODO - public void SetOthersMemoriesLevel(byte level) { } + public void SetTrainingFlag(byte value) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockD(addr, true); + block->trainingFlag = value; + } + } + } - // TODO - public void SetOthersMemoriesCode(byte code) { } + public void SetWazaRecordFlag(byte recordIndex, bool set) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockD(addr, true); + CalcWazaRecordBitPos(out byte arrayIndex, out byte bitFlag, recordIndex); + if (arrayIndex < CoreDataBlockD.WAZA_RECORD_FLAG_LEN) + { + if (set) + block->wazaRecordFlag[arrayIndex] |= bitFlag; + else + block->wazaRecordFlag[arrayIndex] &= (byte)~bitFlag; + } + } + } + } - // TODO - public void SetOthersMemoriesData(ushort data) { } + public void ClearWazaRecordFlag() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockD(addr, true); + for (int i = 0; i < CoreDataBlockD.WAZA_RECORD_FLAG_LEN; i++) + block->wazaRecordFlag[i] = 0; + } + } + } - // TODO - public void SetOthersMemoriesFeel(byte feel) { } + public void SetBankUniqueID(ulong value) + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockD(addr, true); + for (int i = 0; i < CoreDataBlockD.BANK_UNIQUE_ID_LEN; i++) + block->bankUniqueID[i] = (byte)(value >> (i * 8)); + } + } + } - // TODO - public void SetPastParentsName(string name) { } + public void ClearBankUniqueID() + { + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var block = GetCoreDataBlockD(addr, true); + for (int i = 0; i < CoreDataBlockD.BANK_UNIQUE_ID_LEN; i++) + block->bankUniqueID[i] = 0; + } + } + } - // TODO - public void SetPastParentsSex(Sex sex) { } + // ============================================= + // Setters - CalcData + // ============================================= - // TODO - public void SetPastParentsLangID(byte langID) { } + public void SetLevel(byte level) + { + unsafe + { + fixed (byte* addr = m_pCalcData) + { + var calc = GetCalcData(addr, true); + calc->level = level; + } + } + } - // TODO - public void SetMultiPurposeWork(uint value) { } + public void SetMaxHp(ushort maxHp) + { + unsafe + { + fixed (byte* addr = m_pCalcData) + { + var calc = GetCalcData(addr, true); + calc->maxHp = maxHp; + } + } + } - // TODO - public void SetTrainingFlag(byte value) { } + public void SetAtk(ushort atk) + { + unsafe + { + fixed (byte* addr = m_pCalcData) + { + var calc = GetCalcData(addr, true); + calc->atk = atk; + } + } + } - // TODO - public void SetWazaRecordFlag(byte recordIndex, bool set) { } + public void SetDef(ushort def) + { + unsafe + { + fixed (byte* addr = m_pCalcData) + { + var calc = GetCalcData(addr, true); + calc->def = def; + } + } + } - // TODO - public void ClearWazaRecordFlag() { } + public void SetSpAtk(ushort spatk) + { + unsafe + { + fixed (byte* addr = m_pCalcData) + { + var calc = GetCalcData(addr, true); + calc->spatk = spatk; + } + } + } - // TODO - public ulong GetBankUniqueID() { return 0; } + public void SetSpDef(ushort spdef) + { + unsafe + { + fixed (byte* addr = m_pCalcData) + { + var calc = GetCalcData(addr, true); + calc->spdef = spdef; + } + } + } - // TODO - public void SetBankUniqueID(ulong value) { } + public void SetAgi(ushort agi) + { + unsafe + { + fixed (byte* addr = m_pCalcData) + { + var calc = GetCalcData(addr, true); + calc->agi = agi; + } + } + } - // TODO - public void ClearBankUniqueID() { } + public void SetGState(GState state) + { + unsafe + { + fixed (byte* addr = m_pCalcData) + { + var calc = GetCalcData(addr, true); + calc->gState = (byte)state; + } + } + } - // TODO - public void SetPokeJobFlag(byte jobIndex, bool set) { } + // ============================================= + // Infrastructure + // ============================================= - // TODO - public void ClearPokeJobFlag() { } + private unsafe CalcData* GetCalcData(byte* _addr, bool forWrite) + { + return (CalcData*)_addr; + } - // TODO - public void SetCampFriendship(byte value) { } + private unsafe CoreDataBlockA* GetCoreDataBlockA(byte* _addr, bool forWrite) + { + if (!m_accessState.isFastMode) + { + if (forWrite) + DecodeAndCheckIllegalWrite(); + else + DecodeAndCheckIllegalWrite(); + } + + var header = GetCoreDataHeader(_addr); + byte pos = GetCoreDataBlockPos(header->personalRnd, CoreDataBlockId.A); + byte* blockStart = _addr + CoreDataHeader.SIZE + pos * CoreData.CORE_DATA_BLOCK_SIZE; + + if (!m_accessState.isFastMode && !forWrite) + UpdateChecksumAndEncode(); + + return (CoreDataBlockA*)blockStart; + } - // TODO - public void SetPalma(uint value) { } + private unsafe CoreDataBlockB* GetCoreDataBlockB(byte* _addr, bool forWrite) + { + if (!m_accessState.isFastMode) + { + if (forWrite) + DecodeAndCheckIllegalWrite(); + else + DecodeAndCheckIllegalWrite(); + } + + var header = GetCoreDataHeader(_addr); + byte pos = GetCoreDataBlockPos(header->personalRnd, CoreDataBlockId.B); + byte* blockStart = _addr + CoreDataHeader.SIZE + pos * CoreData.CORE_DATA_BLOCK_SIZE; + + if (!m_accessState.isFastMode && !forWrite) + UpdateChecksumAndEncode(); + + return (CoreDataBlockB*)blockStart; + } - // TODO - public void SetTalentHeight(byte value) { } + private unsafe CoreDataBlockC* GetCoreDataBlockC(byte* _addr, bool forWrite) + { + if (!m_accessState.isFastMode) + { + if (forWrite) + DecodeAndCheckIllegalWrite(); + else + DecodeAndCheckIllegalWrite(); + } + + var header = GetCoreDataHeader(_addr); + byte pos = GetCoreDataBlockPos(header->personalRnd, CoreDataBlockId.C); + byte* blockStart = _addr + CoreDataHeader.SIZE + pos * CoreData.CORE_DATA_BLOCK_SIZE; + + if (!m_accessState.isFastMode && !forWrite) + UpdateChecksumAndEncode(); + + return (CoreDataBlockC*)blockStart; + } - // TODO - public void SetTalentWeight(byte value) { } + private unsafe CoreDataBlockD* GetCoreDataBlockD(byte* _addr, bool forWrite) + { + if (!m_accessState.isFastMode) + { + if (forWrite) + DecodeAndCheckIllegalWrite(); + else + DecodeAndCheckIllegalWrite(); + } + + var header = GetCoreDataHeader(_addr); + byte pos = GetCoreDataBlockPos(header->personalRnd, CoreDataBlockId.D); + byte* blockStart = _addr + CoreDataHeader.SIZE + pos * CoreData.CORE_DATA_BLOCK_SIZE; + + if (!m_accessState.isFastMode && !forWrite) + UpdateChecksumAndEncode(); + + return (CoreDataBlockD*)blockStart; + } - // TODO - public void SetBattleRomMark(byte value) { } + protected unsafe static CoreDataHeader* GetCoreDataHeader(byte* addr) + { + return (CoreDataHeader*)addr; + } - // TODO - public void RemoveAllRibbon() { } + private unsafe static byte GetCoreDataBlockPos(uint key, CoreDataBlockId blockId) + { + uint index = (key >> 13) & 0x1F; + return BLOCK_POS_TABLE[index][(int)blockId]; + } - // TODO - private unsafe CalcData* GetCalcData(byte* _addr, bool forWrite) { return default; } + private void UpdateChecksumAndEncode() + { + if (m_accessState.isEncoded || m_accessState.isFastMode) + return; - // TODO - private unsafe CoreDataBlockA* GetCoreDataBlockA(byte* _addr, bool forWrite) { return default; } + updateChecksumAndEncode_Core(m_pCoreData); - // TODO - private unsafe CoreDataBlockB* GetCoreDataBlockB(byte* _addr, bool forWrite) { return default; } + if (m_pCalcData != null) + updateChecksumAndEncode_Calc(m_pCoreData, m_pCalcData); - // TODO - private unsafe CoreDataBlockC* GetCoreDataBlockC(byte* _addr, bool forWrite) { return default; } + m_accessState.isEncoded = true; + } - // TODO - private unsafe CoreDataBlockD* GetCoreDataBlockD(byte* _addr, bool forWrite) { return default; } + public static void updateChecksumAndEncode_Core(byte[] pCoreData) + { + unsafe + { + fixed (byte* addr = pCoreData) + { + var header = GetCoreDataHeader(addr); + uint personalRnd = header->personalRnd; - // TODO - protected unsafe static CoreDataHeader* GetCoreDataHeader(byte* addr) { return null; } + byte* blocksStart = addr + CoreDataHeader.SIZE; + uint blocksSize = CORE_DATA_SIZE - CoreDataHeader.SIZE; - // TODO - private unsafe static byte GetCoreDataBlockPos(uint key, CoreDataBlockId blockId) { return default; } + header->checksum = Encoder.CalcChecksum(blocksStart, blocksSize); - // TODO - private void UpdateChecksumAndEncode() { } + Encoder.Encode(blocksStart, blocksSize, personalRnd); + } + } + } - // TODO - public static void updateChecksumAndEncode_Core(byte[] pCoreData) { } + private static void updateChecksumAndEncode_Calc(byte[] pCoreData, byte[] pCalcData) + { + unsafe + { + fixed (byte* coreAddr = pCoreData) + fixed (byte* calcAddr = pCalcData) + { + var header = GetCoreDataHeader(coreAddr); + uint personalRnd = header->personalRnd; + + Encoder.Encode(calcAddr, CALC_DATA_SIZE, personalRnd); + } + } + } - // TODO - private static void updateChecksumAndEncode_Calc(byte[] pCoreData, byte[] pCalcData) { } + private void DecodeAndCheckIllegalWrite() + { + if (!m_accessState.isEncoded) + return; + + unsafe + { + fixed (byte* addr = m_pCoreData) + { + var header = GetCoreDataHeader(addr); + uint personalRnd = header->personalRnd; + + byte* blocksStart = addr + CoreDataHeader.SIZE; + uint blocksSize = CORE_DATA_SIZE - CoreDataHeader.SIZE; + + Encoder.Decode(blocksStart, blocksSize, personalRnd); + } + + if (m_pCalcData != null) + { + fixed (byte* calcAddr = m_pCalcData) + { + fixed (byte* coreAddr = m_pCoreData) + { + var header = GetCoreDataHeader(coreAddr); + Encoder.Decode(calcAddr, CALC_DATA_SIZE, header->personalRnd); + } + } + } + } + + m_accessState.isEncoded = false; + } - // TODO - private void DecodeAndCheckIllegalWrite() { } + private unsafe void Serialize(void* bufferForCore, void* bufferForCalc) + { + if (!m_accessState.isEncoded) + UpdateChecksumAndEncode(); + + fixed (byte* src = m_pCoreData) + { + Buffer.MemoryCopy(src, bufferForCore, CORE_DATA_SIZE, CORE_DATA_SIZE); + } + + if (bufferForCalc != null && m_pCalcData != null) + { + fixed (byte* src = m_pCalcData) + { + Buffer.MemoryCopy(src, bufferForCalc, CALC_DATA_SIZE, CALC_DATA_SIZE); + } + } + } - // TODO - private unsafe void Serialize(void* bufferForCore, void* bufferForCalc) { } + private unsafe void Deserialize(void* serializedCoreData, void* serializedCalcData) + { + fixed (byte* dst = m_pCoreData) + { + Buffer.MemoryCopy(serializedCoreData, dst, CORE_DATA_SIZE, CORE_DATA_SIZE); + } + + if (serializedCalcData != null && m_pCalcData != null) + { + fixed (byte* dst = m_pCalcData) + { + Buffer.MemoryCopy(serializedCalcData, dst, CALC_DATA_SIZE, CALC_DATA_SIZE); + } + } + + m_accessState.isEncoded = true; + m_accessState.isFastMode = false; + DecodeAndCheckIllegalWrite(); + UpdateChecksumAndEncode(); + } - // TODO - private unsafe void Deserialize(void* serializedCoreData, void* serializedCalcData) { } + private unsafe void copyString(char* dst, string _src, int dst_len) + { + int len = Math.Min(_src.Length, dst_len - 1); + for (int i = 0; i < len; i++) + dst[i] = _src[i]; + for (int i = len; i < dst_len; i++) + dst[i] = '\0'; + } - // TODO private static void CalcWazaRecordBitPos(out byte arrayIndex, out byte bitFlag, byte recordIndex) { - arrayIndex = 0; - bitFlag = 0; + arrayIndex = (byte)(recordIndex / 8); + bitFlag = (byte)(1 << (recordIndex % 8)); } - // TODO private static void CalcPokeJobBitPos(out byte arrayIndex, out byte bitFlag, byte jobIndex) { - arrayIndex = 0; - bitFlag = 0; + arrayIndex = (byte)(jobIndex / 8); + bitFlag = (byte)(1 << (jobIndex % 8)); } private struct AccessState { - public bool isEncoded; + public bool isEncoded; public bool isFastMode; } } diff --git a/Assets/Scripts/Pml/PokePara/BoxMarkController.cs b/Assets/Scripts/Pml/PokePara/BoxMarkController.cs index b06660496..e40b89619 100644 --- a/Assets/Scripts/Pml/PokePara/BoxMarkController.cs +++ b/Assets/Scripts/Pml/PokePara/BoxMarkController.cs @@ -5,10 +5,17 @@ public static class BoxMarkController private const ushort BOXMARK_UNIT_MASK = 3; private const ushort BOXMARK_UNIT_BIT_COUNT = 2; - // TODO - public static BoxMarkColor GetBoxMarkColor(ushort value, BoxMark mark) { return default; } - - // TODO - public static ushort SetBoxMarkColor(ushort value, BoxMark mark, BoxMarkColor color) { return default; } + public static BoxMarkColor GetBoxMarkColor(ushort value, BoxMark mark) + { + int shift = (int)mark * BOXMARK_UNIT_BIT_COUNT; + return (BoxMarkColor)((value >> shift) & BOXMARK_UNIT_MASK); + } + + public static ushort SetBoxMarkColor(ushort value, BoxMark mark, BoxMarkColor color) + { + int shift = (int)mark * BOXMARK_UNIT_BIT_COUNT; + ushort mask = (ushort)(BOXMARK_UNIT_MASK << shift); + return (ushort)((value & ~mask) | (((ushort)color & BOXMARK_UNIT_MASK) << shift)); + } } } \ No newline at end of file diff --git a/Assets/Scripts/Pml/PokePara/CalcTool.cs b/Assets/Scripts/Pml/PokePara/CalcTool.cs index 030f8d1f9..4dd1c8b0b 100644 --- a/Assets/Scripts/Pml/PokePara/CalcTool.cs +++ b/Assets/Scripts/Pml/PokePara/CalcTool.cs @@ -1,4 +1,6 @@ -namespace Pml.PokePara +using Pml.Personal; + +namespace Pml.PokePara { public static class CalcTool { @@ -154,44 +156,54 @@ public static class CalcTool new ITEM_VIEW_PARAM(ItemNo.RIBONAMEZAIKU, Cream2ViewID.RIBBON), }; - // TODO - public static byte CalcLevel(MonsNo monsno, ushort formno, uint exp) { return 0; } + public static byte CalcLevel(MonsNo monsno, ushort formno, uint exp) + { + var growTable = Personal.PersonalSystem.GetGrowTable(monsno, formno); + byte level = PmlConstants.MIN_POKE_LEVEL; + for (byte i = PmlConstants.MIN_POKE_LEVEL; i <= MAX_POKE_LEVEL; i++) + { + if (growTable.GetMinExp(i) > exp) + break; + level = i; + } + return level; + } public static ushort CalcMaxHp(MonsNo monsno, byte level, ushort basev, ushort rnd, ushort exp) { if (monsno == MonsNo.NUKENIN) return 1; - return (ushort)((short)((basev * 2u + rnd + exp / 4u * level) / 100u) + (ushort)level + 10u); + return (ushort)((basev * 2u + rnd + exp / 4u) * level / 100u + level + 10u); } public static ushort CalcAtk(byte level, ushort basev, ushort rnd, ushort exp, Seikaku seikaku) { - var calcv = (ushort)((short)((basev * 2u + rnd + exp / 4u * level) / 100u) + 5u); + var calcv = (ushort)((basev * 2u + rnd + exp / 4u) * level / 100u + 5u); return CalcCorrectedPowerBySeikaku(calcv, (ushort)seikaku, PowerID.ATK); } public static ushort CalcDef(byte level, ushort basev, ushort rnd, ushort exp, Seikaku seikaku) { - var calcv = (ushort)((short)((basev * 2u + rnd + exp / 4u * level) / 100u) + 5u); + var calcv = (ushort)((basev * 2u + rnd + exp / 4u) * level / 100u + 5u); return CalcCorrectedPowerBySeikaku(calcv, (ushort)seikaku, PowerID.DEF); } public static ushort CalcSpAtk(byte level, ushort basev, ushort rnd, ushort exp, Seikaku seikaku) { - var calcv = (ushort)((short)((basev * 2u + rnd + exp / 4u * level) / 100u) + 5u); + var calcv = (ushort)((basev * 2u + rnd + exp / 4u) * level / 100u + 5u); return CalcCorrectedPowerBySeikaku(calcv, (ushort)seikaku, PowerID.SPATK); } public static ushort CalcSpDef(byte level, ushort basev, ushort rnd, ushort exp, Seikaku seikaku) { - var calcv = (ushort)((short)((basev * 2u + rnd + exp / 4u * level) / 100u) + 5u); + var calcv = (ushort)((basev * 2u + rnd + exp / 4u) * level / 100u + 5u); return CalcCorrectedPowerBySeikaku(calcv, (ushort)seikaku, PowerID.SPDEF); } public static ushort CalcAgi(byte level, ushort basev, ushort rnd, ushort exp, Seikaku seikaku) { - var calcv = (ushort)((short)((basev * 2u + rnd + exp / 4u * level) / 100u) + 5u); + var calcv = (ushort)((basev * 2u + rnd + exp / 4u) * level / 100u + 5u); return CalcCorrectedPowerBySeikaku(calcv, (ushort)seikaku, PowerID.AGI); } @@ -237,14 +249,30 @@ private static uint CalcRareCheckValue(uint id, uint rnd) return (id & 0xFFFF) ^ (id >> 0x10) ^ (rnd >> 0x10) ^ (rnd & 0xFFFF); } - // TODO - public static uint CorrectColorRndForNormal(uint id, uint rnd) { return 0; } + public static uint CorrectColorRndForNormal(uint id, uint rnd) + { + if (IsRareColor(id, rnd)) + rnd ^= 0x10000000; + return rnd; + } - // TODO - public static uint CorrectColorRndForRare(uint id, uint rnd) { return 0; } + public static uint CorrectColorRndForRare(uint id, uint rnd) + { + if (!IsRareColor(id, rnd)) + { + uint upper = (id >> 0x10) ^ id ^ rnd; + rnd = (rnd & 0xFFFF) | (upper << 0x10); + } + return rnd; + } - // TODO - public static RareType CalcRareColorType(uint id, uint rnd, uint cassetVersion, bool isEventGetPoke) { return RareType.NOT_RARE; } + public static RareType CalcRareColorType(uint id, uint rnd, uint cassetVersion, bool isEventGetPoke) + { + var rareType = CalcRareColorTypeByID(id, rnd); + if ((cassetVersion == VERSION_HOLOHOLO || isEventGetPoke) && rareType != RareType.NOT_RARE) + return RareType.DISTRIBUTED; + return rareType; + } public static RareType CalcRareColorTypeByID(uint id, uint rnd) { @@ -256,70 +284,192 @@ public static RareType CalcRareColorTypeByID(uint id, uint rnd) return RareType.CAPTURED; } - // TODO - public static uint CorrectColorRndForRareType(uint id, uint rnd, RareType type) { return 0; } + public static uint CorrectColorRndForRareType(uint id, uint rnd, RareType type) + { + if (type != RareType.NOT_RARE) + { + uint upper = (id ^ (id >> 0x10) ^ rnd ^ (type == RareType.CAPTURED ? 1u : 0u)) << 0x10; + return (rnd & 0xFFFF) | upper; + } + return CorrectColorRndForNormal(id, rnd); + } - // TODO - public static Sex GetCorrectSexInPersonalData(MonsNo monsno, ushort formno, Sex bothCase) { return Sex.MALE; } + public static Sex GetCorrectSexInPersonalData(MonsNo monsno, ushort formno, Sex bothCase) + { + var sexVector = (SexVector)Personal.PersonalSystem.GetPersonalData(monsno, formno).GetParam(Personal.ParamID.SEX); + switch (sexVector) + { + case SexVector.ONLY_MALE: + return Sex.MALE; + case SexVector.ONLY_FEMALE: + return Sex.FEMALE; + case SexVector.UNKNOWN: + return Sex.UNKNOWN; + default: + return bothCase; + } + } - // TODO - public static bool IsSeikakuHigh(Seikaku seikaku) { return false; } + public static bool IsSeikakuHigh(Seikaku seikaku) + { + for (int i = 0; i < HIGH_SEIKAKU.Length; i++) + { + if (HIGH_SEIKAKU[i] == seikaku) + return true; + } + return false; + } - // TODO - public static bool IsSeikakuLow(Seikaku seikaku) { return false; } + public static bool IsSeikakuLow(Seikaku seikaku) + { + for (int i = 0; i < LOW_SEIKAKU.Length; i++) + { + if (LOW_SEIKAKU[i] == seikaku) + return true; + } + return false; + } - // TODO public static Seikaku[] GetSeikakuHigh(out byte pNum) { - pNum = 0; - return null; + pNum = (byte)HIGH_SEIKAKU.Length; + return HIGH_SEIKAKU; } - // TODO public static Seikaku[] GetSeikakuLow(out byte pNum) { - pNum = 0; - return null; + pNum = (byte)LOW_SEIKAKU.Length; + return LOW_SEIKAKU; } - // TODO - public static ushort GetTokuseiNo(MonsNo monsno, ushort formno, byte tokuseiIndex) { return 0; } + public static ushort GetTokuseiNo(MonsNo monsno, ushort formno, byte tokuseiIndex) + { + Personal.ParamID paramID; + if (tokuseiIndex < 3) + paramID = (Personal.ParamID)((int)Personal.ParamID.TOKUSEI1 + tokuseiIndex); + else + paramID = Personal.ParamID.TOKUSEI1; + return (ushort)Personal.PersonalSystem.GetPersonalData(monsno, formno).GetParam(paramID); + } - // TODO - public static PokeType CalcMezamerupawaaType(byte hp, byte atk, byte def, byte agi, byte spatk, byte spdef) { return PokeType.NORMAL; } + public static PokeType CalcMezamerupawaaType(byte hp, byte atk, byte def, byte agi, byte spatk, byte spdef) + { + uint val = (uint)((hp & 1) | ((atk & 1) << 1) | ((def & 1) << 2) | ((agi & 1) << 3) | ((spatk & 1) << 4) | ((spdef & 1) << 5)); + uint typeIndex = val * 15 / 63; + return TYPE_TABLE[typeIndex]; + } - // TODO - public static uint CalcMezamerupawaaPower(byte hp, byte atk, byte def, byte agi, byte spatk, byte spdef) { return 0; } + public static uint CalcMezamerupawaaPower(byte hp, byte atk, byte def, byte agi, byte spatk, byte spdef) + { + uint val = (uint)(((hp >> 1) & 1) | (((atk >> 1) & 1) << 1) | (((def >> 1) & 1) << 2) | (((agi >> 1) & 1) << 3) | (((spatk >> 1) & 1) << 4) | (((spdef >> 1) & 1) << 5)); + return val * 40 / 63 + 30; + } - // TODO - public static TasteJudge JudgeTaste(Seikaku seikaku, Taste taste) { return TasteJudge.NORMAL; } + public static TasteJudge JudgeTaste(Seikaku seikaku, Taste taste) + { + return DESIRED_TASTE_TBL[(int)seikaku, (int)taste]; + } + + public static bool CanCreateEgg(MonsNo monsno1, Sex sex1, uint eggGroup1_1, uint eggGroup1_2, MonsNo monsno2, Sex sex2, uint eggGroup2_1, uint eggGroup2_2) + { + if (eggGroup1_1 == (uint)Personal.EggGroup.MUSEISYOKU && eggGroup1_2 == (uint)Personal.EggGroup.MUSEISYOKU) + return false; + if (eggGroup2_1 == (uint)Personal.EggGroup.MUSEISYOKU && eggGroup2_2 == (uint)Personal.EggGroup.MUSEISYOKU) + return false; - // TODO - public static bool CanCreateEgg(MonsNo monsno1, Sex sex1, uint eggGroup1_1, uint eggGroup1_2, MonsNo monsno2, Sex sex2, uint eggGroup2_1, uint eggGroup2_2) { return false; } + bool mon1IsMetamon = (eggGroup1_1 == (uint)Personal.EggGroup.METAMON || eggGroup1_2 == (uint)Personal.EggGroup.METAMON); + bool mon2IsMetamon = (eggGroup2_1 == (uint)Personal.EggGroup.METAMON || eggGroup2_2 == (uint)Personal.EggGroup.METAMON); - // TODO - public static LoveLevel CalcLoveLevel(MonsNo monsno1, uint id1, MonsNo monsno2, uint id2) { return LoveLevel.GOOD; } + if (mon1IsMetamon && mon2IsMetamon) + return false; - // TODO - public static WazaNo GetRotomuWazaNo(ushort formno) { return WazaNo.NULL; } + if (mon1IsMetamon || mon2IsMetamon) + return true; - // TODO - public static PokeType GetAruseusuType(uint itemno) { return PokeType.NORMAL; } + if (sex1 == sex2) + return false; - // TODO - public static PokeType GetGuripusu2Type(uint itemno) { return PokeType.NORMAL; } + if (sex1 == Sex.UNKNOWN || sex2 == Sex.UNKNOWN) + return false; - // TODO - public static bool IsAmezaikuForCream2Evolution(uint itemno) { return false; } + if (eggGroup1_1 == eggGroup2_1 || eggGroup1_1 == eggGroup2_2 || + eggGroup1_2 == eggGroup2_1 || eggGroup1_2 == eggGroup2_2) + return true; + + return false; + } - // TODO - public static Cream2ViewID GetCream2ViewID(uint itemno) { return Cream2ViewID.STRAWBERRY; } + public static LoveLevel CalcLoveLevel(MonsNo monsno1, uint id1, MonsNo monsno2, uint id2) + { + if (monsno1 == monsno2) + return (id1 == id2) ? LoveLevel.NORMAL : LoveLevel.GOOD; + return (id1 == id2) ? LoveLevel.BAD : LoveLevel.NORMAL; + } + + public static WazaNo GetRotomuWazaNo(ushort formno) + { + if (formno < ROTOM_WAZA_TBL.Length) + return ROTOM_WAZA_TBL[formno]; + return WazaNo.NULL; + } + + public static PokeType GetAruseusuType(uint itemno) + { + for (int i = 0; i < ITEM_TYPE_ARUSEUSU.Length; i++) + { + if ((uint)ITEM_TYPE_ARUSEUSU[i].item == itemno) + return ITEM_TYPE_ARUSEUSU[i].type; + } + return PokeType.NORMAL; + } + + public static PokeType GetGuripusu2Type(uint itemno) + { + for (int i = 0; i < ITEM_TYPE_Guripusu2.Length; i++) + { + if ((uint)ITEM_TYPE_Guripusu2[i].item == itemno) + return ITEM_TYPE_Guripusu2[i].type; + } + return PokeType.NORMAL; + } + + public static bool IsAmezaikuForCream2Evolution(uint itemno) + { + for (int i = 0; i < CREAM2_ITEM_TABLE.Length; i++) + { + if ((uint)CREAM2_ITEM_TABLE[i].item == itemno) + return true; + } + return false; + } + + public static Cream2ViewID GetCream2ViewID(uint itemno) + { + for (int i = 0; i < CREAM2_ITEM_TABLE.Length; i++) + { + if ((uint)CREAM2_ITEM_TABLE[i].item == itemno) + return CREAM2_ITEM_TABLE[i].viewID; + } + return Cream2ViewID.STRAWBERRY; + } - // TODO public static bool DecideFormNoFromHoldItem(MonsNo monsno, uint holdItemno, out ushort formno) { formno = 0; - return false; + + if (monsno == MonsNo.GIRATHINA) + { + formno = (ushort)(holdItemno == (uint)ItemNo.HAKKINDAMA ? 1 : 0); + } + else if (monsno == MonsNo.ARUSEUSU) + { + formno = (ushort)(byte)GetAruseusuType(holdItemno); + } + else + { + return false; + } + return true; } private struct ITEM_TYPE_PARAM diff --git a/Assets/Scripts/Pml/PokePara/CoreDataBlockA.cs b/Assets/Scripts/Pml/PokePara/CoreDataBlockA.cs index 828260763..e2c745969 100644 --- a/Assets/Scripts/Pml/PokePara/CoreDataBlockA.cs +++ b/Assets/Scripts/Pml/PokePara/CoreDataBlockA.cs @@ -74,37 +74,70 @@ public struct CoreDataBlockA private const int bitsD0_loc = 0; private const int bitsD0_mask = 1; - // TODO - public bool tokusei1Flag { get; set; } - - // TODO - public bool tokusei2Flag { get; set; } - - // TODO - public bool tokusei3Flag { get; set; } - - // TODO - public bool favoriteFlag { get; set; } - - // TODO - public bool special_g_flag { get; set; } - - // TODO - public bool debug_edit_flag { get; set; } - - // TODO - public bool eventGetFlag { get; set; } - - // TODO - public bool officialBattleEnableFlag { get; set; } - - // TODO - public byte sex { get; set; } - - // TODO - public uint camp_friendship { get; set; } - - // TODO - public bool dpr_illegal_flag { get; set; } + public bool tokusei1Flag + { + get => (_bitsA >> bitsA0_loc & bitsA0_sz) != 0; + set => _bitsA = (ushort)((_bitsA & ~bitsA0_mask) | (value ? bitsA0_mask : 0)); + } + + public bool tokusei2Flag + { + get => (_bitsA >> bitsA1_loc & bitsA1_sz) != 0; + set => _bitsA = (ushort)((_bitsA & ~bitsA1_mask) | (value ? bitsA1_mask : 0)); + } + + public bool tokusei3Flag + { + get => (_bitsA >> bitsA2_loc & bitsA2_sz) != 0; + set => _bitsA = (ushort)((_bitsA & ~bitsA2_mask) | (value ? bitsA2_mask : 0)); + } + + public bool favoriteFlag + { + get => (_bitsA >> bitsA3_loc & bitsA3_sz) != 0; + set => _bitsA = (ushort)((_bitsA & ~bitsA3_mask) | (value ? bitsA3_mask : 0)); + } + + public bool special_g_flag + { + get => (_bitsA >> bitsA4_loc & bitsA4_sz) != 0; + set => _bitsA = (ushort)((_bitsA & ~bitsA4_mask) | (value ? bitsA4_mask : 0)); + } + + public bool debug_edit_flag + { + get => (_bitsA >> bitsA5_loc & bitsA5_sz) != 0; + set => _bitsA = (ushort)((_bitsA & ~bitsA5_mask) | (value ? bitsA5_mask : 0)); + } + + public bool eventGetFlag + { + get => (_bitsB >> bitsB0_loc & bitsB0_sz) != 0; + set => _bitsB = (byte)((_bitsB & ~bitsB0_mask) | (value ? bitsB0_mask : 0)); + } + + public bool officialBattleEnableFlag + { + get => (_bitsB >> bitsB1_loc & bitsB1_sz) != 0; + set => _bitsB = (byte)((_bitsB & ~bitsB1_mask) | (value ? bitsB1_mask : 0)); + } + + public byte sex + { + get => (byte)((_bitsB & bitsB2_mask) >> bitsB2_loc); + set => _bitsB = (byte)((_bitsB & ~bitsB2_mask) | ((value << bitsB2_loc) & bitsB2_mask)); + } + + public uint camp_friendship + { + get => (uint)((_bitsC & (uint)bitsC0_mask) >> bitsC0_loc); + set => _bitsC = (uint)((_bitsC & ~(uint)bitsC0_mask) | ((value << bitsC0_loc) & (uint)bitsC0_mask)); + } + + public bool dpr_illegal_flag + { + get => (_bitsD >> bitsD0_loc & bitsD0_sz) != 0; + set => _bitsD = (byte)((_bitsD & ~bitsD0_mask) | (value ? bitsD0_mask : 0)); + } } } \ No newline at end of file diff --git a/Assets/Scripts/Pml/PokePara/CoreDataBlockB.cs b/Assets/Scripts/Pml/PokePara/CoreDataBlockB.cs index 2e0f81af5..cb0d64c78 100644 --- a/Assets/Scripts/Pml/PokePara/CoreDataBlockB.cs +++ b/Assets/Scripts/Pml/PokePara/CoreDataBlockB.cs @@ -39,28 +39,52 @@ public struct CoreDataBlockB private const int bitsA6_mask = 1073741824; private const int bitsA7_mask = -2147483648; - // TODO - public uint talentHp { get; set; } - - // TODO - public uint talentAtk { get; set; } - - // TODO - public uint talentDef { get; set; } - - // TODO - public uint talentAgi { get; set; } - - // TODO - public uint talentSpatk { get; set; } - - // TODO - public uint talentSpdef { get; set; } - - // TODO - public bool tamagoFlag { get; set; } - - // TODO - public bool nicknameFlag { get; set; } + public uint talentHp + { + get => (uint)((_bitsA & (uint)bitsA0_mask) >> bitsA0_loc); + set => _bitsA = (uint)((_bitsA & ~(uint)bitsA0_mask) | ((value << bitsA0_loc) & (uint)bitsA0_mask)); + } + + public uint talentAtk + { + get => (uint)((_bitsA & (uint)bitsA1_mask) >> bitsA1_loc); + set => _bitsA = (uint)((_bitsA & ~(uint)bitsA1_mask) | ((value << bitsA1_loc) & (uint)bitsA1_mask)); + } + + public uint talentDef + { + get => (uint)((_bitsA & (uint)bitsA2_mask) >> bitsA2_loc); + set => _bitsA = (uint)((_bitsA & ~(uint)bitsA2_mask) | ((value << bitsA2_loc) & (uint)bitsA2_mask)); + } + + public uint talentAgi + { + get => (uint)((_bitsA & (uint)bitsA3_mask) >> bitsA3_loc); + set => _bitsA = (uint)((_bitsA & ~(uint)bitsA3_mask) | ((value << bitsA3_loc) & (uint)bitsA3_mask)); + } + + public uint talentSpatk + { + get => (uint)((_bitsA & (uint)bitsA4_mask) >> bitsA4_loc); + set => _bitsA = (uint)((_bitsA & ~(uint)bitsA4_mask) | ((value << bitsA4_loc) & (uint)bitsA4_mask)); + } + + public uint talentSpdef + { + get => (uint)((_bitsA & (uint)bitsA5_mask) >> bitsA5_loc); + set => _bitsA = (uint)((_bitsA & ~(uint)bitsA5_mask) | ((value << bitsA5_loc) & (uint)bitsA5_mask)); + } + + public bool tamagoFlag + { + get => (_bitsA & (uint)bitsA6_mask) != 0; + set => _bitsA = (uint)((_bitsA & ~(uint)bitsA6_mask) | (value ? (uint)bitsA6_mask : 0)); + } + + public bool nicknameFlag + { + get => (_bitsA & unchecked((uint)bitsA7_mask)) != 0; + set => _bitsA = (uint)((_bitsA & ~unchecked((uint)bitsA7_mask)) | (value ? unchecked((uint)bitsA7_mask) : 0)); + } } } \ No newline at end of file diff --git a/Assets/Scripts/Pml/PokePara/CoreDataBlockD.cs b/Assets/Scripts/Pml/PokePara/CoreDataBlockD.cs index 11a7ba868..000790ef5 100644 --- a/Assets/Scripts/Pml/PokePara/CoreDataBlockD.cs +++ b/Assets/Scripts/Pml/PokePara/CoreDataBlockD.cs @@ -33,10 +33,16 @@ public struct CoreDataBlockD private const int bitsA0_mask = 127; private const int bitsA1_mask = 128; - // TODO - public byte getLevel { get; set; } - - // TODO - public byte parentsSex { get; set; } + public byte getLevel + { + get => (byte)((_bitsA & bitsA0_mask) >> bitsA0_loc); + set => _bitsA = (byte)((_bitsA & ~bitsA0_mask) | ((value << bitsA0_loc) & bitsA0_mask)); + } + + public byte parentsSex + { + get => (byte)((_bitsA & bitsA1_mask) >> bitsA1_loc); + set => _bitsA = (byte)((_bitsA & ~bitsA1_mask) | ((value << bitsA1_loc) & bitsA1_mask)); + } } } \ No newline at end of file diff --git a/Assets/Scripts/Pml/PokePara/CoreParam.cs b/Assets/Scripts/Pml/PokePara/CoreParam.cs index 52e1af06d..85a6b12a5 100644 --- a/Assets/Scripts/Pml/PokePara/CoreParam.cs +++ b/Assets/Scripts/Pml/PokePara/CoreParam.cs @@ -1,4 +1,4 @@ -using Pml.Personal; +using Pml.Personal; using Pml.WazaData; using System; using System.Collections.Generic; @@ -79,7 +79,7 @@ public uint GetMaxHp() if (HaveCalcParam()) return m_accessor.GetMaxHp(); - return CalcMaxHp(); + return CalcMaxHp_NotG(); } public uint GetHp() @@ -87,7 +87,7 @@ public uint GetHp() if (HaveCalcParam()) return m_accessor.GetHp(); - return CalcMaxHp(); + return CalcMaxHp_NotG(); } public void SetHp(uint value) @@ -106,23 +106,26 @@ public void ReduceHp(uint value) public void ReduceNowHp(uint value) { - var max = m_accessor.GetMaxHp(); - var curr = m_accessor.GetHp(); + uint result = m_accessor.GetMaxHp(); + uint curr = m_accessor.GetHp(); - var newhp = (ushort)((curr - value <= max) ? (curr - value) : max); - newhp = (ushort)((curr <= value) ? 0 : newhp); + if (curr - value <= result) + result = curr - value; + if (curr <= value) + result = 0; - m_accessor.SetHp(newhp); + m_accessor.SetHp((ushort)result); } public void RecoverHp(uint value) { - var max = m_accessor.GetMaxHp(); - var curr = m_accessor.GetHp(); + uint result = m_accessor.GetMaxHp(); + uint curr = m_accessor.GetHp(); - var newhp = (ushort)((curr + value <= max) ? (curr + value) : max); + if ((uint)(curr + value) <= result) + result = curr + value; - m_accessor.SetHp(newhp); + m_accessor.SetHp((ushort)result); } public void RecoverHpFull() @@ -216,44 +219,192 @@ public uint GetExp() return m_accessor.GetExp(); } - // TODO - public void SetExp(uint value) { } + public void SetExp(uint value) + { + PersonalSystem.LoadGrowTable(GetMonsNo(), GetFormNo()); + var maxExp = PersonalSystem.GetMinExp(PmlConstants.MAX_POKE_LEVEL); + if (value > maxExp) + value = maxExp; + m_accessor.SetExp(value); + if (HaveCalcParam()) + UpdateCalcDatas(); + } - // TODO - public void AddExp(uint value) { } + public void AddExp(uint value) + { + SetExp(GetExp() + value); + } - // TODO - public uint GetExpForCurrentLevel() { return 0; } + public uint GetExpForCurrentLevel() + { + PersonalSystem.LoadGrowTable(GetMonsNo(), GetFormNo()); + return PersonalSystem.GetMinExp((byte)GetLevel()); + } + + public uint GetExpForNextLevel() + { + var level = GetLevel(); + if (level >= PmlConstants.MAX_POKE_LEVEL) + return GetExp(); + + PersonalSystem.LoadGrowTable(GetMonsNo(), GetFormNo()); + return PersonalSystem.GetMinExp((byte)(level + 1)); + } - // TODO - public uint GetExpForNextLevel() { return 0; } + public void LevelUp(byte upVal) + { + var level = GetLevel(); + var newLevel = level + upVal; + if (newLevel > PmlConstants.MAX_POKE_LEVEL) + newLevel = PmlConstants.MAX_POKE_LEVEL; + + PersonalSystem.LoadGrowTable(GetMonsNo(), GetFormNo()); + SetExp(PersonalSystem.GetMinExp((byte)newLevel)); + } + + public uint GetBasicPower(PowerID powerID) + { + PersonalSystem.LoadPersonalData(GetMonsNo(), GetFormNo()); + switch (powerID) + { + case PowerID.HP: + return PersonalSystem.GetPersonalParam(ParamID.BASIC_HP); + case PowerID.ATK: + return PersonalSystem.GetPersonalParam(ParamID.BASIC_ATK); + case PowerID.DEF: + return PersonalSystem.GetPersonalParam(ParamID.BASIC_DEF); + case PowerID.SPATK: + return PersonalSystem.GetPersonalParam(ParamID.BASIC_SPATK); + case PowerID.SPDEF: + return PersonalSystem.GetPersonalParam(ParamID.BASIC_SPDEF); + case PowerID.AGI: + return PersonalSystem.GetPersonalParam(ParamID.BASIC_AGI); + default: + GFL.ASSERT(false); + return 0; + } + } - // TODO - public void LevelUp(byte upVal) { } + public uint GetNativeTalentPower(PowerID powerId) + { + switch (powerId) + { + case PowerID.HP: + return m_accessor.GetTalentHp(); + case PowerID.ATK: + return m_accessor.GetTalentAtk(); + case PowerID.DEF: + return m_accessor.GetTalentDef(); + case PowerID.SPATK: + return m_accessor.GetTalentSpAtk(); + case PowerID.SPDEF: + return m_accessor.GetTalentSpDef(); + case PowerID.AGI: + return m_accessor.GetTalentAgi(); + default: + GFL.ASSERT(false); + return 0; + } + } - // TODO - public uint GetBasicPower(PowerID powerID) { return 0; } + public uint GetTalentPower(PowerID powerId) + { + if ((int)powerId < 6) + { + byte flag = m_accessor.GetTrainingFlag(); + if ((flag & (1 << ((int)powerId & 0x1f))) != 0) + return PmlConstants.MAX_TALENT_POWER; + } + return GetNativeTalentPower(powerId); + } - // TODO - public uint GetNativeTalentPower(PowerID powerId) { return 0; } + public void ChangeTalentPower(PowerID powerId, uint value) + { + if (value > PmlConstants.MAX_TALENT_POWER) + value = PmlConstants.MAX_TALENT_POWER; - // TODO - public uint GetTalentPower(PowerID powerId) { return 0; } + switch (powerId) + { + case PowerID.HP: + m_accessor.SetTalentHp((byte)value); + break; + case PowerID.ATK: + m_accessor.SetTalentAtk((byte)value); + break; + case PowerID.DEF: + m_accessor.SetTalentDef((byte)value); + break; + case PowerID.SPATK: + m_accessor.SetTalentSpAtk((byte)value); + break; + case PowerID.SPDEF: + m_accessor.SetTalentSpDef((byte)value); + break; + case PowerID.AGI: + m_accessor.SetTalentAgi((byte)value); + break; + default: + GFL.ASSERT(false); + break; + } - // TODO - public void ChangeTalentPower(PowerID powerId, uint value) { } + if (HaveCalcParam()) + UpdateCalcDatas(); + } - // TODO - public uint GetTalentPowerMaxNum() { return 0; } + public uint GetTalentPowerMaxNum() + { + uint count = 0; + for (int i = 0; i < (int)PowerID.NUM; i++) + { + if (GetTalentPower((PowerID)i) >= PmlConstants.MAX_TALENT_POWER) + count++; + } + return count; + } - // TODO - public bool IsTrainingDone(PowerID powerId) { return false; } + public bool IsTrainingDone(PowerID powerId) + { + byte flag = m_accessor.GetTrainingFlag(); + return (flag & (1 << (int)powerId)) != 0; + } - // TODO - public void SetTrainingDone(PowerID powerId) { } + public void SetTrainingDone(PowerID powerId) + { + if ((int)powerId < 6) + { + byte flag = m_accessor.GetTrainingFlag(); + flag |= (byte)(1 << (int)powerId); + m_accessor.SetTrainingFlag(flag); + UpdateCalcDatas(true); + } + else + { + GFL.ASSERT(false); + } + } - // TODO - public uint GetEffortPower(PowerID powerId) { return 0; } + public uint GetEffortPower(PowerID powerId) + { + switch (powerId) + { + case PowerID.HP: + return m_accessor.GetEffortHp(); + case PowerID.ATK: + return m_accessor.GetEffortAtk(); + case PowerID.DEF: + return m_accessor.GetEffortDef(); + case PowerID.SPATK: + return m_accessor.GetEffortSpAtk(); + case PowerID.SPDEF: + return m_accessor.GetEffortSpDef(); + case PowerID.AGI: + return m_accessor.GetEffortAgi(); + default: + GFL.ASSERT(false); + return 0; + } + } public uint GetTotalEffortPower() { @@ -265,14 +416,49 @@ public uint GetTotalEffortPower() m_accessor.GetEffortAgi(); } - // TODO - public void ChangeEffortPower(PowerID powerId, uint value) { } + public void ChangeEffortPower(PowerID powerId, uint value) + { + value = AdjustEffortPower(GetEffortPower(powerId), value); + + switch (powerId) + { + case PowerID.HP: + m_accessor.SetEffortHp((byte)value); + break; + case PowerID.ATK: + m_accessor.SetEffortAtk((byte)value); + break; + case PowerID.DEF: + m_accessor.SetEffortDef((byte)value); + break; + case PowerID.SPATK: + m_accessor.SetEffortSpAtk((byte)value); + break; + case PowerID.SPDEF: + m_accessor.SetEffortSpDef((byte)value); + break; + case PowerID.AGI: + m_accessor.SetEffortAgi((byte)value); + break; + default: + GFL.ASSERT(false); + break; + } + + if (HaveCalcParam()) + UpdateCalcDatas(); + } - // TODO - public void AddEffortPower(PowerID powerId, uint value) { } + public void AddEffortPower(PowerID powerId, uint value) + { + ChangeEffortPower(powerId, GetEffortPower(powerId) + value); + } - // TODO - public void SubEffortPower(PowerID powerId, uint value) { } + public void SubEffortPower(PowerID powerId, uint value) + { + var current = GetEffortPower(powerId); + ChangeEffortPower(powerId, current >= value ? current - value : 0); + } public GState GetGState() { @@ -302,32 +488,58 @@ public bool IsG() return false; } - // TODO - public void ChangeEffortG(byte value) { } + public void ChangeEffortG(byte value) + { + if (value > PmlConstants.MAX_EFFORT_G) + value = PmlConstants.MAX_EFFORT_G; + m_accessor.SetEffortG(value); + } - // TODO - public byte GetEffortG() { return 0; } + public byte GetEffortG() + { + return (byte)m_accessor.GetEffortG(); + } - // TODO - public void AddEffortG(uint value) { } + public void AddEffortG(uint value) + { + var current = m_accessor.GetEffortG(); + var newval = current + value; + if (newval > PmlConstants.MAX_EFFORT_G) + newval = PmlConstants.MAX_EFFORT_G; + m_accessor.SetEffortG((byte)newval); + } - // TODO - public void SubEffortG(uint value) { } + public void SubEffortG(uint value) + { + var current = m_accessor.GetEffortG(); + m_accessor.SetEffortG((byte)(current >= value ? current - value : 0)); + } - // TODO - public uint GetPower_G(PowerID powerID) { return 0; } + public uint GetPower_G(PowerID powerID) + { + // Gigantamax power calculation not implemented for BDSP + return GetPower(powerID); + } - // TODO - public uint GetPower_NotG(PowerID powerID) { return 0; } + public uint GetPower_NotG(PowerID powerID) + { + return GetPower(powerID); + } - // TODO - public bool IsSpecialGEnable() { return false; } + public bool IsSpecialGEnable() + { + return m_accessor.IsSpecialGEnable(); + } - // TODO - public void SetSpecialGEnable() { } + public void SetSpecialGEnable() + { + m_accessor.SetSpecialGFlag(true); + } - // TODO - public void SetSpecialGDisable() { } + public void SetSpecialGDisable() + { + m_accessor.SetSpecialGFlag(false); + } public MonsNo GetMonsNo() { @@ -339,8 +551,17 @@ public ushort GetFormNo() return m_accessor.GetFormNo(); } - // TODO - public void ChangeMonsNo(MonsNo newMonsno, ushort newFormno) { } + public void ChangeMonsNo(MonsNo newMonsno, ushort newFormno) + { + // TODO: Ghidra shows: early return if monsNo unchanged, sets MonsNo/FormNo, + // recalculates tokusei index (IsTokusei2/3 flags -> CalcTool.GetTokuseiNo), + // corrects sex via CalcTool.GetCorrectSexInPersonalData, + // if no nickname set calls SetDefaultNickName, calls UpdateCalcDatas(keepDead=true) + m_accessor.SetMonsNo((uint)newMonsno); + m_accessor.SetFormNo(newFormno); + if (HaveCalcParam()) + UpdateCalcDatas(); + } public WazaNo GetWazaNo(byte index) { @@ -382,8 +603,30 @@ public byte GetWazaIndex(WazaNo wazano) return 4; } - // TODO - public void SetDefaultWaza() { } + public void SetDefaultWaza() + { + PersonalSystem.LoadWazaOboeData(GetMonsNo(), GetFormNo()); + var oboeNum = PersonalSystem.GetWazaOboeNum(); + + for (byte i = 0; i < PmlConstants.MAX_WAZA_NUM; i++) + { + m_accessor.SetWazaNo(i, (uint)WazaNo.NULL); + m_accessor.SetPP(i, 0); + m_accessor.SetWazaPPUpCount(i, 0); + } + + for (ushort i = 0; i < oboeNum; i++) + { + var level = PersonalSystem.GetWazaOboeLevel(i); + if (level > GetLevel()) + break; + + var wazano = (WazaNo)PersonalSystem.GetWazaOboeWazaNo(i); + var kind = PersonalSystem.GetWazaOboeKind(i); + if (kind == OboeWazaKind.LEVEL || kind == OboeWazaKind.BASE) + PushWaza(wazano); + } + } public void PushWaza(WazaNo wazano) { @@ -426,32 +669,104 @@ public void SetWaza(byte wazaIndex, WazaNo wazano) } } - // TODO - public void RemoveWaza(byte wazaIndex) { } + public void RemoveWaza(byte wazaIndex) + { + if (wazaIndex < PmlConstants.MAX_WAZA_NUM) + { + m_accessor.SetWazaNo(wazaIndex, (uint)WazaNo.NULL); + m_accessor.SetPP(wazaIndex, 0); + m_accessor.SetWazaPPUpCount(wazaIndex, 0); + } + } - // TODO - public void RemoveDuplicatedWaza() { } + public void RemoveDuplicatedWaza() + { + for (byte i = 0; i < PmlConstants.MAX_WAZA_NUM; i++) + { + var waza = GetWazaNo(i); + if (waza == WazaNo.NULL) + continue; - // TODO - public void ExchangeWazaPos(byte pos1, byte pos2) { } + for (byte j = (byte)(i + 1); j < PmlConstants.MAX_WAZA_NUM; j++) + { + if (GetWazaNo(j) == waza) + RemoveWaza(j); + } + } + } - // TODO - public void CloseUpWazaPos() { } + public void ExchangeWazaPos(byte pos1, byte pos2) + { + if (pos1 >= PmlConstants.MAX_WAZA_NUM || pos2 >= PmlConstants.MAX_WAZA_NUM) + return; - // TODO - public bool CheckWazaMachine(uint machineNo) { return false; } + var waza1 = m_accessor.GetWazaNo(pos1); + var pp1 = m_accessor.GetPP(pos1); + var upcount1 = m_accessor.GetWazaPPUpCount(pos1); - // TODO - public bool CheckWazaRecord(uint recordNo) { return false; } + m_accessor.SetWazaNo(pos1, (uint)m_accessor.GetWazaNo(pos2)); + m_accessor.SetPP(pos1, m_accessor.GetPP(pos2)); + m_accessor.SetWazaPPUpCount(pos1, m_accessor.GetWazaPPUpCount(pos2)); - // TODO - public bool CheckWazaOshie(uint oshieNo) { return false; } + m_accessor.SetWazaNo(pos2, (uint)waza1); + m_accessor.SetPP(pos2, pp1); + m_accessor.SetWazaPPUpCount(pos2, upcount1); + } - // TODO - public bool CheckWazaOshie(WazaNo wazano) { return false; } + public void CloseUpWazaPos() + { + byte writePos = 0; + for (byte readPos = 0; readPos < PmlConstants.MAX_WAZA_NUM; readPos++) + { + if (GetWazaNo(readPos) != WazaNo.NULL) + { + if (writePos != readPos) + { + m_accessor.SetWazaNo(writePos, (uint)m_accessor.GetWazaNo(readPos)); + m_accessor.SetPP(writePos, m_accessor.GetPP(readPos)); + m_accessor.SetWazaPPUpCount(writePos, m_accessor.GetWazaPPUpCount(readPos)); + + m_accessor.SetWazaNo(readPos, (uint)WazaNo.NULL); + m_accessor.SetPP(readPos, 0); + m_accessor.SetWazaPPUpCount(readPos, 0); + } + writePos++; + } + } + } + + public bool CheckWazaMachine(uint machineNo) + { + PersonalSystem.LoadPersonalData(GetMonsNo(), GetFormNo()); + return PersonalSystem.CheckPersonalWazaMachine((ushort)machineNo); + } + + public bool CheckWazaRecord(uint recordNo) + { + PersonalSystem.LoadPersonalData(GetMonsNo(), GetFormNo()); + return PersonalSystem.CheckPersonalWazaRecord((ushort)recordNo); + } - // TODO - public WazaNo GetTamagoWazaNo(byte index) { return WazaNo.NULL; } + public bool CheckWazaOshie(uint oshieNo) + { + PersonalSystem.LoadPersonalData(GetMonsNo(), GetFormNo()); + return PersonalSystem.CheckPersonalWazaOshie((ushort)oshieNo); + } + + public bool CheckWazaOshie(WazaNo wazano) + { + for (int i = 0; i < PersonalSystem.GetOshieWazaNum(); i++) + { + if (PersonalSystem.GetOshieWazaNo(i) == wazano) + return CheckWazaOshie((uint)i); + } + return false; + } + + public WazaNo GetTamagoWazaNo(byte index) + { + return m_accessor.GetTamagoWazaNo(index); + } public void SetTamagoWazaNo(byte index, WazaNo wazano) { @@ -461,31 +776,140 @@ public void SetTamagoWazaNo(byte index, WazaNo wazano) GFL.ASSERT(false); } - // TODO - public void ClearTamagoWaza() { } + public void ClearTamagoWaza() + { + for (byte i = 0; i < PmlConstants.MAX_WAZA_NUM; i++) + m_accessor.SetTamagoWazaNo(i, (uint)WazaNo.NULL); + } + + public void InheriteTamagoWaza(CoreParam teacher) + { + // TODO: Ghidra shows completely different logic — checks if both Pokemon are same species, + // creates EggWazaData, loads personal egg waza data, iterates teacher's REGULAR waza + // (not tamago waza), checks each against egg waza data set, calls AddWazaIfEmptyExist + // on the child for matching waza. Current implementation incorrectly copies tamago slots. + } + + public WazaLearningResult AddWazaIfEmptyExist(WazaNo wazano) + { + if (HaveWaza(wazano)) + return WazaLearningResult.FAILED_SAME; + + var count = GetWazaCount(); + if (count >= PmlConstants.MAX_WAZA_NUM) + return WazaLearningResult.FAILED_FULL; + + SetWaza(count, wazano); + return WazaLearningResult.SUCCEEDED; + } + + public WazaLearningResult LearnNewWazaOnCurrentLevel(ref uint sameLevelIndex, ref WazaNo newWazano, [Optional] WazaLearnWork work) + { + return LearnNewWazaOnLevel((byte)GetLevel(), ref sameLevelIndex, ref newWazano, work); + } + + public WazaLearningResult LearnNewWazaOnLevel(byte level, ref uint sameLevelIndex, ref WazaNo newWazano, [Optional] WazaLearnWork work) + { + PersonalSystem.LoadWazaOboeData(GetMonsNo(), GetFormNo()); + var oboeNum = PersonalSystem.GetWazaOboeNum(); + + uint matchCount = 0; + for (ushort i = 0; i < oboeNum; i++) + { + var oboeLevel = PersonalSystem.GetWazaOboeLevel(i); + if (oboeLevel != level) + continue; + + if (matchCount < sameLevelIndex) + { + matchCount++; + continue; + } + + var wazano = (WazaNo)PersonalSystem.GetWazaOboeWazaNo(i); + + if (work != null && work.IsCheckedWaza(wazano)) + continue; + + if (work != null) + work.AddCheckedWaza(wazano); + + newWazano = wazano; + sameLevelIndex = matchCount + 1; + + return AddWazaIfEmptyExist(wazano); + } + + return WazaLearningResult.FAILED_NOT_EXIST; + } + + public WazaLearningResult LearnNewWazaOnEvolution(ref uint learnIndex, ref WazaNo newWazano, [Optional] WazaLearnWork work) + { + PersonalSystem.LoadWazaOboeData(GetMonsNo(), GetFormNo()); + var oboeNum = PersonalSystem.GetWazaOboeNum(); + + uint matchCount = 0; + for (ushort i = 0; i < oboeNum; i++) + { + var kind = PersonalSystem.GetWazaOboeKind(i); + if (kind != OboeWazaKind.EVOLVE) + continue; + + if (matchCount < learnIndex) + { + matchCount++; + continue; + } - // TODO - public void InheriteTamagoWaza(CoreParam teacher) { } + var wazano = (WazaNo)PersonalSystem.GetWazaOboeWazaNo(i); - // TODO - public WazaLearningResult AddWazaIfEmptyExist(WazaNo wazano) { return WazaLearningResult.SUCCEEDED; } + if (work != null && work.IsCheckedWaza(wazano)) + continue; - // TODO - public WazaLearningResult LearnNewWazaOnCurrentLevel(ref uint sameLevelIndex, ref WazaNo newWazano, [Optional] WazaLearnWork work) { return WazaLearningResult.SUCCEEDED; } + if (work != null) + work.AddCheckedWaza(wazano); - // TODO - public WazaLearningResult LearnNewWazaOnLevel(byte level, ref uint sameLevelIndex, ref WazaNo newWazano, [Optional] WazaLearnWork work) { return WazaLearningResult.SUCCEEDED; } + newWazano = wazano; + learnIndex = matchCount + 1; - // TODO - public WazaLearningResult LearnNewWazaOnEvolution(ref uint learnIndex, ref WazaNo newWazano, [Optional] WazaLearnWork work) { return WazaLearningResult.SUCCEEDED; } + return AddWazaIfEmptyExist(wazano); + } + + return WazaLearningResult.FAILED_NOT_EXIST; + } - // TODO public HashSet CollectRemindableWaza() { - // TODO - void CheckAndAddWazaNo(HashSet list, WazaNo wazaNo) { } + // TODO: Ghidra shows: first adds 4 tamago waza, then iterates waza record flags + // (0-98) — if a record flag is set, gets the corresponding waza from ItemManager + // and adds it. Then three separate passes through waza oboe by kind (LEVEL, BASE, + // EVOLVE) up to current level. Current implementation is missing waza record flag + // iteration entirely and doesn't separate by OboeWazaKind. + void CheckAndAddWazaNo(HashSet list, WazaNo wazaNo) + { + if (wazaNo != WazaNo.NULL) + list.Add(wazaNo); + } + + var result = new HashSet(); + + for (byte i = 0; i < PmlConstants.MAX_WAZA_NUM; i++) + CheckAndAddWazaNo(result, GetTamagoWazaNo(i)); + + PersonalSystem.LoadWazaOboeData(GetMonsNo(), GetFormNo()); + var oboeNum = PersonalSystem.GetWazaOboeNum(); + + for (ushort i = 0; i < oboeNum; i++) + { + var level = PersonalSystem.GetWazaOboeLevel(i); + if (level > GetLevel()) + break; + + var wazano = (WazaNo)PersonalSystem.GetWazaOboeWazaNo(i); + CheckAndAddWazaNo(result, wazano); + } - return default; + return result; } public uint GetWazaPP(byte wazaIndex) @@ -504,8 +928,11 @@ public void SetWazaPP(byte wazaIndex, byte value) m_accessor.SetPP(wazaIndex, (byte)((value <= max) ? value : max)); } - // TODO - public void ReduceWazaPP(byte wazaIndex, byte value) { } + public void ReduceWazaPP(byte wazaIndex, byte value) + { + var curr = GetWazaPP(wazaIndex); + SetWazaPP(wazaIndex, (byte)(curr >= value ? curr - value : 0)); + } public void RecoverWazaPP(byte wazaIndex) { @@ -529,168 +956,333 @@ public void RecoverWazaPPAll() RecoverWazaPP(3); } - // TODO - public bool CanUsePointUp(byte wazaIndex) { return false; } + public bool CanUsePointUp(byte wazaIndex) + { + if (GetWazaNo(wazaIndex) == WazaNo.NULL) + return false; + + return GetWazaPPUpCount(wazaIndex) < PmlConstants.MAX_WAZAPP_UPCOUNT; + } + + public void UsePointUp(byte wazaIndex) + { + if (!CanUsePointUp(wazaIndex)) + return; - // TODO - public void UsePointUp(byte wazaIndex) { } + var count = (byte)(GetWazaPPUpCount(wazaIndex) + 1); + m_accessor.SetWazaPPUpCount(wazaIndex, count); + RecoverWazaPP(wazaIndex); + } public uint GetWazaPPUpCount(byte wazaIndex) { return m_accessor.GetWazaPPUpCount(wazaIndex); } - // TODO - public void SetWazaPPUpCount(byte wazaIndex, byte value) { } + public void SetWazaPPUpCount(byte wazaIndex, byte value) + { + if (value > PmlConstants.MAX_WAZAPP_UPCOUNT) + value = PmlConstants.MAX_WAZAPP_UPCOUNT; + m_accessor.SetWazaPPUpCount(wazaIndex, value); + } - // TODO - public void IncWazaPPUpCount(byte wazaIndex) { } + public void IncWazaPPUpCount(byte wazaIndex) + { + var count = GetWazaPPUpCount(wazaIndex); + if (count < PmlConstants.MAX_WAZAPP_UPCOUNT) + m_accessor.SetWazaPPUpCount(wazaIndex, (byte)(count + 1)); + } - // TODO - public bool GetWazaRecordFlag(byte recordIndex) { return false; } + public bool GetWazaRecordFlag(byte recordIndex) + { + return m_accessor.GetWazaRecordFlag(recordIndex); + } - // TODO - public void SetWazaRecordFlag(byte recordIndex) { } + public void SetWazaRecordFlag(byte recordIndex) + { + m_accessor.SetWazaRecordFlag(recordIndex, true); + } - // TODO - public void RemoveWazaRecordFlag(byte recordIndex) { } + public void RemoveWazaRecordFlag(byte recordIndex) + { + m_accessor.SetWazaRecordFlag(recordIndex, false); + } - // TODO - public void ClearWazaRecordFlag() { } + public void ClearWazaRecordFlag() + { + m_accessor.ClearWazaRecordFlag(); + } public void ClearBankUniqueID() { m_accessor.ClearBankUniqueID(); } - // TODO - public ulong GetBankUniqueID() { return 0; } + public ulong GetBankUniqueID() + { + return m_accessor.GetBankUniqueID(); + } - // TODO - public void SetBankUniqueID(ulong value) { } + public void SetBankUniqueID(ulong value) + { + m_accessor.SetBankUniqueID(value); + } public Sex GetSex() { return m_accessor.GetSex(); } - // TODO - public byte GetSexVector() { return 0; } + public byte GetSexVector() + { + PersonalSystem.LoadPersonalData(GetMonsNo(), GetFormNo()); + return (byte)PersonalSystem.GetPersonalParam(ParamID.SEX); + } - // TODO - public SexType GetSexType() { return SexType.RANDOM; } + public SexType GetSexType() + { + PersonalSystem.LoadPersonalData(GetMonsNo(), GetFormNo()); + return PersonalSystem.GetPersonalSexType(); + } - // TODO - public void ChangeSex(Sex newSex) { } + public void ChangeSex(Sex newSex) + { + m_accessor.SetSex(newSex); + } - // TODO - public Seikaku GetSeikaku() { return Seikaku.GANBARIYA; } + public Seikaku GetSeikaku() + { + return (Seikaku)m_accessor.GetSeikaku(); + } - // TODO - public void ChangeSeikaku(Seikaku seikaku) { } + public void ChangeSeikaku(Seikaku seikaku) + { + m_accessor.SetSeikaku((uint)seikaku); + } + + public bool IsSeikakuHigh() + { + return CalcTool.IsSeikakuHigh(GetSeikaku()); + } - // TODO - public bool IsSeikakuHigh() { return false; } + public bool IsSeikakuLow() + { + return CalcTool.IsSeikakuLow(GetSeikaku()); + } - // TODO - public bool IsSeikakuLow() { return false; } + public Seikaku GetSeikakuHosei() + { + return (Seikaku)m_accessor.GetSeikakuHosei(); + } + + public void ChangeSeikakuHosei(Seikaku seikaku) + { + m_accessor.SetSeikakuHosei((uint)seikaku); + if (HaveCalcParam()) + UpdateCalcDatas(); + } - // TODO - public Seikaku GetSeikakuHosei() { return Seikaku.GANBARIYA; } + public TokuseiNo GetTokuseiNo() + { + return m_accessor.GetTokuseiNo(); + } - // TODO - public void ChangeSeikakuHosei(Seikaku seikaku) { } + public byte GetTokuseiIndex() + { + if (m_accessor.IsTokusei3()) + return 2; + if (m_accessor.IsTokusei2()) + return 1; + if (m_accessor.IsTokusei1()) + return 0; - // TODO - public TokuseiNo GetTokuseiNo() { return TokuseiNo.NULL; } + return TOKUSEI_INDEX_ERROR; + } - // TODO - public byte GetTokuseiIndex() { return 0; } + public byte GetTokuseiIndexStrict() + { + var tokuseiNo = (ushort)m_accessor.GetTokuseiNo(); + PersonalSystem.LoadPersonalData(GetMonsNo(), GetFormNo()); - // TODO - public byte GetTokuseiIndexStrict() { return 0; } + if (tokuseiNo == PersonalSystem.GetPersonalParam(ParamID.TOKUSEI1)) + return 0; + if (tokuseiNo == PersonalSystem.GetPersonalParam(ParamID.TOKUSEI2)) + return 1; + if (tokuseiNo == PersonalSystem.GetPersonalParam(ParamID.TOKUSEI3)) + return 2; - // TODO - public void FlipTokuseiIndex() { } + return TOKUSEI_INDEX_ERROR; + } - // TODO - public void SetTokusei3rd() { } + public void FlipTokuseiIndex() + { + var index = GetTokuseiIndex(); + if (index == 2) + return; - // TODO - public void SetTokuseiIndex(byte tokuseiIndex) { } + byte newIndex = (byte)(index == 0 ? 1 : 0); + SetTokuseiIndex(newIndex); + } - // TODO - public void SetFavoriteFlag(bool flag) { } + public void SetTokusei3rd() + { + SetTokuseiIndex(2); + } - // TODO - public bool GetFavoriteFlag() { return false; } + public void SetTokuseiIndex(byte tokuseiIndex) + { + PersonalSystem.LoadPersonalData(GetMonsNo(), GetFormNo()); - // TODO - public bool CompareOwnerInfo(OwnerInfo ownerInfo) { return false; } + m_accessor.SetTokusei1Flag(tokuseiIndex == 0); + m_accessor.SetTokusei2Flag(tokuseiIndex == 1); + m_accessor.SetTokusei3Flag(tokuseiIndex == 2); - // TODO - public bool UpdateOwnerInfo(OwnerInfo ownerInfo) { return false; } + var tokusei = CalcTool.GetTokuseiNo(GetMonsNo(), GetFormNo(), tokuseiIndex); + m_accessor.SetTokuseiNo(tokusei); + } + + public void SetFavoriteFlag(bool flag) + { + m_accessor.SetFavoriteFlag(flag); + } + + public bool GetFavoriteFlag() + { + return m_accessor.IsFavorite(); + } + + public bool CompareOwnerInfo(OwnerInfo ownerInfo) + { + return (byte)m_accessor.GetOyasex() == ownerInfo.sex && + m_accessor.GetID() == ownerInfo.trainerId && + m_accessor.CompareOyaName(ownerInfo.name); + } + + public bool UpdateOwnerInfo(OwnerInfo ownerInfo) + { + // TODO: Ghidra shows: if same owner -> SetOwnedOthersFlag(false), return true. + // If different owner -> SetOwnedOthersFlag(true), copy PastParentsName/Sex/LangID, + // reset OthersMemories (Level/Code/Data/Feel to 0), load personal data, + // set OthersFriendship to base friendship from personal, return false. + // Return value semantics are inverted vs current implementation. + if (CompareOwnerInfo(ownerInfo)) + return false; + + m_accessor.SetOwnedOthersFlag(true); + m_accessor.SetOthersFriendshipTrainerID((ushort)(ownerInfo.trainerId & 0xFFFF)); + return true; + } public bool IsOwnedOriginalParent() { return !m_accessor.GetOwnedOthersFlag(); } - // TODO - public bool HaveNickName() { return false; } + public bool HaveNickName() + { + return m_accessor.HaveNickName(); + } public string GetNickName() { return m_accessor.GetNickName(); } - // TODO - public void SetNickName(string nickName) { } + public void SetNickName(string nickName) + { + m_accessor.SetNickName(nickName); + m_accessor.SetNickNameFlag(true); + } - // TODO - public void SetDefaultNickName() { } + public void SetDefaultNickName() + { + var monsno = GetMonsNo(); + if (monsno != MonsNo.NULL) + { + var name = PersonalSystem.GetMonsName(monsno); + m_accessor.SetNickName(name); + m_accessor.SetNickNameFlag(false); + } + } - // TODO - public bool IsDefaultNickName() { return false; } + public bool IsDefaultNickName() + { + return !m_accessor.HaveNickName(); + } - // TODO - public uint GetFriendship() { return 0; } + public uint GetFriendship() + { + return m_accessor.GetFriendship(); + } - // TODO - public void SetFriendship(uint value) { } + public void SetFriendship(uint value) + { + if (value > PmlConstants.MAX_FRIENDSHIP) + value = PmlConstants.MAX_FRIENDSHIP; + m_accessor.SetFriendship((byte)value); + } - // TODO - public void AddFriendship(uint value) { } + public void AddFriendship(uint value) + { + SetFriendship(GetFriendship() + value); + } - // TODO - public void SubFriendship(uint value) { } + public void SubFriendship(uint value) + { + var curr = GetFriendship(); + SetFriendship(curr >= value ? curr - value : 0); + } - // TODO - public uint GetOriginalFriendship() { return 0; } + public uint GetOriginalFriendship() + { + return m_accessor.GetOriginalFriendship(); + } - // TODO - public void SetOriginalFriendship(uint value) { } + public void SetOriginalFriendship(uint value) + { + if (value > PmlConstants.MAX_FRIENDSHIP) + value = PmlConstants.MAX_FRIENDSHIP; + m_accessor.SetOriginalFriendship((byte)value); + } - // TODO - public void AddOriginalFriendship(uint value) { } + public void AddOriginalFriendship(uint value) + { + SetOriginalFriendship(GetOriginalFriendship() + value); + } - // TODO - public void SubOriginalFriendship(uint value) { } + public void SubOriginalFriendship(uint value) + { + var curr = GetOriginalFriendship(); + SetOriginalFriendship(curr >= value ? curr - value : 0); + } - // TODO - public ushort GetOthersFriendshipTrainerID() { return 0; } + public ushort GetOthersFriendshipTrainerID() + { + return m_accessor.GetOthersFriendshipTrainerID(); + } - // TODO - public uint GetOthersFriendship() { return 0; } + public uint GetOthersFriendship() + { + return m_accessor.GetOthersFriendship(); + } - // TODO - public void SetOthersFriendship(uint value) { } + public void SetOthersFriendship(uint value) + { + if (value > PmlConstants.MAX_FRIENDSHIP) + value = PmlConstants.MAX_FRIENDSHIP; + m_accessor.SetOthersFriendship((byte)value); + } - // TODO - public void AddOthersFriendship(uint value) { } + public void AddOthersFriendship(uint value) + { + SetOthersFriendship(GetOthersFriendship() + value); + } - // TODO - public void SubOthersFriendship(uint value) { } + public void SubOthersFriendship(uint value) + { + var curr = GetOthersFriendship(); + SetOthersFriendship(curr >= value ? curr - value : 0); + } public bool IsEgg(EggCheckType type) { @@ -720,11 +1312,25 @@ public void SetEggFlag() m_accessor.SetTamagoFlag(true); } - // TODO - public void ChangeEgg() { } + public void ChangeEgg() + { + // TODO: Ghidra shows: checks IsFuseiTamago (returns if bad egg), sets TamagoFlag, + // gets language ID and calls GetMonsName(0x1ee, langId) to set egg nickname, + // sets NickNameFlag=false, loads personal data to get FRIENDSHIP_BIRTH param + // and sets OriginalFriendship to that value (NOT SetFriendship) + m_accessor.SetTamagoFlag(true); + m_accessor.SetNickNameFlag(false); + SetFriendship(BIRTH_FRIENDSHIP); + } - // TODO - public void Birth() { } + public void Birth() + { + // TODO: Ghidra shows: asserts IsTamago, sets TamagoFlag=false, + // sets OriginalFriendship=120, sets LangId from PmlUse.Instance.LangId, + // calls SetDefaultNickName, sets OwnedOthersFlag=false + m_accessor.SetTamagoFlag(false); + SetDefaultNickName(); + } public ushort GetItem() { @@ -736,73 +1342,167 @@ public void SetItem(ushort itemno) m_accessor.SetItemNo(itemno); } - // TODO - public void RemoveItem() { } + public void RemoveItem() + { + m_accessor.SetItemNo((ushort)ItemNo.DUMMY_DATA); + } + + public void Evolve(MonsNo nextMonsno, uint routeIndex) + { + // TODO: Ghidra shows: loads evolution table, asserts evolved mons matches nextMonsno, + // checks form specification, calls ChangeMonsNo (which itself needs fixing), + // then checks evolution condition — if it matches item-consuming types + // (conditions 6, 18, 33, 45), removes the held item via SetItemNo(0). + // Tokusei recalculation is handled inside ChangeMonsNo in the binary. + PersonalSystem.LoadEvolutionTable(GetMonsNo(), GetFormNo()); + var formno = PersonalSystem.GetEvolvedFormNo((byte)routeIndex); + if (!PersonalSystem.IsEvolvedFormNoSpecified((byte)routeIndex)) + formno = GetFormNo(); + + ChangeMonsNo(nextMonsno, formno); + + PersonalSystem.LoadPersonalData(nextMonsno, formno); + var tokuseiIndex = GetTokuseiIndex(); + if (tokuseiIndex != 2) + { + var tokusei = CalcTool.GetTokuseiNo(nextMonsno, formno, tokuseiIndex); + m_accessor.SetTokuseiNo(tokusei); + } + else + { + var tokusei = CalcTool.GetTokuseiNo(nextMonsno, formno, 2); + m_accessor.SetTokuseiNo(tokusei); + } + } + + public bool CanEvolve(EvolveSituation situation, PokeParty party, ref MonsNo nextMonsno, ref uint rootNum) + { + // Evolution checking is complex and depends on EvolveManager + // Stub for now - full implementation requires EvolveManager + return false; + } + + public bool CanEvolveByItem(EvolveSituation situation, ushort itemno, ref MonsNo nextMonsno, ref uint rootNum) + { + return false; + } - // TODO - public void Evolve(MonsNo nextMonsno, uint routeIndex) { } + public bool CanEvolveByTrade(CoreParam pairPoke, ref MonsNo nextMonsno, ref uint rootNum) + { + return false; + } - // TODO - public bool CanEvolve(EvolveSituation situation, PokeParty party, ref MonsNo nextMonsno, ref uint rootNum) { return false; } + public bool CanEvolveByEvent(EvolveSituation situation, PokeParty party, ref MonsNo nextMonsno, ref uint rootNum) + { + return false; + } - // TODO - public bool CanEvolveByItem(EvolveSituation situation, ushort itemno, ref MonsNo nextMonsno, ref uint rootNum) { return false; } + public bool HaveEvolutionRoot() + { + PersonalSystem.LoadEvolutionTable(GetMonsNo(), GetFormNo()); + return PersonalSystem.GetEvolutionRouteNum() > 0; + } - // TODO - public bool CanEvolveByTrade(CoreParam pairPoke, ref MonsNo nextMonsno, ref uint rootNum) { return false; } + public void ChangeFormNo(ushort nextFormno, [Optional] FormChangeResult pResult) + { + m_accessor.SetFormNo(nextFormno); - // TODO - public bool CanEvolveByEvent(EvolveSituation situation, PokeParty party, ref MonsNo nextMonsno, ref uint rootNum) { return false; } + PersonalSystem.LoadPersonalData(GetMonsNo(), nextFormno); + var tokuseiIndex = GetTokuseiIndex(); + var tokusei = CalcTool.GetTokuseiNo(GetMonsNo(), nextFormno, tokuseiIndex); + m_accessor.SetTokuseiNo(tokusei); - // TODO - public bool HaveEvolutionRoot() { return false; } + changeWazaByFormChange(nextFormno, pResult); - // TODO - public void ChangeFormNo(ushort nextFormno, [Optional] FormChangeResult pResult) { } + if (HaveCalcParam()) + UpdateCalcDatas(); + } - // TODO - public ushort GetNextFormNoFromHoldItem(ushort holdItemno) { return 0; } + public ushort GetNextFormNoFromHoldItem(ushort holdItemno) + { + if (CalcTool.DecideFormNoFromHoldItem(GetMonsNo(), holdItemno, out ushort formno)) + return formno; + return GetFormNo(); + } - // TODO - public bool RegulateFormParams() { return false; } + public bool RegulateFormParams() + { + var formno = GetFormNo(); + PersonalSystem.LoadPersonalData(GetMonsNo(), formno); + var maxForm = PersonalSystem.GetPersonalParam(ParamID.FORM_MAX); + if (formno >= maxForm && maxForm > 0) + { + m_accessor.SetFormNo(0); + return true; + } + return false; + } - // TODO - public bool IsRare() { return false; } + public bool IsRare() + { + return CalcTool.IsRareColor(m_accessor.GetID(), m_accessor.GetColorRnd()); + } - // TODO - public uint GetRareRnd() { return 0; } + public uint GetRareRnd() + { + return m_accessor.GetColorRnd(); + } - // TODO - public RareType GetRareType() { return RareType.NOT_RARE; } + public RareType GetRareType() + { + return CalcTool.CalcRareColorType(m_accessor.GetID(), m_accessor.GetColorRnd(), + m_accessor.GetCassetteVersion(), m_accessor.IsEventPokemon()); + } - // TODO - public uint GetID() { return 0; } + public uint GetID() + { + return m_accessor.GetID(); + } public uint GetPersonalRnd() { return m_accessor.GetPersonalRnd(); } - // TODO - public uint GetCheckSum() { return 0; } + public uint GetCheckSum() + { + return m_accessor.GetCheckSum(); + } - // TODO - public void SetID(uint id) { } + public void SetID(uint id) + { + m_accessor.SetID(id); + } - // TODO - public void SetRare() { } + public void SetRare() + { + var rnd = CalcTool.CorrectColorRndForRare(m_accessor.GetID(), m_accessor.GetColorRnd()); + m_accessor.SetColorRnd(rnd); + } - // TODO - public void SetNotRare() { } + public void SetNotRare() + { + var rnd = CalcTool.CorrectColorRndForNormal(m_accessor.GetID(), m_accessor.GetColorRnd()); + m_accessor.SetColorRnd(rnd); + } - // TODO - public void SetRareType(RareType type) { } + public void SetRareType(RareType type) + { + var rnd = CalcTool.CorrectColorRndForRareType(m_accessor.GetID(), m_accessor.GetColorRnd(), type); + m_accessor.SetColorRnd(rnd); + } - // TODO - public PokeType GetType1() { return PokeType.NORMAL; } + public PokeType GetType1() + { + PersonalSystem.LoadPersonalData(GetMonsNo(), GetFormNo()); + return (PokeType)PersonalSystem.GetPersonalParam(ParamID.TYPE1); + } - // TODO - public PokeType GetType2() { return PokeType.NORMAL; } + public PokeType GetType2() + { + PersonalSystem.LoadPersonalData(GetMonsNo(), GetFormNo()); + return (PokeType)PersonalSystem.GetPersonalParam(ParamID.TYPE2); + } public string GetParentName() { @@ -824,59 +1524,242 @@ public void SetParentSex(Sex sex) m_accessor.SetOyasex(sex); } - // TODO - public uint GetMemories(Memories memoriesKind) { return default; } + public uint GetMemories(Memories memoriesKind) + { + switch (memoriesKind) + { + case Memories.EGG_TAKEN_YEAR: + return m_accessor.GetTamagoGetYear(); + case Memories.EGG_TAKEN_MONTH: + return m_accessor.GetTamagoGetMonth(); + case Memories.EGG_TAKEN_DAY: + return m_accessor.GetTamagoGetDay(); + case Memories.FIRST_CONTACT_YEAR: + return m_accessor.GetBirthYear(); + case Memories.FIRST_CONTACT_MONTH: + return m_accessor.GetBirthMonth(); + case Memories.FIRST_CONTACT_DAY: + return m_accessor.GetBirthDay(); + case Memories.EGG_TAKEN_PLACE: + return m_accessor.GetBirthPlace(); + case Memories.FIRST_CONTACT_PLACE: + return m_accessor.GetGetPlace(); + case Memories.CAPTURED_BALL: + return m_accessor.GetGetBall(); + case Memories.CAPTURED_LEVEL: + return m_accessor.GetGetLevel(); + case Memories.LEVEL_WITH_PARENT: + return m_accessor.GetMemoriesLevel(); + case Memories.CODE_WITH_PARENT: + return m_accessor.GetMemoriesCode(); + case Memories.DATA_WITH_PARENT: + return m_accessor.GetMemoriesData(); + case Memories.FEEL_WITH_PARENT: + return m_accessor.GetMemoriesFeel(); + case Memories.LEVEL_WITH_OTHERS: + return m_accessor.GetOthersMemoriesLevel(); + case Memories.CODE_WITH_OTHERS: + return m_accessor.GetOthersMemoriesCode(); + case Memories.DATA_WITH_OTHERS: + return m_accessor.GetOthersMemoriesData(); + case Memories.FEEL_WITH_OTHERS: + return m_accessor.GetOthersMemoriesFeel(); + default: + GFL.ASSERT(false); + return 0; + } + } - // TODO - public void SetMemories(Memories memoriesKind, uint value) { } + public void SetMemories(Memories memoriesKind, uint value) + { + switch (memoriesKind) + { + case Memories.EGG_TAKEN_YEAR: + m_accessor.SetTamagoGetYear((byte)value); + break; + case Memories.EGG_TAKEN_MONTH: + m_accessor.SetTamagoGetMonth((byte)value); + break; + case Memories.EGG_TAKEN_DAY: + m_accessor.SetTamagoGetDay((byte)value); + break; + case Memories.FIRST_CONTACT_YEAR: + m_accessor.SetBirthYear((byte)value); + break; + case Memories.FIRST_CONTACT_MONTH: + m_accessor.SetBirthMonth((byte)value); + break; + case Memories.FIRST_CONTACT_DAY: + m_accessor.SetBirthDay((byte)value); + break; + case Memories.EGG_TAKEN_PLACE: + m_accessor.SetBirthPlace((ushort)value); + break; + case Memories.FIRST_CONTACT_PLACE: + m_accessor.SetGetPlace((ushort)value); + break; + case Memories.CAPTURED_BALL: + m_accessor.SetGetBall((byte)value); + break; + case Memories.CAPTURED_LEVEL: + m_accessor.SetGetLevel((byte)value); + break; + case Memories.LEVEL_WITH_PARENT: + m_accessor.SetMemoriesLevel((byte)value); + break; + case Memories.CODE_WITH_PARENT: + m_accessor.SetMemoriesCode((byte)value); + break; + case Memories.DATA_WITH_PARENT: + m_accessor.SetMemoriesData((ushort)value); + break; + case Memories.FEEL_WITH_PARENT: + m_accessor.SetMemoriesFeel((byte)value); + break; + case Memories.LEVEL_WITH_OTHERS: + m_accessor.SetOthersMemoriesLevel((byte)value); + break; + case Memories.CODE_WITH_OTHERS: + m_accessor.SetOthersMemoriesCode((byte)value); + break; + case Memories.DATA_WITH_OTHERS: + m_accessor.SetOthersMemoriesData((ushort)value); + break; + case Memories.FEEL_WITH_OTHERS: + m_accessor.SetOthersMemoriesFeel((byte)value); + break; + default: + GFL.ASSERT(false); + break; + } + } - // TODO - public string GetPastParentsName() { return ""; } + public string GetPastParentsName() + { + return m_accessor.GetPastParentsName(); + } - // TODO - public void SetPastParentsName(string name) { } + public void SetPastParentsName(string name) + { + m_accessor.SetPastParentsName(name); + } - // TODO - public Sex GetPastParentsSex() { return Sex.NUM; } + public Sex GetPastParentsSex() + { + return m_accessor.GetPastParentsSex(); + } - // TODO - public void SetPastParentsSex(Sex sex) { } + public void SetPastParentsSex(Sex sex) + { + m_accessor.SetPastParentsSex(sex); + } - // TODO - public byte GetPastParentsLangID() { return 0; } + public byte GetPastParentsLangID() + { + return m_accessor.GetPastParentsLangID(); + } - // TODO - public void SetPastParentsLangID(byte langID) { } + public void SetPastParentsLangID(byte langID) + { + m_accessor.SetPastParentsLangID(langID); + } - // TODO - public byte GetCondition(Condition cond) { return 0; } + public byte GetCondition(Condition cond) + { + switch (cond) + { + case Condition.STYLE: + return m_accessor.GetStyle(); + case Condition.BEAUTIFUL: + return m_accessor.GetBeautiful(); + case Condition.CUTE: + return m_accessor.GetCute(); + case Condition.CLEVER: + return m_accessor.GetClever(); + case Condition.STRONG: + return m_accessor.GetStrong(); + case Condition.FUR: + return m_accessor.GetFur(); + default: + GFL.ASSERT(false); + return 0; + } + } - // TODO - public void SetCondition(Condition cond, byte value) { } + public void SetCondition(Condition cond, byte value) + { + switch (cond) + { + case Condition.STYLE: + m_accessor.SetStyle(value); + break; + case Condition.BEAUTIFUL: + m_accessor.SetBeautiful(value); + break; + case Condition.CUTE: + m_accessor.SetCute(value); + break; + case Condition.CLEVER: + m_accessor.SetClever(value); + break; + case Condition.STRONG: + m_accessor.SetStrong(value); + break; + case Condition.FUR: + m_accessor.SetFur(value); + break; + default: + GFL.ASSERT(false); + break; + } + } - // TODO - public bool IsBoxMarkSet() { return false; } + public bool IsBoxMarkSet() + { + return m_accessor.GetBoxMark() != 0; + } - // TODO - public bool IsBoxMarkSet(BoxMark mark) { return false; } + public bool IsBoxMarkSet(BoxMark mark) + { + return GetBoxMark(mark) != BoxMarkColor.NONE; + } - // TODO - public void SetBoxMark(BoxMark mark, BoxMarkColor color) { } + public void SetBoxMark(BoxMark mark, BoxMarkColor color) + { + var bits = m_accessor.GetBoxMark(); + int shift = (int)mark * 2; + bits = (ushort)((bits & ~(3 << shift)) | ((int)color << shift)); + m_accessor.SetBoxMark(bits); + } - // TODO - public void RemoveBoxMark(BoxMark mark) { } + public void RemoveBoxMark(BoxMark mark) + { + SetBoxMark(mark, BoxMarkColor.NONE); + } - // TODO - public BoxMarkColor GetBoxMark(BoxMark mark) { return default; } + public BoxMarkColor GetBoxMark(BoxMark mark) + { + var bits = m_accessor.GetBoxMark(); + int shift = (int)mark * 2; + return (BoxMarkColor)((bits >> shift) & 3); + } - // TODO - public void RemoveAllBoxMark() { } + public void RemoveAllBoxMark() + { + m_accessor.SetBoxMark(0); + } - // TODO - public void SetAllBoxMark(BoxMarkContainer markContainer) { } + public void SetAllBoxMark(BoxMarkContainer markContainer) + { + for (int i = 0; i < (int)BoxMark.MARK_NUM; i++) + SetBoxMark((BoxMark)i, markContainer.markColor[i]); + } - // TODO - public void GetAllBoxMark(BoxMarkContainer markContainer) { } + public void GetAllBoxMark(BoxMarkContainer markContainer) + { + for (int i = 0; i < (int)BoxMark.MARK_NUM; i++) + markContainer.markColor[i] = GetBoxMark((BoxMark)i); + } public uint GetLangId() { @@ -888,11 +1771,15 @@ public void SetLangId(uint langId) m_accessor.SetLangId((byte)langId); } - // TODO - public uint GetCassetteVersion() { return 0; } + public uint GetCassetteVersion() + { + return m_accessor.GetCassetteVersion(); + } - // TODO - public void SetCassetteVersion(uint version) { } + public void SetCassetteVersion(uint version) + { + m_accessor.SetCassetteVersion(version); + } public uint GetGetBall() { @@ -904,67 +1791,126 @@ public void SetGetBall(uint value) m_accessor.SetGetBall((byte)value); } - // TODO - public byte GetBattleRomMark() { return 0; } + public byte GetBattleRomMark() + { + return m_accessor.GetBattleRomMark(); + } - // TODO - public void SetBattleRomMark(byte battleRomMark) { } + public void SetBattleRomMark(byte battleRomMark) + { + m_accessor.SetBattleRomMark(battleRomMark); + } - // TODO - public byte GetNadenadeValue() { return 0; } + public byte GetNadenadeValue() + { + return m_accessor.GetNadenadeValue(); + } - // TODO - public void SetNadenadeValue(byte value) { } + public void SetNadenadeValue(byte value) + { + if (value > PmlConstants.MAX_NADENADE_VALUE) + value = PmlConstants.MAX_NADENADE_VALUE; + m_accessor.SetNadenadeValue(value); + } - // TODO - public void AddNadenadeValue(byte value) { } + public void AddNadenadeValue(byte value) + { + var curr = GetNadenadeValue(); + var newval = curr + value; + SetNadenadeValue((byte)(newval > PmlConstants.MAX_NADENADE_VALUE ? PmlConstants.MAX_NADENADE_VALUE : newval)); + } - // TODO - public void SubNadenadeValue(byte value) { } + public void SubNadenadeValue(byte value) + { + var curr = GetNadenadeValue(); + SetNadenadeValue((byte)(curr >= value ? curr - value : 0)); + } - // TODO - public PokeType GetMezapaType() { return PokeType.NULL; } + public PokeType GetMezapaType() + { + return CalcTool.CalcMezamerupawaaType( + (byte)m_accessor.GetTalentHp(), + (byte)m_accessor.GetTalentAtk(), + (byte)m_accessor.GetTalentDef(), + (byte)m_accessor.GetTalentAgi(), + (byte)m_accessor.GetTalentSpAtk(), + (byte)m_accessor.GetTalentSpDef()); + } - // TODO - public uint GetMezapaPower() { return 0; } + public uint GetMezapaPower() + { + return CalcTool.CalcMezamerupawaaPower( + (byte)m_accessor.GetTalentHp(), + (byte)m_accessor.GetTalentAtk(), + (byte)m_accessor.GetTalentDef(), + (byte)m_accessor.GetTalentAgi(), + (byte)m_accessor.GetTalentSpAtk(), + (byte)m_accessor.GetTalentSpDef()); + } - // TODO - public TasteJudge JudgeTaste(Taste taste) { return TasteJudge.NORMAL; } + public TasteJudge JudgeTaste(Taste taste) + { + return CalcTool.JudgeTaste(GetSeikakuHosei(), taste); + } - // TODO - public bool HaveRibbon(uint ribbonNo) { return false; } + public bool HaveRibbon(uint ribbonNo) + { + return m_accessor.HaveRibbon(ribbonNo); + } - // TODO - public void SetRibbon(uint ribbonNo) { } + public void SetRibbon(uint ribbonNo) + { + m_accessor.SetRibbon(ribbonNo); + } - // TODO - public void RemoveRibbon(uint ribbonNo) { } + public void RemoveRibbon(uint ribbonNo) + { + m_accessor.RemoveRibbon(ribbonNo); + } public void RemoveAllRibbon() { m_accessor.RemoveAllRibbon(); } - // TODO - public void SetLumpingRibbon(LumpingRibbon ribbonId, uint num) { } + public void SetLumpingRibbon(LumpingRibbon ribbonId, uint num) + { + m_accessor.SetLumpingRibbon(ribbonId, num); + } - // TODO - public void SetLumpingRibbon(uint ribbonNo, uint num) { } + public void SetLumpingRibbon(uint ribbonNo, uint num) + { + // Map ribbon number to lumping ribbon ID based on ribbon ranges + if (ribbonNo < (uint)LumpingRibbon.NUM) + m_accessor.SetLumpingRibbon((LumpingRibbon)ribbonNo, num); + } - // TODO - public uint GetLumpingRibbon(LumpingRibbon ribbonId) { return default; } + public uint GetLumpingRibbon(LumpingRibbon ribbonId) + { + return m_accessor.GetLumpingRibbon(ribbonId); + } - // TODO - public uint GetLumpingRibbon(uint ribbonNo) { return default; } + public uint GetLumpingRibbon(uint ribbonNo) + { + if (ribbonNo < (uint)LumpingRibbon.NUM) + return m_accessor.GetLumpingRibbon((LumpingRibbon)ribbonNo); + return 0; + } - // TODO - public bool IsEquipRibbonExist() { return false; } + public bool IsEquipRibbonExist() + { + return m_accessor.GetEquipRibbonNo() != PmlConstants.EQUIP_RIBBON_NULL; + } - // TODO - public byte GetEquipRibbonNo() { return 0; } + public byte GetEquipRibbonNo() + { + return m_accessor.GetEquipRibbonNo(); + } - // TODO - public void SetEquipRibbonNo(byte ribbonNo) { } + public void SetEquipRibbonNo(byte ribbonNo) + { + m_accessor.SetEquipRibbonNo(ribbonNo); + } public bool HavePokerusJustNow() { @@ -976,19 +1922,33 @@ public bool HavePokerusUntilNow() return (m_accessor.GetPokerus() & 0xFF) != 0; } - // TODO - public bool HavePokerusPast() { return false; } + public bool HavePokerusPast() + { + return !HavePokerusJustNow() && ((m_accessor.GetPokerus() >> 4) & 0xF) != 0; + } - // TODO - public void CatchPokerus() { } + public void CatchPokerus() + { + // Random pokerus strain and duration + var strain = (byte)((Local.Random.GetValue(4) + 1) << 4); + var duration = (byte)((strain >> 4) % 4 + 1); + m_accessor.SetPokerus((byte)(strain | duration)); + } public void InfectPokerusWith(CoreParam target) { target.SetPokerus(GetPokerus()); } - // TODO - public void DecreasePokerusDayCount(int passedDayCount) { } + public void DecreasePokerusDayCount(int passedDayCount) + { + var pokerus = m_accessor.GetPokerus(); + var duration = (int)(pokerus & 0xF); + duration -= passedDayCount; + if (duration < 0) + duration = 0; + m_accessor.SetPokerus((byte)((pokerus & 0xF0) | duration)); + } public uint GetPokerus() { @@ -1025,18 +1985,29 @@ public void GrantOfficialBattleRights() m_accessor.SetOfficialBattleEnableFlag(true); } - // TODO - public void RemoveAllRotomWaza() { } + public void RemoveAllRotomWaza() + { + var rotomWaza = CalcTool.GetRotomuWazaNo(GetFormNo()); + if (rotomWaza != WazaNo.NULL) + { + var idx = GetWazaIndex(rotomWaza); + if (idx < PmlConstants.MAX_WAZA_NUM) + RemoveWaza(idx); + } + } - // TODO public void SetRotomWaza(byte wazaIndex) { var formno = GetFormNo(); - + var rotomWaza = CalcTool.GetRotomuWazaNo(formno); + if (rotomWaza != WazaNo.NULL && wazaIndex < PmlConstants.MAX_WAZA_NUM) + SetWaza(wazaIndex, rotomWaza); } - // TODO - public LoveLevel CheckLoveLevel(CoreParam partner) { return LoveLevel.GOOD; } + public LoveLevel CheckLoveLevel(CoreParam partner) + { + return CalcTool.CalcLoveLevel(GetMonsNo(), GetID(), partner.GetMonsNo(), partner.GetID()); + } public bool GetPokeJobFlag(byte jobIndex) { @@ -1318,7 +2289,7 @@ protected uint GetAtk() if (HaveCalcParam()) return m_accessor.GetAtk(); - return CalcAtk(); + return CalcAtk_NotG(); } protected uint GetDef() @@ -1326,7 +2297,7 @@ protected uint GetDef() if (HaveCalcParam()) return m_accessor.GetDef(); - return CalcDef(); + return CalcDef_NotG(); } protected uint GetSpAtk() @@ -1334,7 +2305,7 @@ protected uint GetSpAtk() if (HaveCalcParam()) return m_accessor.GetSpAtk(); - return CalcSpAtk(); + return CalcSpAtk_NotG(); } protected uint GetSpDef() @@ -1342,7 +2313,7 @@ protected uint GetSpDef() if (HaveCalcParam()) return m_accessor.GetSpDef(); - return CalcSpDef(); + return CalcSpDef_NotG(); } protected uint GetAgi() @@ -1350,10 +2321,9 @@ protected uint GetAgi() if (HaveCalcParam()) return m_accessor.GetAgi(); - return CalcAgi(); + return CalcAgi_NotG(); } - // TODO protected byte CalcLevel() { return CalcTool.CalcLevel(GetMonsNo(), GetFormNo(), GetExp()); @@ -1419,41 +2389,89 @@ protected ushort CalcAgi() return CalcAgi_NotG(); } - // TODO - protected ushort CalcMaxHp_G() { return 0; } + protected ushort CalcMaxHp_G() + { + return CalcMaxHp_NotG(); + } - // TODO - protected ushort CalcAtk_G() { return 0; } + protected ushort CalcAtk_G() + { + return CalcAtk_NotG(); + } - // TODO - protected ushort CalcDef_G() { return 0; } + protected ushort CalcDef_G() + { + return CalcDef_NotG(); + } - // TODO - protected ushort CalcSpAtk_G() { return 0; } + protected ushort CalcSpAtk_G() + { + return CalcSpAtk_NotG(); + } - // TODO - protected ushort CalcSpDef_G() { return 0; } + protected ushort CalcSpDef_G() + { + return CalcSpDef_NotG(); + } - // TODO - protected ushort CalcAgi_G() { return 0; } + protected ushort CalcAgi_G() + { + return CalcAgi_NotG(); + } - // TODO - protected ushort CalcMaxHp_NotG() { return 0; } + protected ushort CalcMaxHp_NotG() + { + PersonalSystem.LoadPersonalData(GetMonsNo(), GetFormNo()); + var basev = (ushort)PersonalSystem.GetPersonalParam(ParamID.BASIC_HP); + byte flag = m_accessor.GetTrainingFlag(); + ushort talent = (flag & (1 << (int)PowerID.HP)) != 0 ? PmlConstants.MAX_TALENT_POWER : (ushort)m_accessor.GetTalentHp(); + return CalcTool.CalcMaxHp(GetMonsNo(), CalcLevel(), basev, talent, (ushort)m_accessor.GetEffortHp()); + } - // TODO - protected ushort CalcAtk_NotG() { return 0; } + protected ushort CalcAtk_NotG() + { + PersonalSystem.LoadPersonalData(GetMonsNo(), GetFormNo()); + var basev = (ushort)PersonalSystem.GetPersonalParam(ParamID.BASIC_ATK); + byte flag = m_accessor.GetTrainingFlag(); + ushort talent = (flag & (1 << (int)PowerID.ATK)) != 0 ? PmlConstants.MAX_TALENT_POWER : (ushort)m_accessor.GetTalentAtk(); + return CalcTool.CalcAtk(CalcLevel(), basev, talent, (ushort)m_accessor.GetEffortAtk(), GetSeikakuHosei()); + } - // TODO - protected ushort CalcDef_NotG() { return 0; } + protected ushort CalcDef_NotG() + { + PersonalSystem.LoadPersonalData(GetMonsNo(), GetFormNo()); + var basev = (ushort)PersonalSystem.GetPersonalParam(ParamID.BASIC_DEF); + byte flag = m_accessor.GetTrainingFlag(); + ushort talent = (flag & (1 << (int)PowerID.DEF)) != 0 ? PmlConstants.MAX_TALENT_POWER : (ushort)m_accessor.GetTalentDef(); + return CalcTool.CalcDef(CalcLevel(), basev, talent, (ushort)m_accessor.GetEffortDef(), GetSeikakuHosei()); + } - // TODO - protected ushort CalcSpAtk_NotG() { return 0; } + protected ushort CalcSpAtk_NotG() + { + PersonalSystem.LoadPersonalData(GetMonsNo(), GetFormNo()); + var basev = (ushort)PersonalSystem.GetPersonalParam(ParamID.BASIC_SPATK); + byte flag = m_accessor.GetTrainingFlag(); + ushort talent = (flag & (1 << (int)PowerID.SPATK)) != 0 ? PmlConstants.MAX_TALENT_POWER : (ushort)m_accessor.GetTalentSpAtk(); + return CalcTool.CalcSpAtk(CalcLevel(), basev, talent, (ushort)m_accessor.GetEffortSpAtk(), GetSeikakuHosei()); + } - // TODO - protected ushort CalcSpDef_NotG() { return 0; } + protected ushort CalcSpDef_NotG() + { + PersonalSystem.LoadPersonalData(GetMonsNo(), GetFormNo()); + var basev = (ushort)PersonalSystem.GetPersonalParam(ParamID.BASIC_SPDEF); + byte flag = m_accessor.GetTrainingFlag(); + ushort talent = (flag & (1 << (int)PowerID.SPDEF)) != 0 ? PmlConstants.MAX_TALENT_POWER : (ushort)m_accessor.GetTalentSpDef(); + return CalcTool.CalcSpDef(CalcLevel(), basev, talent, (ushort)m_accessor.GetEffortSpDef(), GetSeikakuHosei()); + } - // TODO - protected ushort CalcAgi_NotG() { return 0; } + protected ushort CalcAgi_NotG() + { + PersonalSystem.LoadPersonalData(GetMonsNo(), GetFormNo()); + var basev = (ushort)PersonalSystem.GetPersonalParam(ParamID.BASIC_AGI); + byte flag = m_accessor.GetTrainingFlag(); + ushort talent = (flag & (1 << (int)PowerID.AGI)) != 0 ? PmlConstants.MAX_TALENT_POWER : (ushort)m_accessor.GetTalentAgi(); + return CalcTool.CalcAgi(CalcLevel(), basev, talent, (ushort)m_accessor.GetEffortAgi(), GetSeikakuHosei()); + } protected void changeWazaByFormChange(ushort nextFormno, [Optional] FormChangeResult pResult) { @@ -1482,16 +2500,38 @@ protected void changeWazaByFormChange_Learn(WazaNo learnWaza, [Optional] FormCha } } - // TODO protected void changeWazaByFormChange_Forget(WazaNo forgetWaza, WazaNo supplyWaza, [Optional] FormChangeResult pResult) { + var idx = GetWazaIndex(forgetWaza); + if (idx < PmlConstants.MAX_WAZA_NUM) + { + RemoveWaza(idx); + if (pResult != null) + pResult.SetRemovedWaza(forgetWaza); + if (supplyWaza != WazaNo.NULL) + changeWazaByFormChange_Learn(supplyWaza, pResult); + + CloseUpWazaPos(); + } } - // TODO protected void changeWazaByFormChange_Replace(WazaNo forgetWaza, WazaNo learnWaza, [Optional] FormChangeResult pResult) { - + var idx = GetWazaIndex(forgetWaza); + if (idx < PmlConstants.MAX_WAZA_NUM) + { + SetWaza(idx, learnWaza); + if (pResult != null) + { + pResult.SetRemovedWaza(forgetWaza); + pResult.SetAddedWaza(learnWaza); + } + } + else + { + changeWazaByFormChange_Learn(learnWaza, pResult); + } } protected uint AdjustEffortPower(uint beforeValue, uint afterValue) @@ -1511,7 +2551,7 @@ protected uint AdjustEffortPower(uint beforeValue, uint afterValue) public class WazaLearnWork { - private WazaNo[] m_checkedWazaArray = new WazaNo[PersonalConstants.MAX_WAZAOBOE_CODE_NUM]; + private WazaNo[] m_checkedWazaArray = new WazaNo[PersonalConstants.MAX_WAZAOBOE_CODE_NUM]; private uint m_checkedWazaNum; public WazaLearnWork() @@ -1556,7 +2596,7 @@ public bool IsCheckedWaza(WazaNo waza) public class FormChangeResult { - private WazaNo[] m_addedWaza = new WazaNo[4]; + private WazaNo[] m_addedWaza = new WazaNo[4]; private WazaNo[] m_removedWaza = new WazaNo[4]; private WazaNo[] m_addFailedWaza = new WazaNo[4]; @@ -1653,7 +2693,7 @@ private WazaNo get(WazaNo[] pArray, byte idx) { GFL.ASSERT(false); return WazaNo.NULL; - } + } } private byte getCount(WazaNo[] pArray) @@ -1669,4 +2709,4 @@ private byte getCount(WazaNo[] pArray) } } } -} \ No newline at end of file +} diff --git a/Assets/Scripts/Pml/PokePara/EvolveManager.cs b/Assets/Scripts/Pml/PokePara/EvolveManager.cs index 9826254fa..9e81393bd 100644 --- a/Assets/Scripts/Pml/PokePara/EvolveManager.cs +++ b/Assets/Scripts/Pml/PokePara/EvolveManager.cs @@ -1,3 +1,4 @@ +using Pml.Personal; using XLSXContent; namespace Pml.PokePara @@ -5,43 +6,201 @@ namespace Pml.PokePara public sealed class EvolveManager { public const ushort EVOLVE_FRIENDSHIP = 160; - + public EvolveManager() { // Empty, declared explicitly } - - // TODO - public MonsNo GetEvolvedMonsNo_byLevelUp(CoreParam poke, PokeParty party, EvolveSituation situation, ref uint root_num) { return default; } - - // TODO - public MonsNo GetEvolvedMonsNo_byEvent(CoreParam poke, PokeParty party, EvolveSituation situation, ref uint root_num) { return default; } - - // TODO - public MonsNo GetEvolvedMonsNo_byItem(CoreParam poke, EvolveSituation situation, uint use_item, ref uint root_num) { return default; } - - // TODO - public MonsNo GetEvolvedMonsNo_byTrade(CoreParam poke, CoreParam pair_poke, ref uint root_num) { return default; } - - // TODO - public bool HaveEvolutionRoot(CoreParam poke) { return default; } - - // TODO - protected bool CheckItem_KAWARAZUNOISHI(uint item) { return default; } - - // TODO - private bool canEvolve(CoreParam poke) { return default; } - - // TODO - private bool IsSatisfyEvolveConditionLevelUp(CoreParam poke, PokeParty party, EvolveSituation situation, EvolveTable.SheetEvolve evolveData, int evolveRouteIndex) { return default; } - - // TODO - private bool IsSatisfyEvolveConditionEvent(CoreParam poke, PokeParty party, EvolveSituation situation, EvolveTable.SheetEvolve evolveData, int evolveRouteIndex) { return default; } - - // TODO - private bool IsSatisfyEvolveConditionItem(CoreParam poke, EvolveSituation situation, uint use_item, EvolveTable.SheetEvolve evolveData, int evolveRouteIndex) { return default; } - - // TODO - private bool IsSatisfyEvolveConditionTrade(CoreParam poke, CoreParam pair_poke, EvolveTable.SheetEvolve evolveData, int evolveRouteIndex) { return default; } + + public MonsNo GetEvolvedMonsNo_byLevelUp(CoreParam poke, PokeParty party, EvolveSituation situation, ref uint root_num) + { + if (!canEvolve(poke)) + return MonsNo.NULL; + + if (poke.IsEgg(EggCheckType.BOTH_EGG)) + return MonsNo.NULL; + if (CheckItem_KAWARAZUNOISHI(poke.GetItem())) + return MonsNo.NULL; + + var evolveData = PersonalSystem.GetEvolutionTable(poke.GetMonsNo(), poke.GetFormNo()); + var routeNum = evolveData.GetEvolutionRouteNum(); + + for (int i = 0; i < routeNum; i++) + { + if (IsSatisfyEvolveConditionLevelUp(poke, party, situation, evolveData, i)) + { + root_num = (uint)i; + return evolveData.GetEvolvedMonsNo(i); + } + } + + return MonsNo.NULL; + } + + public MonsNo GetEvolvedMonsNo_byEvent(CoreParam poke, PokeParty party, EvolveSituation situation, ref uint root_num) + { + if (!canEvolve(poke)) + return MonsNo.NULL; + + if (poke.IsEgg(EggCheckType.BOTH_EGG)) + return MonsNo.NULL; + if (CheckItem_KAWARAZUNOISHI(poke.GetItem())) + return MonsNo.NULL; + + var evolveData = PersonalSystem.GetEvolutionTable(poke.GetMonsNo(), poke.GetFormNo()); + var routeNum = evolveData.GetEvolutionRouteNum(); + + for (int i = 0; i < routeNum; i++) + { + IsSatisfyEvolveConditionEvent(poke, party, situation, evolveData, i); + } + + return MonsNo.NULL; + } + + public MonsNo GetEvolvedMonsNo_byItem(CoreParam poke, EvolveSituation situation, uint use_item, ref uint root_num) + { + if (!canEvolve(poke)) + return MonsNo.NULL; + + if (poke.IsEgg(EggCheckType.BOTH_EGG)) + return MonsNo.NULL; + if (CheckItem_KAWARAZUNOISHI(poke.GetItem())) + return MonsNo.NULL; + + var evolveData = PersonalSystem.GetEvolutionTable(poke.GetMonsNo(), poke.GetFormNo()); + var routeNum = evolveData.GetEvolutionRouteNum(); + + for (int i = 0; i < routeNum; i++) + { + if (IsSatisfyEvolveConditionItem(poke, situation, use_item, evolveData, i)) + { + root_num = (uint)i; + return evolveData.GetEvolvedMonsNo(i); + } + } + + return MonsNo.NULL; + } + + public MonsNo GetEvolvedMonsNo_byTrade(CoreParam poke, CoreParam pair_poke, ref uint root_num) + { + if (!canEvolve(poke)) + return MonsNo.NULL; + + if (poke.IsEgg(EggCheckType.BOTH_EGG)) + return MonsNo.NULL; + if (poke.GetMonsNo() != MonsNo.YUNGERAA && CheckItem_KAWARAZUNOISHI(poke.GetItem())) + return MonsNo.NULL; + + var evolveData = PersonalSystem.GetEvolutionTable(poke.GetMonsNo(), poke.GetFormNo()); + var routeNum = evolveData.GetEvolutionRouteNum(); + + for (int i = 0; i < routeNum; i++) + { + if (IsSatisfyEvolveConditionTrade(poke, pair_poke, evolveData, i)) + { + root_num = (uint)i; + return evolveData.GetEvolvedMonsNo(i); + } + } + + return MonsNo.NULL; + } + + public bool HaveEvolutionRoot(CoreParam poke) + { + if (poke.IsSpecialGEnable()) + { + var monsno = poke.GetMonsNo(); + if (monsno == MonsNo.PIKATYUU || monsno == MonsNo.NYAASU || monsno == MonsNo.IIBUI) + return false; + } + var evolveData = PersonalSystem.GetEvolutionTable(poke.GetMonsNo(), poke.GetFormNo()); + return evolveData.GetEvolutionRouteNum() > 0; + } + + protected bool CheckItem_KAWARAZUNOISHI(uint item) + { + return item == (uint)ItemNo.KAWARAZUNOISI; + } + + private bool canEvolve(CoreParam poke) + { + if (poke.IsSpecialGEnable()) + { + var monsno = poke.GetMonsNo(); + if (monsno == MonsNo.PIKATYUU || monsno == MonsNo.NYAASU || monsno == MonsNo.IIBUI) + return false; + } + return true; + } + + private bool IsSatisfyEvolveConditionLevelUp(CoreParam poke, PokeParty party, EvolveSituation situation, EvolveTable.SheetEvolve evolveData, int evolveRouteIndex) + { + // TODO: Complex method with OT friendship logic, HaveCalcData checks, and jump table + return false; + } + + private bool IsSatisfyEvolveConditionEvent(CoreParam poke, PokeParty party, EvolveSituation situation, EvolveTable.SheetEvolve evolveData, int evolveRouteIndex) + { + // TODO: Binary shows this always returns false (event evolution not used in BDSP) + return false; + } + + private bool IsSatisfyEvolveConditionItem(CoreParam poke, EvolveSituation situation, uint use_item, EvolveTable.SheetEvolve evolveData, int evolveRouteIndex) + { + var cond = evolveData.GetEvolutionCondition(evolveRouteIndex); + var param = evolveData.GetEvolutionParam(evolveRouteIndex); + evolveData.GetEvolvedMonsNo(evolveRouteIndex); + evolveData.GetEvolveEnableLevel(evolveRouteIndex); + + switch (cond) + { + case EvolveCond.ITEM: + return param == use_item; + + case EvolveCond.ITEM_MALE: + return param == use_item && poke.GetSex() == Sex.MALE; + + case EvolveCond.ITEM_FEMALE: + return param == use_item && poke.GetSex() == Sex.FEMALE; + + case EvolveCond.PLACE_ULTRA_SPACE_ITEM: + return param == use_item && situation.isUltraSpace; + + default: + return false; + } + } + + private bool IsSatisfyEvolveConditionTrade(CoreParam poke, CoreParam pair_poke, EvolveTable.SheetEvolve evolveData, int evolveRouteIndex) + { + int cond = (int)evolveData.GetEvolutionCondition(evolveRouteIndex); + var param = evolveData.GetEvolutionParam(evolveRouteIndex); + evolveData.GetEvolvedMonsNo(evolveRouteIndex); + evolveData.GetEvolveEnableLevel(evolveRouteIndex); + + if (cond == 7) // EvolveCond.TUUSHIN_YUUGOU + { + if (pair_poke != null && pair_poke.GetItem() != (uint)ItemNo.KAWARAZUNOISI) + { + // Dead code in binary: calls IsTamago and IsFuseiTamago but discards results + pair_poke.IsEgg(EggCheckType.BOTH_EGG); + } + } + else + { + if (cond == 6) // EvolveCond.TUUSHIN_ITEM + { + return poke.GetItem() == param; + } + if (cond == 5) // EvolveCond.TUUSHIN + { + return true; + } + } + return false; + } } -} \ No newline at end of file +} diff --git a/Assets/Scripts/Pml/PokePara/SavePokeParty.cs b/Assets/Scripts/Pml/PokePara/SavePokeParty.cs index 555f3f95c..751a5c921 100644 --- a/Assets/Scripts/Pml/PokePara/SavePokeParty.cs +++ b/Assets/Scripts/Pml/PokePara/SavePokeParty.cs @@ -13,16 +13,44 @@ public struct SavePokeParty [SerializeField] private byte markingIndex; - // TODO - public void Serialize_Full(PokeParty party) { } + public void Serialize_Full(PokeParty party) + { + CreateWorkIfNeed(); + for (int i = 0; i < PokeParty.MAX_MEMBERS; i++) + { + var member = party.GetMemberPointer((uint)i); + member.Serialize_Full(ref members[i]); + } + memberCount = (byte)party.GetMemberCount(); + markingIndex = (byte)party.GetMarkingIndex(); + } - // TODO - public void Deserialize_Full(PokeParty party) { } + public void Deserialize_Full(PokeParty party) + { + CreateWorkIfNeed(); + for (int i = 0; i < PokeParty.MAX_MEMBERS; i++) + { + var pp = party.GetMemberPointer((uint)i); + pp.Deserialize_Full(members[i]); + } + party.SetMemberCount(memberCount); + party.SetMarkingIndex(markingIndex); + } - // TODO - public void CreateWorkIfNeed() { } + public void CreateWorkIfNeed() + { + if (members == null) + members = new SerializedPokemonFull[PokeParty.MAX_MEMBERS]; + for (int i = 0; i < members.Length; i++) + members[i].CreateWorkIfNeed(); + } - // TODO - public void Clear() { } + public void Clear() + { + members = null; + memberCount = 0; + markingIndex = 0; + CreateWorkIfNeed(); + } } } \ No newline at end of file diff --git a/Assets/Scripts/Pml/PokePara/SerializedPokemonCore.cs b/Assets/Scripts/Pml/PokePara/SerializedPokemonCore.cs index 3b89be68b..247bbb071 100644 --- a/Assets/Scripts/Pml/PokePara/SerializedPokemonCore.cs +++ b/Assets/Scripts/Pml/PokePara/SerializedPokemonCore.cs @@ -9,10 +9,15 @@ public struct SerializedPokemonCore [SerializeField] public byte[] buffer; - // TODO - public void CopyFrom(in SerializedPokemonCore src) { } - - // TODO - public void CreateWorkIfNeed(bool isRecreate = false) { } + public void CopyFrom(in SerializedPokemonCore src) + { + src.buffer.CopyTo(buffer, 0); + } + + public void CreateWorkIfNeed(bool isRecreate = false) + { + if (buffer == null || isRecreate) + buffer = new byte[CoreParam.DATASIZE]; + } } } \ No newline at end of file diff --git a/Assets/Scripts/Pml/PokePara/SerializedPokemonExtensions.cs b/Assets/Scripts/Pml/PokePara/SerializedPokemonExtensions.cs index 15cc6e1f9..d63bbd25e 100644 --- a/Assets/Scripts/Pml/PokePara/SerializedPokemonExtensions.cs +++ b/Assets/Scripts/Pml/PokePara/SerializedPokemonExtensions.cs @@ -2,16 +2,26 @@ { public static class SerializedPokemonExtensions { - // TODO - public static void Serialize_Full(this PokemonParam self, ref SerializedPokemonFull buffer) { } + public static void Serialize_Full(this PokemonParam self, ref SerializedPokemonFull buffer) + { + buffer.CreateWorkIfNeed(); + self.Serialize_Full(buffer.buffer); + } - // TODO - public static void Deserialize_Full(this PokemonParam self, in SerializedPokemonFull serializedData) { } + public static void Deserialize_Full(this PokemonParam self, in SerializedPokemonFull serializedData) + { + self.Deserialize_Full(serializedData.buffer); + } - // TODO - public static void Serialize_Core(this PokemonParam self, ref SerializedPokemonCore buffer) { } + public static void Serialize_Core(this PokemonParam self, ref SerializedPokemonCore buffer) + { + buffer.CreateWorkIfNeed(); + self.Serialize_Core(buffer.buffer); + } - // TODO - public static void Deserialize_Core(this PokemonParam self, in SerializedPokemonCore serializedData) { } + public static void Deserialize_Core(this PokemonParam self, in SerializedPokemonCore serializedData) + { + self.Deserialize_Core(serializedData.buffer); + } } } \ No newline at end of file diff --git a/Assets/Scripts/Pml/PokePara/SerializedPokemonFull.cs b/Assets/Scripts/Pml/PokePara/SerializedPokemonFull.cs index 7f34e0a13..af1ff279f 100644 --- a/Assets/Scripts/Pml/PokePara/SerializedPokemonFull.cs +++ b/Assets/Scripts/Pml/PokePara/SerializedPokemonFull.cs @@ -9,13 +9,26 @@ public struct SerializedPokemonFull [SerializeField] public byte[] buffer; - // TODO - public void CopyFrom(in SerializedPokemonFull src) { } + public void CopyFrom(in SerializedPokemonFull src) + { + src.buffer.CopyTo(buffer, 0); + } - // TODO - public static void Swap(ref SerializedPokemonFull lhs, ref SerializedPokemonFull rhs) { } + public static void Swap(ref SerializedPokemonFull lhs, ref SerializedPokemonFull rhs) + { + var temp = new byte[PokemonParam.DATASIZE]; + lhs.buffer.CopyTo(temp, 0); + rhs.buffer.CopyTo(lhs.buffer, 0); + temp.CopyTo(rhs.buffer, 0); + } - // TODO - public void CreateWorkIfNeed() { } + public void CreateWorkIfNeed() + { + if (buffer == null) + { + buffer = new byte[PokemonParam.DATASIZE]; + Accessor.updateChecksumAndEncode_Core(buffer); + } + } } } \ No newline at end of file diff --git a/Assets/Scripts/Pml/PokeParty.cs b/Assets/Scripts/Pml/PokeParty.cs index 03fb99a45..83ec1aad7 100644 --- a/Assets/Scripts/Pml/PokeParty.cs +++ b/Assets/Scripts/Pml/PokeParty.cs @@ -20,95 +20,270 @@ public PokeParty() m_member[5] = new PokemonParam(MonsNo.NULL, 1, 0); } - // TODO - public bool AddMember(PokemonParam pp) { return false; } + public bool AddMember(PokemonParam pp) + { + if (pp.GetMonsNo() == MonsNo.NULL) + return false; + if (IsFull()) + return false; + m_member[m_memberCount].CopyFrom(pp); + m_memberCount++; + return true; + } - // TODO - public void ReplaceMember(uint idx, PokemonParam pp) { } + public void ReplaceMember(uint idx, PokemonParam pp) + { + // TODO: Ghidra shows complex logic — checks source/dest MonsNo, Serialize/Deserialize, + // increments memberCount if replacing NULL with non-NULL, updates markingIndex via + // ClearMarkingIndex-like logic when markingIndex == idx + } - // TODO - public void RemoveMember(uint idx) { } + public void RemoveMember(uint idx) + { + // TODO: Ghidra shows complex logic — checks MonsNo, calls FieldWalkingManager.CheckPartnerPokeChange, + // gets ID/PersonalRnd for BallDecoWork.GetAttachCapsuleId/SetAttachCapsule, calls ClearData, + // scootOver, decrements memberCount, BallDecoWork.ScootOverCapsuleExtraData, markingIndex adjustment + } - // TODO - public void ExchangePosition(byte pos1, byte pos2) { } + public void ExchangePosition(byte pos1, byte pos2) + { + // TODO: Ghidra shows complex logic — sorts positions, swaps array references directly, + // calls scootOver, swaps markingIndex if either position matches, + // calls BallDecoWork.SwapCapsuleExtraData + } - // TODO - public PokemonParam GetMemberPointer(uint idx) { return null; } + public PokemonParam GetMemberPointer(uint idx) + { + return m_member[idx]; + } - // TODO - public PokemonParam GetMemberPointerConst(uint idx) { return null; } + public PokemonParam GetMemberPointerConst(uint idx) + { + return m_member[idx]; + } - // TODO - public uint GetMemberCount() { return 0; } + public uint GetMemberCount() + { + return m_memberCount; + } - // TODO - public void SetMemberCount(uint count) { } + public void SetMemberCount(uint count) + { + m_memberCount = count; + } - // TODO - public uint GetMemberIndex(PokemonParam pokeParam) { return 0; } + public uint GetMemberIndex(PokemonParam pokeParam) + { + for (uint i = 0; i < m_memberCount; i++) + { + if (m_member[i] == pokeParam) + return i; + } + return MEMBER_INDEX_ERROR; + } - // TODO - public uint GetMemberCountEx(CountType type) { return 0; } + public uint GetMemberCountEx(CountType type) + { + return GetMemberCountEx(type, 0); + } - // TODO - public uint GetMemberCountEx(CountType type, byte pass_idx_bit) { return 0; } + public uint GetMemberCountEx(CountType type, byte pass_idx_bit) + { + uint count = 0; + for (uint i = 0; i < m_memberCount; i++) + { + if ((pass_idx_bit & (1 << (int)i)) != 0) + continue; + + var member = m_member[i]; + if (member.GetMonsNo() == MonsNo.NULL) + continue; + + switch (type) + { + case CountType.ALL: + count++; + break; + case CountType.BATTLE_ENABLE: + if (!member.IsEgg(EggCheckType.BOTH_EGG) && (!member.HaveCalcParam() || member.GetHp() > 0)) + count++; + break; + case CountType.NOT_EGG: + if (!member.IsEgg(EggCheckType.BOTH_EGG)) + count++; + break; + case CountType.ONLY_LEGAL_EGG: + if (member.IsEgg(EggCheckType.ONLY_LEGAL_EGG)) + count++; + break; + case CountType.ONLY_ILLEGAL_EGG: + if (member.IsEgg(EggCheckType.ONLY_ILLEGAL_EGG)) + count++; + break; + case CountType.BOTH_EGG: + if (member.IsEgg(EggCheckType.BOTH_EGG)) + count++; + break; + } + } + return count; + } - // TODO - public uint GetMemberTopIndex(SearchType type) { return 0; } + public uint GetMemberTopIndex(SearchType type) + { + for (uint i = 0; i < m_memberCount; i++) + { + var member = m_member[i]; + if (member.GetMonsNo() == MonsNo.NULL) + continue; + + switch (type) + { + case SearchType.BATTLE_ENABLE: + if (!member.IsEgg(EggCheckType.BOTH_EGG) && (!member.HaveCalcParam() || member.GetHp() > 0)) + return i; + break; + case SearchType.NOT_EGG: + if (!member.IsEgg(EggCheckType.BOTH_EGG)) + return i; + break; + } + } + return MEMBER_INDEX_ERROR; + } - // TODO - public bool CheckPokeExist(MonsNo monsno) { return false; } + public bool CheckPokeExist(MonsNo monsno) + { + for (uint i = 0; i < m_memberCount; i++) + { + if (m_member[i].IsEgg(EggCheckType.BOTH_EGG)) + continue; + if (m_member[i].GetMonsNo() == monsno) + return true; + } + return false; + } - // TODO - public bool IsFull() { return false; } + public bool IsFull() + { + return m_memberCount >= MAX_MEMBERS; + } - // TODO - public void CopyFrom(PokeParty src) { } + public void CopyFrom(PokeParty src) + { + for (int i = 0; i < MAX_MEMBERS; i++) + { + m_member[i].CopyFrom(src.m_member[i]); + } + m_memberCount = src.m_memberCount; + } - // TODO - public void Clear() { } + public void Clear() + { + for (int i = 0; i < MAX_MEMBERS; i++) + { + m_member[i].Clear(); + } + m_memberCount = 0; + ClearMarkingIndex(); + } - // TODO - public void SerializeFull(ref SavePokeParty save) { } + public void SerializeFull(ref SavePokeParty save) + { + save.Serialize_Full(this); + } - // TODO - public void DeserializeFull(ref SavePokeParty save) { } + public void DeserializeFull(ref SavePokeParty save) + { + save.Deserialize_Full(this); + } - // TODO - public bool CheckPokerusExist() { return false; } + public bool CheckPokerusExist() + { + for (uint i = 0; i < m_memberCount; i++) + { + if (m_member[i].GetPokerus() != 0) + return true; + } + return false; + } - // TODO - public bool PokerusCatchCheck() { return false; } + public bool PokerusCatchCheck() + { + // TODO: Ghidra shows completely different algorithm — uses Pml.Local.Random.GetValue, + // checks for specific values (0x4000, 0xc000, 0x8000 from range 0x10000), + // loops to find non-legal-egg with MonsNo != 0, different strain/days calculation + return false; + } - // TODO - public bool PokerusInfectionCheck() { return false; } + public bool PokerusInfectionCheck() + { + // TODO: Ghidra shows different algorithm — uses Pml.Local.Random.GetValue(3) for 1/3 chance, + // copies full pokerus value (not recalculated strain/days) to adjacent members, + // extra index increment when infecting forward neighbor, checks (pokerus & 0xf) != 0 + return false; + } - // TODO - public void DecreasePokerusDayCount(int passed_day_count) { } + public void DecreasePokerusDayCount(int passed_day_count) + { + // TODO: Ghidra shows two separate paths — if passed_day_count < 5: subtract days with + // clamping, preserve strain (or set to 0x10 if strain was 0), assert result != 0; + // if passed_day_count >= 5: zero out days completely, keep strain, assert strain != 0 + } - // TODO - public void RecoverAll() { } + public void RecoverAll() + { + for (uint i = 0; i < m_memberCount; i++) + { + m_member[i].RecoverAll(); + } + } - // TODO - public void SetMarkingIndex(uint pos) { } + public void SetMarkingIndex(uint pos) + { + markingIndex = (byte)pos; + } - // TODO - public uint GetMarkingIndex() { return 0; } + public uint GetMarkingIndex() + { + return markingIndex; + } - // TODO - public bool CanTrade() { return false; } + public bool CanTrade() + { + if (GetMemberCountEx(CountType.ONLY_ILLEGAL_EGG) != 0) + return false; + uint eggCount = GetMemberCountEx(CountType.BOTH_EGG); + return (uint)(m_memberCount - eggCount) > 1; + } - // TODO - public bool CanTradeMember(uint idx) { return false; } + public bool CanTradeMember(uint idx) + { + return GetMemberCountEx(CountType.BATTLE_ENABLE, (byte)(1 << (int)(idx & 0x1f))) != 0; + } - // TODO - private void Dump() { } + private void Dump() + { + } - // TODO - private void scootOver() { } + private void scootOver() + { + // TODO: Ghidra shows reverse iteration pattern (from index 4 down to 0), finds NULL entries + // and shifts non-NULL entries from end to fill gaps, with array reference swapping + } - // TODO - private void ClearMarkingIndex() { } + private void ClearMarkingIndex() + { + for (uint i = 0; i < m_memberCount; i++) + { + if (!m_member[i].IsEgg(EggCheckType.BOTH_EGG)) + { + markingIndex = (byte)i; + return; + } + } + markingIndex = 0; + } public enum CountType : int { @@ -126,4 +301,4 @@ public enum SearchType : int NOT_EGG = 1, } } -} \ No newline at end of file +} diff --git a/Assets/Scripts/Pml/WazaData/SickContParam.cs b/Assets/Scripts/Pml/WazaData/SickContParam.cs index 4b15b8bcd..832e8bab9 100644 --- a/Assets/Scripts/Pml/WazaData/SickContParam.cs +++ b/Assets/Scripts/Pml/WazaData/SickContParam.cs @@ -13,9 +13,22 @@ public struct SickContParam private const int mask2 = 64512; public ushort raw; - // TODO - public byte type { get; set; } - public byte turnMin { get; set; } - public byte turnMax { get; set; } + public byte type + { + get => (byte)((raw & mask0) >> loc0); + set => raw = (ushort)((raw & ~mask0) | ((value << loc0) & mask0)); + } + + public ushort turnMin + { + get => (ushort)((raw & mask1) >> loc1); + set => raw = (ushort)((raw & ~mask1) | ((value << loc1) & mask1)); + } + + public ushort turnMax + { + get => (ushort)((raw & mask2) >> loc2); + set => raw = (ushort)((raw & ~mask2) | ((value << loc2) & mask2)); + } } -} \ No newline at end of file +} diff --git a/Assets/Scripts/Pml/WazaData/WazaDataSystem.cs b/Assets/Scripts/Pml/WazaData/WazaDataSystem.cs index 5118dac47..595152249 100644 --- a/Assets/Scripts/Pml/WazaData/WazaDataSystem.cs +++ b/Assets/Scripts/Pml/WazaData/WazaDataSystem.cs @@ -24,11 +24,17 @@ public static WazaTable.SheetWaza Get(WazaNo id) return s_wazaTable.Waza[(int)id]; } - // TODO - public static bool IsValid(WazaNo id) { return false; } + public static bool IsValid(WazaNo id) + { + if (id <= WazaNo.NULL || (int)id >= s_wazaTable.Waza.Length) + return false; + return Get(id).isValid; + } - // TODO - public static bool GetFlag(WazaNo id, WazaFlag flag) { return false; } + public static bool GetFlag(WazaNo id, WazaFlag flag) + { + return (Get(id).flags & (1u << (int)flag)) != 0; + } public static uint GetMaxPP(WazaNo id, uint maxupcnt) { @@ -38,26 +44,43 @@ public static uint GetMaxPP(WazaNo id, uint maxupcnt) return (maxupcnt * basePP * 20 / 100 + basePP) & 0xFF; } - // TODO - public static uint GetPower(WazaNo id) { return 0; } + public static uint GetPower(WazaNo id) + { + return Get(id).power; + } - // TODO - public static byte GetType(WazaNo id) { return 0; } + public static byte GetType(WazaNo id) + { + return Get(id).type; + } - // TODO - public static WazaDamageType GetDamageType(WazaNo id) { return 0; } + public static WazaDamageType GetDamageType(WazaNo id) + { + return (WazaDamageType)Get(id).damageType; + } - // TODO - public static WazaCategory GetCategory(WazaNo id) { return WazaCategory.SIMPLE_DAMAGE; } + public static WazaCategory GetCategory(WazaNo id) + { + return (WazaCategory)Get(id).category; + } - // TODO - public static int GetPriority(WazaNo id) { return 0; } + public static int GetPriority(WazaNo id) + { + return Get(id).priority; + } - // TODO - public static ushort GetHitPer(WazaNo id) { return 0; } + public static ushort GetHitPer(WazaNo id) + { + var hitPer = Get(id).hitPer; + if (hitPer == HITRATIO_MUST) + return 100; + return hitPer; + } - // TODO - public static bool IsAlwaysHit(WazaNo id) { return false; } + public static bool IsAlwaysHit(WazaNo id) + { + return Get(id).hitPer == HITRATIO_MUST; + } public static uint GetHitCountMax(WazaNo id) { @@ -69,68 +92,160 @@ public static uint GetHitCountMin(WazaNo id) return Get(id).hitCountMin; } - // TODO - public static bool IsMustCritical(WazaNo id) { return false; } + public static bool IsMustCritical(WazaNo id) + { + return Get(id).criticalRank == CRITICAL_MUST; + } - // TODO - public static uint GetShrinkPer(WazaNo id) { return 0; } + public static uint GetShrinkPer(WazaNo id) + { + return Get(id).shrinkPer; + } - // TODO - public static bool IsDamage(WazaNo id) { return false; } + public static bool IsDamage(WazaNo id) + { + return GetPower(id) != 0; + } - // TODO - public static byte GetCriticalRank(WazaNo id) { return 0; } + public static byte GetCriticalRank(WazaNo id) + { + return Get(id).criticalRank; + } - // TODO - public static WazaWeather GetWeather(WazaNo wazano) { return default; } + public static WazaWeather GetWeather(WazaNo wazano) + { + switch (wazano) + { + case WazaNo.NIHONBARE: return WazaWeather.SHINE; + case WazaNo.AMAGOI: return WazaWeather.RAIN; + case WazaNo.ARARE: return WazaWeather.SNOW; + case WazaNo.SUNAARASI: return WazaWeather.SAND; + default: return WazaWeather.NONE; + } + } - // TODO - public static WazaSick GetSick(WazaNo id) { return WazaSick.WAZASICK_NONE; } + public static WazaSick GetSick(WazaNo id) + { + return (WazaSick)Get(id).sickID; + } - // TODO - public static int GetSickPer(WazaNo id) { return 0; } + public static int GetSickPer(WazaNo id) + { + return Get(id).sickPer; + } - // TODO - public static SickContParam GetSickCont(WazaNo id) { return default; } + public static SickContParam GetSickCont(WazaNo id) + { + var waza = Get(id); + var param = new SickContParam(); + param.type = waza.sickCont; + param.turnMin = waza.sickTurnMin; + param.turnMax = waza.sickTurnMax; + return param; + } - // TODO - public static byte GetRankEffectCount(WazaNo id) { return 0; } + public static byte GetRankEffectCount(WazaNo id) + { + var waza = Get(id); + byte count = 0; + if (waza.rankEffType1 != (byte)WazaRankEffect.NONE) count++; + if (waza.rankEffType2 != (byte)WazaRankEffect.NONE) count++; + if (waza.rankEffType3 != (byte)WazaRankEffect.NONE) count++; + return count; + } - // TODO public static WazaRankEffect GetRankEffect(WazaNo id, uint idx, out int volume) { volume = 0; - return WazaRankEffect.NONE; + if (idx >= RANK_STORE_MAX) + { + GFL.ASSERT(false); + return WazaRankEffect.NONE; + } + + var waza = Get(id); + byte type; + switch (idx) + { + case 0: type = waza.rankEffType1; break; + case 1: type = waza.rankEffType2; break; + case 2: type = waza.rankEffType3; break; + default: return WazaRankEffect.NONE; + } + + if (type == (byte)WazaRankEffect.NONE) + return WazaRankEffect.NONE; + + switch (idx) + { + case 0: volume = waza.rankEffValue1; break; + case 1: volume = waza.rankEffValue2; break; + case 2: volume = waza.rankEffValue3; break; + } + return (WazaRankEffect)type; } - // TODO - public static int GetRankEffectPer(WazaNo id, uint idx) { return 0; } + public static int GetRankEffectPer(WazaNo id, uint idx) + { + var waza = Get(id); + switch (idx) + { + case 0: return waza.rankEffPer1; + case 1: return waza.rankEffPer2; + case 2: return waza.rankEffPer3; + default: return 0; + } + } - // TODO - public static uint GetDamageRecoverRatio(WazaNo id) { return 0; } + public static uint GetDamageRecoverRatio(WazaNo id) + { + uint val = (uint)Get(id).damageRecoverRatio; + return val & (uint)((int)val >> 31 ^ ~0); + } - // TODO - public static uint GetHPRecoverRatio(WazaNo id) { return 0; } + public static uint GetHPRecoverRatio(WazaNo id) + { + uint val = (uint)Get(id).hpRecoverRatio; + return val & (uint)((int)val >> 31 ^ ~0); + } - // TODO - public static WazaTarget GetTarget(WazaNo id) { return WazaTarget.TARGET_OTHER_SELECT; } + public static WazaTarget GetTarget(WazaNo id) + { + return (WazaTarget)Get(id).target; + } - // TODO - public static int GetAISeqNo(WazaNo id) { return 0; } + public static int GetAISeqNo(WazaNo id) + { + return Get(id).aiSeqNo; + } - // TODO - public static byte GetDamageReactionRatio(WazaNo id) { return 0; } + public static uint GetDamageReactionRatio(WazaNo id) + { + int val = (int)Get(id).damageRecoverRatio; + return (uint)(-val & (val >> 7)); + } - // TODO - public static byte GetHPReactionRatio(WazaNo id) { return 0; } + public static uint GetHPReactionRatio(WazaNo id) + { + int val = (int)Get(id).hpRecoverRatio; + return (uint)(-val & (val >> 7)); + } - // TODO - public static byte GetGPower(WazaNo id) { return 0; } + public static byte GetGPower(WazaNo id) + { + return 0; + } - // TODO - public static ushort[] GetYubiWoHuruPermitWazaTable() { return null; } + public static ushort[] GetYubiWoHuruPermitWazaTable() + { + if (s_wazaTable.Yubiwohuru != null && s_wazaTable.Yubiwohuru.Length > 0) + return s_wazaTable.Yubiwohuru[0].wazaNos; + return null; + } - // TODO - public static uint GetContestWazaNo(WazaNo id) { return 0; } + public static uint GetContestWazaNo(WazaNo id) + { + return Get(id).contestWazaNo; + } } -} \ No newline at end of file +} From 6981f5336859dfe81967817d9d64e9af66af7b5e Mon Sep 17 00:00:00 2001 From: AstrandPallas Date: Tue, 10 Feb 2026 00:43:45 -0800 Subject: [PATCH 2/3] Address PR #5 round 2 review comments - CoreDataBlockA: fix all boolean getters from >> loc & sz to (& mask) >> loc - CoreDataBlockA: remove unnecessary casts from camp_friendship - CoreDataBlockB: remove unnecessary casts from talent getters - CoreDataBlockB: add right bitshift to tamagoFlag/nicknameFlag getters - Accessor: init static fields to null per .cctor - Accessor: inline BLOCK_POS_TABLE as 32-entry static array - Accessor: add fast mode checks to ClearCalcData - Accessor: add GFL.ASSERT to StartFastMode/EndFastMode - Accessor: add asserts + delegate to unsafe in Serialize/Deserialize byte[] overloads - Accessor: simplify unsafe Serialize/Deserialize pointer arithmetic - Accessor: rewrite private Serialize/Deserialize with UnsafeUtility.MemCpy - Accessor: remove Decode/Encode from GetCoreDataBlockX infrastructure - Accessor: add DecodeAndCheckIllegalWrite/UpdateChecksumAndEncode to all getters/setters - Accessor: add m_pCalcData null checks to all CalcData getters - Accessor: fix GetDprIllegalFlag to use forWrite=true - Accessor: add GFL.ASSERT(false) to error/default paths - Accessor: replace GetBankUniqueID loop with pointer cast - Accessor: use .Equals() for CompareOyaName --- Assets/Scripts/Pml/PokePara/Accessor.cs | 1048 +++++++++++++---- Assets/Scripts/Pml/PokePara/CoreDataBlockA.cs | 22 +- Assets/Scripts/Pml/PokePara/CoreDataBlockB.cs | 32 +- 3 files changed, 816 insertions(+), 286 deletions(-) diff --git a/Assets/Scripts/Pml/PokePara/Accessor.cs b/Assets/Scripts/Pml/PokePara/Accessor.cs index 7e5fbb90c..aa2cee488 100644 --- a/Assets/Scripts/Pml/PokePara/Accessor.cs +++ b/Assets/Scripts/Pml/PokePara/Accessor.cs @@ -1,5 +1,6 @@ using System; using System.Runtime.InteropServices; +using Unity.Collections.LowLevel.Unsafe; using Pml; namespace Pml.PokePara @@ -22,10 +23,10 @@ public class Accessor private const uint MAX_RIBBON_NO_ON_RIBBON_FIELD_2 = 63; private const uint MAX_RIBBON_NO_ON_RIBBON_FIELD_3 = 95; private const uint MAX_RIBBON_NO_ON_RIBBON_FIELD_4 = 127; - private static unsafe byte* IllegalCoreData; - private static unsafe byte* DummyWriteCoreData; - private static unsafe byte* IllegalCalcData; - private static unsafe byte* DummyWriteCalcData; + private static unsafe byte* IllegalCoreData = null; + private static unsafe byte* DummyWriteCoreData = null; + private static unsafe byte* IllegalCalcData = null; + private static unsafe byte* DummyWriteCalcData = null; private byte[] m_pCalcData; private byte[] m_pCoreData; private AccessState m_accessState; @@ -33,44 +34,41 @@ public class Accessor private const byte POS2 = 1; private const byte POS3 = 2; private const byte POS4 = 3; - private static readonly byte[][] BLOCK_POS_TABLE = GenerateBlockPosTable(); - - private static byte[][] GenerateBlockPosTable() - { - byte[][] order = new byte[24][] - { - new byte[] { 0, 1, 2, 3 }, - new byte[] { 0, 1, 3, 2 }, - new byte[] { 0, 2, 1, 3 }, - new byte[] { 0, 2, 3, 1 }, - new byte[] { 0, 3, 1, 2 }, - new byte[] { 0, 3, 2, 1 }, - new byte[] { 1, 0, 2, 3 }, - new byte[] { 1, 0, 3, 2 }, - new byte[] { 1, 2, 0, 3 }, - new byte[] { 1, 2, 3, 0 }, - new byte[] { 1, 3, 0, 2 }, - new byte[] { 1, 3, 2, 0 }, - new byte[] { 2, 0, 1, 3 }, - new byte[] { 2, 0, 3, 1 }, - new byte[] { 2, 1, 0, 3 }, - new byte[] { 2, 1, 3, 0 }, - new byte[] { 2, 3, 0, 1 }, - new byte[] { 2, 3, 1, 0 }, - new byte[] { 3, 0, 1, 2 }, - new byte[] { 3, 0, 2, 1 }, - new byte[] { 3, 1, 0, 2 }, - new byte[] { 3, 1, 2, 0 }, - new byte[] { 3, 2, 0, 1 }, - new byte[] { 3, 2, 1, 0 }, - }; - - byte[][] table = new byte[32][]; - for (int i = 0; i < 32; i++) - table[i] = order[i % 24]; - - return table; - } + private static readonly byte[][] BLOCK_POS_TABLE = new byte[][] + { + new byte[] { POS1, POS2, POS3, POS4 }, + new byte[] { POS1, POS2, POS4, POS3 }, + new byte[] { POS1, POS3, POS2, POS4 }, + new byte[] { POS1, POS4, POS2, POS3 }, + new byte[] { POS1, POS3, POS4, POS2 }, + new byte[] { POS1, POS4, POS3, POS2 }, + new byte[] { POS2, POS1, POS3, POS4 }, + new byte[] { POS2, POS1, POS4, POS3 }, + new byte[] { POS3, POS1, POS2, POS4 }, + new byte[] { POS4, POS1, POS2, POS3 }, + new byte[] { POS3, POS1, POS4, POS2 }, + new byte[] { POS4, POS1, POS3, POS2 }, + new byte[] { POS2, POS3, POS1, POS4 }, + new byte[] { POS2, POS4, POS1, POS3 }, + new byte[] { POS3, POS2, POS1, POS4 }, + new byte[] { POS4, POS2, POS1, POS3 }, + new byte[] { POS3, POS4, POS1, POS2 }, + new byte[] { POS4, POS3, POS1, POS2 }, + new byte[] { POS2, POS3, POS4, POS1 }, + new byte[] { POS2, POS4, POS3, POS1 }, + new byte[] { POS3, POS2, POS4, POS1 }, + new byte[] { POS4, POS2, POS3, POS1 }, + new byte[] { POS3, POS4, POS2, POS1 }, + new byte[] { POS4, POS3, POS2, POS1 }, + new byte[] { POS1, POS2, POS3, POS4 }, + new byte[] { POS1, POS2, POS4, POS3 }, + new byte[] { POS1, POS3, POS2, POS4 }, + new byte[] { POS1, POS4, POS2, POS3 }, + new byte[] { POS1, POS3, POS4, POS2 }, + new byte[] { POS1, POS4, POS3, POS2 }, + new byte[] { POS2, POS1, POS3, POS4 }, + new byte[] { POS2, POS1, POS4, POS3 }, + }; public static void Initialize() { } @@ -111,20 +109,35 @@ public void ClearData() public void ClearCalcData() { - if (m_pCalcData != null) + if (m_pCalcData == null) + return; + if (IsFastMode()) + { + Array.Clear(m_pCalcData, 0, m_pCalcData.Length); + } + else + { + StartFastMode(); Array.Clear(m_pCalcData, 0, m_pCalcData.Length); + EndFastMode(); + } } public void StartFastMode() { DecodeAndCheckIllegalWrite(); m_accessState.isFastMode = true; + GFL.ASSERT(!IsEncoded()); } public void EndFastMode() { m_accessState.isFastMode = false; UpdateChecksumAndEncode(); + if (IsFastMode()) + GFL.ASSERT(false); + else + GFL.ASSERT(IsEncoded()); } public bool IsFastMode() @@ -139,51 +152,31 @@ public bool IsEncoded() public void Serialize_FullData(byte[] buffer) { - unsafe - { - fixed (byte* dst = buffer) - { - Serialize(dst, dst + CORE_SERIALIZE_DATA_SIZE); - } - } + GFL.ASSERT(buffer.Length >= FULL_SERIALIZE_DATA_SIZE); + unsafe { fixed (byte* dst = buffer) Serialize_FullData(dst); } } public void Serialize_CoreData(byte[] buffer) { - unsafe - { - fixed (byte* dst = buffer) - { - Serialize(dst, null); - } - } + GFL.ASSERT(buffer.Length >= CORE_SERIALIZE_DATA_SIZE); + unsafe { fixed (byte* dst = buffer) Serialize_CoreData(dst); } } public void Deserialize_FullData(byte[] serializedData) { - unsafe - { - fixed (byte* src = serializedData) - { - Deserialize(src, src + CORE_SERIALIZE_DATA_SIZE); - } - } + GFL.ASSERT(serializedData.Length >= FULL_SERIALIZE_DATA_SIZE); + unsafe { fixed (byte* src = serializedData) Deserialize_FullData(src); } } public void Deserialize_CoreData(byte[] serializedData) { - unsafe - { - fixed (byte* src = serializedData) - { - Deserialize(src, null); - } - } + GFL.ASSERT(serializedData.Length >= CORE_SERIALIZE_DATA_SIZE); + unsafe { fixed (byte* src = serializedData) Deserialize_CoreData(src); } } public unsafe void Serialize_FullData(void* buffer) { - Serialize(buffer, (void*)((long)buffer + CORE_SERIALIZE_DATA_SIZE)); + Serialize(buffer, (byte*)buffer + CORE_SERIALIZE_DATA_SIZE); } public unsafe void Serialize_CoreData(void* buffer) @@ -193,7 +186,7 @@ public unsafe void Serialize_CoreData(void* buffer) public unsafe void Deserialize_FullData(void* serializedData) { - Deserialize(serializedData, (void*)((long)serializedData + CORE_SERIALIZE_DATA_SIZE)); + Deserialize(serializedData, (byte*)serializedData + CORE_SERIALIZE_DATA_SIZE); } public unsafe void Deserialize_CoreData(void* serializedData) @@ -211,8 +204,11 @@ public uint GetPersonalRnd() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var header = GetCoreDataHeader(addr); - return header->personalRnd; + var value = header->personalRnd; + UpdateChecksumAndEncode(); + return value; } } } @@ -223,8 +219,11 @@ public uint GetCheckSum() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var header = GetCoreDataHeader(addr); - return header->checksum; + var value = header->checksum; + UpdateChecksumAndEncode(); + return value; } } } @@ -235,8 +234,11 @@ public bool IsFuseiTamago() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var header = GetCoreDataHeader(addr); - return header->fuseiTamagoFlag; + var value = header->fuseiTamagoFlag; + UpdateChecksumAndEncode(); + return value; } } } @@ -251,8 +253,11 @@ public MonsNo GetMonsNo() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, false); - return (MonsNo)block->monsno; + var value = (MonsNo)block->monsno; + UpdateChecksumAndEncode(); + return value; } } } @@ -263,8 +268,11 @@ public uint GetItemNo() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, false); - return block->itemno; + var value = (uint)block->itemno; + UpdateChecksumAndEncode(); + return value; } } } @@ -275,8 +283,11 @@ public uint GetID() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, false); - return block->id; + var value = block->id; + UpdateChecksumAndEncode(); + return value; } } } @@ -287,8 +298,11 @@ public uint GetExp() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, false); - return block->exp; + var value = block->exp; + UpdateChecksumAndEncode(); + return value; } } } @@ -299,8 +313,11 @@ public TokuseiNo GetTokuseiNo() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, false); - return (TokuseiNo)block->tokuseino; + var value = (TokuseiNo)block->tokuseino; + UpdateChecksumAndEncode(); + return value; } } } @@ -311,8 +328,11 @@ public ushort GetBoxMark() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, false); - return block->boxMark; + var value = block->boxMark; + UpdateChecksumAndEncode(); + return value; } } } @@ -323,8 +343,11 @@ public uint GetColorRnd() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, false); - return block->colorRnd; + var value = block->colorRnd; + UpdateChecksumAndEncode(); + return value; } } } @@ -335,8 +358,11 @@ public uint GetSeikaku() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, false); - return block->seikaku; + var value = (uint)block->seikaku; + UpdateChecksumAndEncode(); + return value; } } } @@ -347,8 +373,11 @@ public uint GetSeikakuHosei() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, false); - return block->seikakuHosei; + var value = (uint)block->seikakuHosei; + UpdateChecksumAndEncode(); + return value; } } } @@ -359,8 +388,11 @@ public ushort GetFormNo() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, false); - return block->formNo; + var value = block->formNo; + UpdateChecksumAndEncode(); + return value; } } } @@ -371,8 +403,11 @@ public uint GetEffortHp() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, false); - return block->effortHp; + var value = (uint)block->effortHp; + UpdateChecksumAndEncode(); + return value; } } } @@ -383,8 +418,11 @@ public uint GetEffortAtk() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, false); - return block->effortAtk; + var value = (uint)block->effortAtk; + UpdateChecksumAndEncode(); + return value; } } } @@ -395,8 +433,11 @@ public uint GetEffortDef() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, false); - return block->effortDef; + var value = (uint)block->effortDef; + UpdateChecksumAndEncode(); + return value; } } } @@ -407,8 +448,11 @@ public uint GetEffortAgi() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, false); - return block->effortAgi; + var value = (uint)block->effortAgi; + UpdateChecksumAndEncode(); + return value; } } } @@ -419,8 +463,11 @@ public uint GetEffortSpAtk() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, false); - return block->effortSpatk; + var value = (uint)block->effortSpatk; + UpdateChecksumAndEncode(); + return value; } } } @@ -431,8 +478,11 @@ public uint GetEffortSpDef() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, false); - return block->effortSpdef; + var value = (uint)block->effortSpdef; + UpdateChecksumAndEncode(); + return value; } } } @@ -443,8 +493,11 @@ public byte GetStyle() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, false); - return block->style; + var value = block->style; + UpdateChecksumAndEncode(); + return value; } } } @@ -455,8 +508,11 @@ public byte GetBeautiful() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, false); - return block->beautiful; + var value = block->beautiful; + UpdateChecksumAndEncode(); + return value; } } } @@ -467,8 +523,11 @@ public byte GetCute() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, false); - return block->cute; + var value = block->cute; + UpdateChecksumAndEncode(); + return value; } } } @@ -479,8 +538,11 @@ public byte GetClever() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, false); - return block->clever; + var value = block->clever; + UpdateChecksumAndEncode(); + return value; } } } @@ -491,8 +553,11 @@ public byte GetStrong() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, false); - return block->strong; + var value = block->strong; + UpdateChecksumAndEncode(); + return value; } } } @@ -503,8 +568,11 @@ public byte GetFur() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, false); - return block->fur; + var value = block->fur; + UpdateChecksumAndEncode(); + return value; } } } @@ -515,8 +583,11 @@ public uint GetPokerus() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, false); - return block->pokerus; + var value = (uint)block->pokerus; + UpdateChecksumAndEncode(); + return value; } } } @@ -527,8 +598,11 @@ public bool IsTokusei1() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, false); - return block->tokusei1Flag; + var value = block->tokusei1Flag; + UpdateChecksumAndEncode(); + return value; } } } @@ -539,8 +613,11 @@ public bool IsTokusei2() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, false); - return block->tokusei2Flag; + var value = block->tokusei2Flag; + UpdateChecksumAndEncode(); + return value; } } } @@ -551,8 +628,11 @@ public bool IsTokusei3() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, false); - return block->tokusei3Flag; + var value = block->tokusei3Flag; + UpdateChecksumAndEncode(); + return value; } } } @@ -563,8 +643,11 @@ public bool IsFavorite() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, false); - return block->favoriteFlag; + var value = block->favoriteFlag; + UpdateChecksumAndEncode(); + return value; } } } @@ -575,8 +658,11 @@ public bool IsSpecialGEnable() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, false); - return block->special_g_flag; + var value = block->special_g_flag; + UpdateChecksumAndEncode(); + return value; } } } @@ -587,8 +673,11 @@ public bool IsEventPokemon() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, false); - return block->eventGetFlag; + var value = block->eventGetFlag; + UpdateChecksumAndEncode(); + return value; } } } @@ -599,8 +688,11 @@ public bool GetOfficialBattleEnableFlag() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, false); - return block->officialBattleEnableFlag; + var value = block->officialBattleEnableFlag; + UpdateChecksumAndEncode(); + return value; } } } @@ -611,8 +703,11 @@ public Sex GetSex() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, false); - return (Sex)block->sex; + var value = (Sex)block->sex; + UpdateChecksumAndEncode(); + return value; } } } @@ -623,8 +718,11 @@ public byte GetCampFriendship() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, false); - return (byte)block->camp_friendship; + var value = (byte)block->camp_friendship; + UpdateChecksumAndEncode(); + return value; } } } @@ -635,8 +733,11 @@ public bool GetDprIllegalFlag() { fixed (byte* addr = m_pCoreData) { - var block = GetCoreDataBlockA(addr, false); - return block->dpr_illegal_flag; + DecodeAndCheckIllegalWrite(); + var block = GetCoreDataBlockA(addr, true); + var value = block->dpr_illegal_flag; + UpdateChecksumAndEncode(); + return value; } } } @@ -647,8 +748,11 @@ public byte GetTalentHeight() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, false); - return block->talentHeight; + var value = block->talentHeight; + UpdateChecksumAndEncode(); + return value; } } } @@ -659,8 +763,11 @@ public byte GetTalentWeight() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, false); - return block->talentWeight; + var value = block->talentWeight; + UpdateChecksumAndEncode(); + return value; } } } @@ -671,17 +778,21 @@ public bool HaveRibbon(uint ribbonNo) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, false); + bool value; if (ribbonNo <= MAX_RIBBON_NO_ON_RIBBON_FIELD_1) - return (block->ribbonA & (1u << (int)(ribbonNo - MIN_RIBBON_NO_ON_RIBBON_FIELD_1))) != 0; + value = (block->ribbonA & (1u << (int)(ribbonNo - MIN_RIBBON_NO_ON_RIBBON_FIELD_1))) != 0; else if (ribbonNo <= MAX_RIBBON_NO_ON_RIBBON_FIELD_2) - return (block->ribbonB & (1u << (int)(ribbonNo - MIN_RIBBON_NO_ON_RIBBON_FIELD_2))) != 0; + value = (block->ribbonB & (1u << (int)(ribbonNo - MIN_RIBBON_NO_ON_RIBBON_FIELD_2))) != 0; else if (ribbonNo <= MAX_RIBBON_NO_ON_RIBBON_FIELD_3) - return (block->ribbonC & (1u << (int)(ribbonNo - MIN_RIBBON_NO_ON_RIBBON_FIELD_3))) != 0; + value = (block->ribbonC & (1u << (int)(ribbonNo - MIN_RIBBON_NO_ON_RIBBON_FIELD_3))) != 0; else if (ribbonNo <= MAX_RIBBON_NO_ON_RIBBON_FIELD_4) - return (block->ribbonD & (1u << (int)(ribbonNo - MIN_RIBBON_NO_ON_RIBBON_FIELD_4))) != 0; - - return false; + value = (block->ribbonD & (1u << (int)(ribbonNo - MIN_RIBBON_NO_ON_RIBBON_FIELD_4))) != 0; + else + value = false; + UpdateChecksumAndEncode(); + return value; } } } @@ -692,16 +803,24 @@ public uint GetLumpingRibbon(LumpingRibbon ribbonId) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, false); + uint value; switch (ribbonId) { case LumpingRibbon.A: - return block->lumpingRibbonA; + value = block->lumpingRibbonA; + break; case LumpingRibbon.B: - return block->lumpingRibbonB; + value = block->lumpingRibbonB; + break; default: - return 0; + GFL.ASSERT(false); + value = 0; + break; } + UpdateChecksumAndEncode(); + return value; } } } @@ -716,8 +835,11 @@ public uint GetSick() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockB(addr, false); - return block->sick; + var value = block->sick; + UpdateChecksumAndEncode(); + return value; } } } @@ -728,10 +850,18 @@ public WazaNo GetWazaNo(byte wazaIndex) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockB(addr, false); + WazaNo value; if (wazaIndex < PmlConstants.MAX_WAZA_NUM) - return (WazaNo)block->waza[wazaIndex]; - return WazaNo.NULL; + value = (WazaNo)block->waza[wazaIndex]; + else + { + GFL.ASSERT(false); + value = WazaNo.NULL; + } + UpdateChecksumAndEncode(); + return value; } } } @@ -742,10 +872,18 @@ public byte GetPP(byte wazaIndex) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockB(addr, false); + byte value; if (wazaIndex < PmlConstants.MAX_WAZA_NUM) - return block->pp[wazaIndex]; - return 0; + value = block->pp[wazaIndex]; + else + { + GFL.ASSERT(false); + value = 0; + } + UpdateChecksumAndEncode(); + return value; } } } @@ -756,10 +894,18 @@ public byte GetWazaPPUpCount(byte wazaIndex) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockB(addr, false); + byte value; if (wazaIndex < PmlConstants.MAX_WAZA_NUM) - return block->pointupUsedCount[wazaIndex]; - return 0; + value = block->pointupUsedCount[wazaIndex]; + else + { + GFL.ASSERT(false); + value = 0; + } + UpdateChecksumAndEncode(); + return value; } } } @@ -770,10 +916,18 @@ public WazaNo GetTamagoWazaNo(byte index) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockB(addr, false); + WazaNo value; if (index < PmlConstants.MAX_WAZA_NUM) - return (WazaNo)block->tamagoWaza[index]; - return WazaNo.NULL; + value = (WazaNo)block->tamagoWaza[index]; + else + { + GFL.ASSERT(false); + value = WazaNo.NULL; + } + UpdateChecksumAndEncode(); + return value; } } } @@ -784,8 +938,11 @@ public uint GetHp() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockB(addr, false); - return block->hp; + var value = (uint)block->hp; + UpdateChecksumAndEncode(); + return value; } } } @@ -796,8 +953,11 @@ public uint GetTalentHp() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockB(addr, false); - return block->talentHp; + var value = block->talentHp; + UpdateChecksumAndEncode(); + return value; } } } @@ -808,8 +968,11 @@ public uint GetTalentAtk() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockB(addr, false); - return block->talentAtk; + var value = block->talentAtk; + UpdateChecksumAndEncode(); + return value; } } } @@ -820,8 +983,11 @@ public uint GetTalentDef() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockB(addr, false); - return block->talentDef; + var value = block->talentDef; + UpdateChecksumAndEncode(); + return value; } } } @@ -832,8 +998,11 @@ public uint GetTalentSpAtk() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockB(addr, false); - return block->talentSpatk; + var value = block->talentSpatk; + UpdateChecksumAndEncode(); + return value; } } } @@ -844,8 +1013,11 @@ public uint GetTalentSpDef() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockB(addr, false); - return block->talentSpdef; + var value = block->talentSpdef; + UpdateChecksumAndEncode(); + return value; } } } @@ -856,8 +1028,11 @@ public uint GetTalentAgi() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockB(addr, false); - return block->talentAgi; + var value = block->talentAgi; + UpdateChecksumAndEncode(); + return value; } } } @@ -868,8 +1043,11 @@ public uint GetEffortG() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockB(addr, false); - return block->effortG; + var value = (uint)block->effortG; + UpdateChecksumAndEncode(); + return value; } } } @@ -880,8 +1058,11 @@ public bool IsTamago() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockB(addr, false); - return block->tamagoFlag; + var value = block->tamagoFlag; + UpdateChecksumAndEncode(); + return value; } } } @@ -892,8 +1073,11 @@ public bool HaveNickName() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockB(addr, false); - return block->nicknameFlag; + var value = block->nicknameFlag; + UpdateChecksumAndEncode(); + return value; } } } @@ -904,8 +1088,11 @@ public string GetNickName() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockB(addr, false); - return new string(block->nickname); + var value = new string(block->nickname); + UpdateChecksumAndEncode(); + return value; } } } @@ -916,8 +1103,11 @@ public uint GetPalma() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockB(addr, false); - return block->palma; + var value = block->palma; + UpdateChecksumAndEncode(); + return value; } } } @@ -932,8 +1122,11 @@ public string GetPastParentsName() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockC(addr, false); - return new string(block->pastParentsName); + var value = new string(block->pastParentsName); + UpdateChecksumAndEncode(); + return value; } } } @@ -944,8 +1137,11 @@ public Sex GetPastParentsSex() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockC(addr, false); - return (Sex)block->pastParentsSex; + var value = (Sex)block->pastParentsSex; + UpdateChecksumAndEncode(); + return value; } } } @@ -956,8 +1152,11 @@ public byte GetPastParentsLangID() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockC(addr, false); - return block->pastParentLangID; + var value = block->pastParentLangID; + UpdateChecksumAndEncode(); + return value; } } } @@ -968,8 +1167,11 @@ public bool GetOwnedOthersFlag() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockC(addr, false); - return block->ownedByOthers != 0; + var value = block->ownedByOthers != 0; + UpdateChecksumAndEncode(); + return value; } } } @@ -980,8 +1182,11 @@ public ushort GetOthersFriendshipTrainerID() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockC(addr, false); - return block->othersFriendshipTrainerId; + var value = block->othersFriendshipTrainerId; + UpdateChecksumAndEncode(); + return value; } } } @@ -992,8 +1197,11 @@ public byte GetOthersFriendship() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockC(addr, false); - return block->othersFriendship; + var value = block->othersFriendship; + UpdateChecksumAndEncode(); + return value; } } } @@ -1004,8 +1212,11 @@ public byte GetOthersMemoriesLevel() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockC(addr, false); - return block->othersMemoriesLevel; + var value = block->othersMemoriesLevel; + UpdateChecksumAndEncode(); + return value; } } } @@ -1016,8 +1227,11 @@ public byte GetOthersMemoriesCode() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockC(addr, false); - return block->othersMemoriesCode; + var value = block->othersMemoriesCode; + UpdateChecksumAndEncode(); + return value; } } } @@ -1028,8 +1242,11 @@ public ushort GetOthersMemoriesData() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockC(addr, false); - return block->othersMemoriesData; + var value = block->othersMemoriesData; + UpdateChecksumAndEncode(); + return value; } } } @@ -1040,8 +1257,11 @@ public byte GetOthersMemoriesFeel() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockC(addr, false); - return block->othersMemoriesFeel; + var value = block->othersMemoriesFeel; + UpdateChecksumAndEncode(); + return value; } } } @@ -1052,11 +1272,19 @@ public bool GetPokeJobFlag(byte jobIndex) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockC(addr, false); CalcPokeJobBitPos(out byte arrayIndex, out byte bitFlag, jobIndex); + bool value; if (arrayIndex < CoreDataBlockC.POKEJOB_LEN) - return (block->pokejob[arrayIndex] & bitFlag) != 0; - return false; + value = (block->pokejob[arrayIndex] & bitFlag) != 0; + else + { + GFL.ASSERT(false); + value = false; + } + UpdateChecksumAndEncode(); + return value; } } } @@ -1067,8 +1295,11 @@ public byte GetEnjoy() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockC(addr, false); - return block->enjoy; + var value = block->enjoy; + UpdateChecksumAndEncode(); + return value; } } } @@ -1079,8 +1310,11 @@ public byte GetNadenadeValue() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockC(addr, false); - return block->nadeNadeValue; + var value = block->nadeNadeValue; + UpdateChecksumAndEncode(); + return value; } } } @@ -1091,8 +1325,11 @@ public uint GetCassetteVersion() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockC(addr, false); - return block->getCassette; + var value = (uint)block->getCassette; + UpdateChecksumAndEncode(); + return value; } } } @@ -1103,8 +1340,11 @@ public byte GetBattleRomMark() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockC(addr, false); - return block->battleRomMark; + var value = block->battleRomMark; + UpdateChecksumAndEncode(); + return value; } } } @@ -1115,8 +1355,11 @@ public uint GetLangId() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockC(addr, false); - return block->langId; + var value = (uint)block->langId; + UpdateChecksumAndEncode(); + return value; } } } @@ -1127,8 +1370,11 @@ public uint GetMultiPurposeWork() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockC(addr, false); - return block->multiWork; + var value = block->multiWork; + UpdateChecksumAndEncode(); + return value; } } } @@ -1139,8 +1385,11 @@ public byte GetEquipRibbonNo() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockC(addr, false); - return block->equipRibbon; + var value = block->equipRibbon; + UpdateChecksumAndEncode(); + return value; } } } @@ -1155,8 +1404,11 @@ public string GetOyaName() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockD(addr, false); - return new string(block->parentsName); + var value = new string(block->parentsName); + UpdateChecksumAndEncode(); + return value; } } } @@ -1167,12 +1419,20 @@ public uint GetFriendship() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var blockC = GetCoreDataBlockC(addr, false); + uint value; if (blockC->ownedByOthers != 0) - return blockC->othersFriendship; - - var block = GetCoreDataBlockD(addr, false); - return block->friendship; + { + value = blockC->othersFriendship; + } + else + { + var block = GetCoreDataBlockD(addr, false); + value = block->friendship; + } + UpdateChecksumAndEncode(); + return value; } } } @@ -1183,8 +1443,11 @@ public byte GetOriginalFriendship() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockD(addr, false); - return block->friendship; + var value = block->friendship; + UpdateChecksumAndEncode(); + return value; } } } @@ -1195,8 +1458,11 @@ public byte GetMemoriesLevel() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockD(addr, false); - return block->memories_level; + var value = block->memories_level; + UpdateChecksumAndEncode(); + return value; } } } @@ -1207,8 +1473,11 @@ public byte GetMemoriesCode() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockD(addr, false); - return block->memories_code; + var value = block->memories_code; + UpdateChecksumAndEncode(); + return value; } } } @@ -1219,8 +1488,11 @@ public ushort GetMemoriesData() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockD(addr, false); - return block->memories_data; + var value = block->memories_data; + UpdateChecksumAndEncode(); + return value; } } } @@ -1231,8 +1503,11 @@ public byte GetMemoriesFeel() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockD(addr, false); - return block->memories_feel; + var value = block->memories_feel; + UpdateChecksumAndEncode(); + return value; } } } @@ -1243,8 +1518,11 @@ public uint GetTamagoGetYear() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockD(addr, false); - return block->eggGetYear; + var value = (uint)block->eggGetYear; + UpdateChecksumAndEncode(); + return value; } } } @@ -1255,8 +1533,11 @@ public uint GetTamagoGetMonth() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockD(addr, false); - return block->eggGetMonth; + var value = (uint)block->eggGetMonth; + UpdateChecksumAndEncode(); + return value; } } } @@ -1267,8 +1548,11 @@ public uint GetTamagoGetDay() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockD(addr, false); - return block->eggGetDay; + var value = (uint)block->eggGetDay; + UpdateChecksumAndEncode(); + return value; } } } @@ -1279,8 +1563,11 @@ public uint GetBirthYear() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockD(addr, false); - return block->firstContactYear; + var value = (uint)block->firstContactYear; + UpdateChecksumAndEncode(); + return value; } } } @@ -1291,8 +1578,11 @@ public uint GetBirthMonth() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockD(addr, false); - return block->firstContactMonth; + var value = (uint)block->firstContactMonth; + UpdateChecksumAndEncode(); + return value; } } } @@ -1303,8 +1593,11 @@ public uint GetBirthDay() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockD(addr, false); - return block->firstContactDay; + var value = (uint)block->firstContactDay; + UpdateChecksumAndEncode(); + return value; } } } @@ -1315,8 +1608,11 @@ public uint GetGetPlace() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockD(addr, false); - return block->getPlace; + var value = (uint)block->getPlace; + UpdateChecksumAndEncode(); + return value; } } } @@ -1327,8 +1623,11 @@ public uint GetBirthPlace() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockD(addr, false); - return block->birthPlace; + var value = (uint)block->birthPlace; + UpdateChecksumAndEncode(); + return value; } } } @@ -1339,8 +1638,11 @@ public uint GetGetBall() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockD(addr, false); - return block->getBall; + var value = (uint)block->getBall; + UpdateChecksumAndEncode(); + return value; } } } @@ -1351,8 +1653,11 @@ public uint GetGetLevel() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockD(addr, false); - return block->getLevel; + var value = (uint)block->getLevel; + UpdateChecksumAndEncode(); + return value; } } } @@ -1363,8 +1668,11 @@ public Sex GetOyasex() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockD(addr, false); - return (Sex)block->parentsSex; + var value = (Sex)block->parentsSex; + UpdateChecksumAndEncode(); + return value; } } } @@ -1375,8 +1683,11 @@ public byte GetTrainingFlag() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockD(addr, false); - return block->trainingFlag; + var value = block->trainingFlag; + UpdateChecksumAndEncode(); + return value; } } } @@ -1387,11 +1698,19 @@ public bool GetWazaRecordFlag(byte recordIndex) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockD(addr, false); CalcWazaRecordBitPos(out byte arrayIndex, out byte bitFlag, recordIndex); + bool value; if (arrayIndex < CoreDataBlockD.WAZA_RECORD_FLAG_LEN) - return (block->wazaRecordFlag[arrayIndex] & bitFlag) != 0; - return false; + value = (block->wazaRecordFlag[arrayIndex] & bitFlag) != 0; + else + { + GFL.ASSERT(false); + value = false; + } + UpdateChecksumAndEncode(); + return value; } } } @@ -1402,10 +1721,10 @@ public ulong GetBankUniqueID() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockD(addr, false); - ulong value = 0; - for (int i = 0; i < CoreDataBlockD.BANK_UNIQUE_ID_LEN; i++) - value |= (ulong)block->bankUniqueID[i] << (i * 8); + var value = *(ulong*)block->bankUniqueID; + UpdateChecksumAndEncode(); return value; } } @@ -1413,7 +1732,7 @@ public ulong GetBankUniqueID() public bool CompareOyaName(string cmpName) { - return GetOyaName() == cmpName; + return cmpName.Equals(GetOyaName()); } // ============================================= @@ -1422,96 +1741,128 @@ public bool CompareOyaName(string cmpName) public uint GetLevel() { + if (m_pCalcData == null) return 0; unsafe { fixed (byte* addr = m_pCalcData) { + DecodeAndCheckIllegalWrite(); var calc = GetCalcData(addr, false); - return calc->level; + var value = (uint)calc->level; + UpdateChecksumAndEncode(); + return value; } } } public uint GetMaxHp() { + if (m_pCalcData == null) return 0; unsafe { fixed (byte* addr = m_pCalcData) { + DecodeAndCheckIllegalWrite(); var calc = GetCalcData(addr, false); - return calc->maxHp; + var value = (uint)calc->maxHp; + UpdateChecksumAndEncode(); + return value; } } } public uint GetAtk() { + if (m_pCalcData == null) return 0; unsafe { fixed (byte* addr = m_pCalcData) { + DecodeAndCheckIllegalWrite(); var calc = GetCalcData(addr, false); - return calc->atk; + var value = (uint)calc->atk; + UpdateChecksumAndEncode(); + return value; } } } public uint GetDef() { + if (m_pCalcData == null) return 0; unsafe { fixed (byte* addr = m_pCalcData) { + DecodeAndCheckIllegalWrite(); var calc = GetCalcData(addr, false); - return calc->def; + var value = (uint)calc->def; + UpdateChecksumAndEncode(); + return value; } } } public uint GetSpAtk() { + if (m_pCalcData == null) return 0; unsafe { fixed (byte* addr = m_pCalcData) { + DecodeAndCheckIllegalWrite(); var calc = GetCalcData(addr, false); - return calc->spatk; + var value = (uint)calc->spatk; + UpdateChecksumAndEncode(); + return value; } } } public uint GetSpDef() { + if (m_pCalcData == null) return 0; unsafe { fixed (byte* addr = m_pCalcData) { + DecodeAndCheckIllegalWrite(); var calc = GetCalcData(addr, false); - return calc->spdef; + var value = (uint)calc->spdef; + UpdateChecksumAndEncode(); + return value; } } } public uint GetAgi() { + if (m_pCalcData == null) return 0; unsafe { fixed (byte* addr = m_pCalcData) { + DecodeAndCheckIllegalWrite(); var calc = GetCalcData(addr, false); - return calc->agi; + var value = (uint)calc->agi; + UpdateChecksumAndEncode(); + return value; } } } public GState GetGState() { + if (m_pCalcData == null) return GState.NONE; unsafe { fixed (byte* addr = m_pCalcData) { + DecodeAndCheckIllegalWrite(); var calc = GetCalcData(addr, false); - return (GState)calc->gState; + var value = (GState)calc->gState; + UpdateChecksumAndEncode(); + return value; } } } @@ -1526,8 +1877,10 @@ public void SetPersonalRnd(uint rnd) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var header = GetCoreDataHeader(addr); header->personalRnd = rnd; + UpdateChecksumAndEncode(); } } } @@ -1538,8 +1891,10 @@ public void SetCheckSum(ushort checksum) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var header = GetCoreDataHeader(addr); header->checksum = checksum; + UpdateChecksumAndEncode(); } } } @@ -1550,8 +1905,10 @@ public void SetFuseiTamagoFlag(bool flag) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var header = GetCoreDataHeader(addr); header->fuseiTamagoFlag = flag; + UpdateChecksumAndEncode(); } } } @@ -1566,8 +1923,10 @@ public void SetMonsNo(uint monsno) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, true); block->monsno = (ushort)monsno; + UpdateChecksumAndEncode(); } } } @@ -1578,8 +1937,10 @@ public void SetItemNo(ushort itemno) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, true); block->itemno = itemno; + UpdateChecksumAndEncode(); } } } @@ -1590,8 +1951,10 @@ public void SetID(uint id) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, true); block->id = id; + UpdateChecksumAndEncode(); } } } @@ -1602,8 +1965,10 @@ public void SetExp(uint exp) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, true); block->exp = exp; + UpdateChecksumAndEncode(); } } } @@ -1614,8 +1979,10 @@ public void SetTokuseiNo(uint tokusei) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, true); block->tokuseino = (ushort)tokusei; + UpdateChecksumAndEncode(); } } } @@ -1626,8 +1993,10 @@ public void SetBoxMark(ushort mark) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, true); block->boxMark = mark; + UpdateChecksumAndEncode(); } } } @@ -1638,8 +2007,10 @@ public void SetColorRnd(uint rnd) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, true); block->colorRnd = rnd; + UpdateChecksumAndEncode(); } } } @@ -1650,8 +2021,10 @@ public void SetSeikaku(uint seikaku) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, true); block->seikaku = (byte)seikaku; + UpdateChecksumAndEncode(); } } } @@ -1662,8 +2035,10 @@ public void SetSeikakuHosei(uint seikaku) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, true); block->seikakuHosei = (byte)seikaku; + UpdateChecksumAndEncode(); } } } @@ -1674,8 +2049,10 @@ public void SetFormNo(ushort formno) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, true); block->formNo = formno; + UpdateChecksumAndEncode(); } } } @@ -1686,8 +2063,10 @@ public void SetEffortHp(byte value) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, true); block->effortHp = value; + UpdateChecksumAndEncode(); } } } @@ -1698,8 +2077,10 @@ public void SetEffortAtk(byte value) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, true); block->effortAtk = value; + UpdateChecksumAndEncode(); } } } @@ -1710,8 +2091,10 @@ public void SetEffortDef(byte value) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, true); block->effortDef = value; + UpdateChecksumAndEncode(); } } } @@ -1722,8 +2105,10 @@ public void SetEffortAgi(byte value) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, true); block->effortAgi = value; + UpdateChecksumAndEncode(); } } } @@ -1734,8 +2119,10 @@ public void SetEffortSpAtk(byte value) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, true); block->effortSpatk = value; + UpdateChecksumAndEncode(); } } } @@ -1746,8 +2133,10 @@ public void SetEffortSpDef(byte value) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, true); block->effortSpdef = value; + UpdateChecksumAndEncode(); } } } @@ -1758,8 +2147,10 @@ public void SetStyle(byte style) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, true); block->style = style; + UpdateChecksumAndEncode(); } } } @@ -1770,8 +2161,10 @@ public void SetBeautiful(byte beautiful) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, true); block->beautiful = beautiful; + UpdateChecksumAndEncode(); } } } @@ -1782,8 +2175,10 @@ public void SetCute(byte cute) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, true); block->cute = cute; + UpdateChecksumAndEncode(); } } } @@ -1794,8 +2189,10 @@ public void SetClever(byte clever) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, true); block->clever = clever; + UpdateChecksumAndEncode(); } } } @@ -1806,8 +2203,10 @@ public void SetStrong(byte strong) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, true); block->strong = strong; + UpdateChecksumAndEncode(); } } } @@ -1818,8 +2217,10 @@ public void SetFur(byte fur) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, true); block->fur = fur; + UpdateChecksumAndEncode(); } } } @@ -1830,8 +2231,10 @@ public void SetPokerus(byte pokerus) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, true); block->pokerus = pokerus; + UpdateChecksumAndEncode(); } } } @@ -1842,6 +2245,7 @@ public void SetRibbon(uint ribbonNo) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, true); if (ribbonNo <= MAX_RIBBON_NO_ON_RIBBON_FIELD_1) block->ribbonA |= (1u << (int)(ribbonNo - MIN_RIBBON_NO_ON_RIBBON_FIELD_1)); @@ -1851,6 +2255,7 @@ public void SetRibbon(uint ribbonNo) block->ribbonC |= (1u << (int)(ribbonNo - MIN_RIBBON_NO_ON_RIBBON_FIELD_3)); else if (ribbonNo <= MAX_RIBBON_NO_ON_RIBBON_FIELD_4) block->ribbonD |= (1u << (int)(ribbonNo - MIN_RIBBON_NO_ON_RIBBON_FIELD_4)); + UpdateChecksumAndEncode(); } } } @@ -1861,6 +2266,7 @@ public void RemoveRibbon(uint ribbonNo) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, true); if (ribbonNo <= MAX_RIBBON_NO_ON_RIBBON_FIELD_1) block->ribbonA &= ~(1u << (int)(ribbonNo - MIN_RIBBON_NO_ON_RIBBON_FIELD_1)); @@ -1870,6 +2276,7 @@ public void RemoveRibbon(uint ribbonNo) block->ribbonC &= ~(1u << (int)(ribbonNo - MIN_RIBBON_NO_ON_RIBBON_FIELD_3)); else if (ribbonNo <= MAX_RIBBON_NO_ON_RIBBON_FIELD_4) block->ribbonD &= ~(1u << (int)(ribbonNo - MIN_RIBBON_NO_ON_RIBBON_FIELD_4)); + UpdateChecksumAndEncode(); } } } @@ -1880,6 +2287,7 @@ public void RemoveAllRibbon() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, true); block->ribbonA = 0; block->ribbonB = 0; @@ -1887,6 +2295,7 @@ public void RemoveAllRibbon() block->ribbonD = 0; block->lumpingRibbonA = 0; block->lumpingRibbonB = 0; + UpdateChecksumAndEncode(); } } } @@ -1897,6 +2306,7 @@ public void SetLumpingRibbon(LumpingRibbon ribbonId, uint num) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, true); switch (ribbonId) { @@ -1907,6 +2317,7 @@ public void SetLumpingRibbon(LumpingRibbon ribbonId, uint num) block->lumpingRibbonB = (byte)num; break; } + UpdateChecksumAndEncode(); } } } @@ -1917,8 +2328,10 @@ public void SetTokusei1Flag(bool flag) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, true); block->tokusei1Flag = flag; + UpdateChecksumAndEncode(); } } } @@ -1929,8 +2342,10 @@ public void SetTokusei2Flag(bool flag) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, true); block->tokusei2Flag = flag; + UpdateChecksumAndEncode(); } } } @@ -1941,8 +2356,10 @@ public void SetTokusei3Flag(bool flag) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, true); block->tokusei3Flag = flag; + UpdateChecksumAndEncode(); } } } @@ -1953,8 +2370,10 @@ public void SetFavoriteFlag(bool flag) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, true); block->favoriteFlag = flag; + UpdateChecksumAndEncode(); } } } @@ -1965,8 +2384,10 @@ public void SetSpecialGFlag(bool flag) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, true); block->special_g_flag = flag; + UpdateChecksumAndEncode(); } } } @@ -1977,8 +2398,10 @@ public void SetEventPokemonFlag(bool flag) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, true); block->eventGetFlag = flag; + UpdateChecksumAndEncode(); } } } @@ -1989,8 +2412,10 @@ public void SetOfficialBattleEnableFlag(bool flag) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, true); block->officialBattleEnableFlag = flag; + UpdateChecksumAndEncode(); } } } @@ -2001,8 +2426,10 @@ public void SetSex(Sex sex) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, true); block->sex = (byte)sex; + UpdateChecksumAndEncode(); } } } @@ -2013,8 +2440,10 @@ public void SetCampFriendship(byte value) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, true); block->camp_friendship = value; + UpdateChecksumAndEncode(); } } } @@ -2025,8 +2454,10 @@ public void SetDprIllegalFlag(bool flag) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, true); block->dpr_illegal_flag = flag; + UpdateChecksumAndEncode(); } } } @@ -2037,8 +2468,10 @@ public void SetTalentHeight(byte value) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, true); block->talentHeight = value; + UpdateChecksumAndEncode(); } } } @@ -2049,8 +2482,10 @@ public void SetTalentWeight(byte value) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockA(addr, true); block->talentWeight = value; + UpdateChecksumAndEncode(); } } } @@ -2065,8 +2500,10 @@ public void SetSick(uint sick) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockB(addr, true); block->sick = sick; + UpdateChecksumAndEncode(); } } } @@ -2077,9 +2514,11 @@ public void SetWazaNo(byte wazaIndex, uint wazano) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockB(addr, true); if (wazaIndex < PmlConstants.MAX_WAZA_NUM) block->waza[wazaIndex] = (ushort)wazano; + UpdateChecksumAndEncode(); } } } @@ -2090,9 +2529,11 @@ public void SetPP(byte wazaIndex, byte pp) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockB(addr, true); if (wazaIndex < PmlConstants.MAX_WAZA_NUM) block->pp[wazaIndex] = pp; + UpdateChecksumAndEncode(); } } } @@ -2103,9 +2544,11 @@ public void SetWazaPPUpCount(byte wazaIndex, byte count) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockB(addr, true); if (wazaIndex < PmlConstants.MAX_WAZA_NUM) block->pointupUsedCount[wazaIndex] = count; + UpdateChecksumAndEncode(); } } } @@ -2116,9 +2559,11 @@ public void SetTamagoWazaNo(byte index, uint wazano) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockB(addr, true); if (index < PmlConstants.MAX_WAZA_NUM) block->tamagoWaza[index] = (ushort)wazano; + UpdateChecksumAndEncode(); } } } @@ -2129,8 +2574,10 @@ public void SetHp(ushort hp) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockB(addr, true); block->hp = hp; + UpdateChecksumAndEncode(); } } } @@ -2141,8 +2588,10 @@ public void SetTalentHp(byte value) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockB(addr, true); block->talentHp = value; + UpdateChecksumAndEncode(); } } } @@ -2153,8 +2602,10 @@ public void SetTalentAtk(byte value) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockB(addr, true); block->talentAtk = value; + UpdateChecksumAndEncode(); } } } @@ -2165,8 +2616,10 @@ public void SetTalentDef(byte value) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockB(addr, true); block->talentDef = value; + UpdateChecksumAndEncode(); } } } @@ -2177,8 +2630,10 @@ public void SetTalentSpAtk(byte value) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockB(addr, true); block->talentSpatk = value; + UpdateChecksumAndEncode(); } } } @@ -2189,8 +2644,10 @@ public void SetTalentSpDef(byte value) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockB(addr, true); block->talentSpdef = value; + UpdateChecksumAndEncode(); } } } @@ -2201,8 +2658,10 @@ public void SetTalentAgi(byte value) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockB(addr, true); block->talentAgi = value; + UpdateChecksumAndEncode(); } } } @@ -2213,8 +2672,10 @@ public void SetEffortG(byte value) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockB(addr, true); block->effortG = value; + UpdateChecksumAndEncode(); } } } @@ -2225,8 +2686,10 @@ public void SetTamagoFlag(bool flag) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockB(addr, true); block->tamagoFlag = flag; + UpdateChecksumAndEncode(); } } } @@ -2237,8 +2700,10 @@ public void SetNickNameFlag(bool flag) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockB(addr, true); block->nicknameFlag = flag; + UpdateChecksumAndEncode(); } } } @@ -2249,8 +2714,10 @@ public void SetNickName(string nickName) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockB(addr, true); copyString(block->nickname, nickName, PmlConstants.MONS_NAME_BUFFER_SIZE); + UpdateChecksumAndEncode(); } } } @@ -2261,8 +2728,10 @@ public void SetPalma(uint value) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockB(addr, true); block->palma = value; + UpdateChecksumAndEncode(); } } } @@ -2277,8 +2746,10 @@ public void SetPastParentsName(string name) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockC(addr, true); copyString(block->pastParentsName, name, PmlConstants.PERSON_NAME_BUFFER_SIZE); + UpdateChecksumAndEncode(); } } } @@ -2289,8 +2760,10 @@ public void SetPastParentsSex(Sex sex) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockC(addr, true); block->pastParentsSex = (byte)sex; + UpdateChecksumAndEncode(); } } } @@ -2301,8 +2774,10 @@ public void SetPastParentsLangID(byte langID) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockC(addr, true); block->pastParentLangID = langID; + UpdateChecksumAndEncode(); } } } @@ -2313,8 +2788,10 @@ public void SetOwnedOthersFlag(bool flag) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockC(addr, true); block->ownedByOthers = (byte)(flag ? 1 : 0); + UpdateChecksumAndEncode(); } } } @@ -2325,8 +2802,10 @@ public void SetOthersFriendshipTrainerID(ushort trainerId) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockC(addr, true); block->othersFriendshipTrainerId = trainerId; + UpdateChecksumAndEncode(); } } } @@ -2337,8 +2816,10 @@ public void SetOthersFriendship(byte friendship) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockC(addr, true); block->othersFriendship = friendship; + UpdateChecksumAndEncode(); } } } @@ -2349,8 +2830,10 @@ public void SetOthersMemoriesLevel(byte level) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockC(addr, true); block->othersMemoriesLevel = level; + UpdateChecksumAndEncode(); } } } @@ -2361,8 +2844,10 @@ public void SetOthersMemoriesCode(byte code) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockC(addr, true); block->othersMemoriesCode = code; + UpdateChecksumAndEncode(); } } } @@ -2373,8 +2858,10 @@ public void SetOthersMemoriesData(ushort data) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockC(addr, true); block->othersMemoriesData = data; + UpdateChecksumAndEncode(); } } } @@ -2385,8 +2872,10 @@ public void SetOthersMemoriesFeel(byte feel) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockC(addr, true); block->othersMemoriesFeel = feel; + UpdateChecksumAndEncode(); } } } @@ -2397,6 +2886,7 @@ public void SetPokeJobFlag(byte jobIndex, bool set) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockC(addr, true); CalcPokeJobBitPos(out byte arrayIndex, out byte bitFlag, jobIndex); if (arrayIndex < CoreDataBlockC.POKEJOB_LEN) @@ -2406,6 +2896,11 @@ public void SetPokeJobFlag(byte jobIndex, bool set) else block->pokejob[arrayIndex] &= (byte)~bitFlag; } + else + { + GFL.ASSERT(false); + } + UpdateChecksumAndEncode(); } } } @@ -2416,9 +2911,11 @@ public void ClearPokeJobFlag() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockC(addr, true); for (int i = 0; i < CoreDataBlockC.POKEJOB_LEN; i++) block->pokejob[i] = 0; + UpdateChecksumAndEncode(); } } } @@ -2429,8 +2926,10 @@ public void SetEnjoy(byte enjoy) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockC(addr, true); block->enjoy = enjoy; + UpdateChecksumAndEncode(); } } } @@ -2441,8 +2940,10 @@ public void SetNadenadeValue(byte value) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockC(addr, true); block->nadeNadeValue = value; + UpdateChecksumAndEncode(); } } } @@ -2453,8 +2954,10 @@ public void SetCassetteVersion(uint version) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockC(addr, true); block->getCassette = (byte)version; + UpdateChecksumAndEncode(); } } } @@ -2465,8 +2968,10 @@ public void SetBattleRomMark(byte value) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockC(addr, true); block->battleRomMark = value; + UpdateChecksumAndEncode(); } } } @@ -2477,8 +2982,10 @@ public void SetLangId(byte langId) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockC(addr, true); block->langId = langId; + UpdateChecksumAndEncode(); } } } @@ -2489,8 +2996,10 @@ public void SetMultiPurposeWork(uint value) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockC(addr, true); block->multiWork = value; + UpdateChecksumAndEncode(); } } } @@ -2501,8 +3010,10 @@ public void SetEquipRibbonNo(byte ribbonNo) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockC(addr, true); block->equipRibbon = ribbonNo; + UpdateChecksumAndEncode(); } } } @@ -2517,8 +3028,10 @@ public void SetOyaName(string oyaName) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockD(addr, true); copyString(block->parentsName, oyaName, PmlConstants.PERSON_NAME_BUFFER_SIZE); + UpdateChecksumAndEncode(); } } } @@ -2529,6 +3042,7 @@ public void SetFriendship(byte friendship) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var blockC = GetCoreDataBlockC(addr, false); if (blockC->ownedByOthers != 0) { @@ -2540,6 +3054,7 @@ public void SetFriendship(byte friendship) var block = GetCoreDataBlockD(addr, true); block->friendship = friendship; } + UpdateChecksumAndEncode(); } } } @@ -2550,8 +3065,10 @@ public void SetOriginalFriendship(byte friendship) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockD(addr, true); block->friendship = friendship; + UpdateChecksumAndEncode(); } } } @@ -2562,8 +3079,10 @@ public void SetMemoriesLevel(byte level) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockD(addr, true); block->memories_level = level; + UpdateChecksumAndEncode(); } } } @@ -2574,8 +3093,10 @@ public void SetMemoriesCode(byte code) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockD(addr, true); block->memories_code = code; + UpdateChecksumAndEncode(); } } } @@ -2586,8 +3107,10 @@ public void SetMemoriesData(ushort data) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockD(addr, true); block->memories_data = data; + UpdateChecksumAndEncode(); } } } @@ -2598,8 +3121,10 @@ public void SetMemoriesFeel(byte feel) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockD(addr, true); block->memories_feel = feel; + UpdateChecksumAndEncode(); } } } @@ -2610,8 +3135,10 @@ public void SetTamagoGetYear(byte year) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockD(addr, true); block->eggGetYear = year; + UpdateChecksumAndEncode(); } } } @@ -2622,8 +3149,10 @@ public void SetTamagoGetMonth(byte month) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockD(addr, true); block->eggGetMonth = month; + UpdateChecksumAndEncode(); } } } @@ -2634,8 +3163,10 @@ public void SetTamagoGetDay(byte day) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockD(addr, true); block->eggGetDay = day; + UpdateChecksumAndEncode(); } } } @@ -2646,8 +3177,10 @@ public void SetBirthYear(byte year) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockD(addr, true); block->firstContactYear = year; + UpdateChecksumAndEncode(); } } } @@ -2658,8 +3191,10 @@ public void SetBirthMonth(byte month) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockD(addr, true); block->firstContactMonth = month; + UpdateChecksumAndEncode(); } } } @@ -2670,8 +3205,10 @@ public void SetBirthDay(byte day) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockD(addr, true); block->firstContactDay = day; + UpdateChecksumAndEncode(); } } } @@ -2682,8 +3219,10 @@ public void SetGetPlace(ushort place) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockD(addr, true); block->getPlace = place; + UpdateChecksumAndEncode(); } } } @@ -2694,8 +3233,10 @@ public void SetBirthPlace(ushort place) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockD(addr, true); block->birthPlace = place; + UpdateChecksumAndEncode(); } } } @@ -2706,8 +3247,10 @@ public void SetGetBall(byte ball) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockD(addr, true); block->getBall = ball; + UpdateChecksumAndEncode(); } } } @@ -2718,8 +3261,10 @@ public void SetGetLevel(byte level) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockD(addr, true); block->getLevel = level; + UpdateChecksumAndEncode(); } } } @@ -2730,8 +3275,10 @@ public void SetOyasex(Sex sex) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockD(addr, true); block->parentsSex = (byte)sex; + UpdateChecksumAndEncode(); } } } @@ -2742,8 +3289,10 @@ public void SetTrainingFlag(byte value) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockD(addr, true); block->trainingFlag = value; + UpdateChecksumAndEncode(); } } } @@ -2754,6 +3303,7 @@ public void SetWazaRecordFlag(byte recordIndex, bool set) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockD(addr, true); CalcWazaRecordBitPos(out byte arrayIndex, out byte bitFlag, recordIndex); if (arrayIndex < CoreDataBlockD.WAZA_RECORD_FLAG_LEN) @@ -2763,6 +3313,11 @@ public void SetWazaRecordFlag(byte recordIndex, bool set) else block->wazaRecordFlag[arrayIndex] &= (byte)~bitFlag; } + else + { + GFL.ASSERT(false); + } + UpdateChecksumAndEncode(); } } } @@ -2773,9 +3328,11 @@ public void ClearWazaRecordFlag() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockD(addr, true); for (int i = 0; i < CoreDataBlockD.WAZA_RECORD_FLAG_LEN; i++) block->wazaRecordFlag[i] = 0; + UpdateChecksumAndEncode(); } } } @@ -2786,9 +3343,11 @@ public void SetBankUniqueID(ulong value) { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockD(addr, true); for (int i = 0; i < CoreDataBlockD.BANK_UNIQUE_ID_LEN; i++) block->bankUniqueID[i] = (byte)(value >> (i * 8)); + UpdateChecksumAndEncode(); } } } @@ -2799,9 +3358,11 @@ public void ClearBankUniqueID() { fixed (byte* addr = m_pCoreData) { + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockD(addr, true); for (int i = 0; i < CoreDataBlockD.BANK_UNIQUE_ID_LEN; i++) block->bankUniqueID[i] = 0; + UpdateChecksumAndEncode(); } } } @@ -2816,8 +3377,10 @@ public void SetLevel(byte level) { fixed (byte* addr = m_pCalcData) { + DecodeAndCheckIllegalWrite(); var calc = GetCalcData(addr, true); calc->level = level; + UpdateChecksumAndEncode(); } } } @@ -2828,8 +3391,10 @@ public void SetMaxHp(ushort maxHp) { fixed (byte* addr = m_pCalcData) { + DecodeAndCheckIllegalWrite(); var calc = GetCalcData(addr, true); calc->maxHp = maxHp; + UpdateChecksumAndEncode(); } } } @@ -2840,8 +3405,10 @@ public void SetAtk(ushort atk) { fixed (byte* addr = m_pCalcData) { + DecodeAndCheckIllegalWrite(); var calc = GetCalcData(addr, true); calc->atk = atk; + UpdateChecksumAndEncode(); } } } @@ -2852,8 +3419,10 @@ public void SetDef(ushort def) { fixed (byte* addr = m_pCalcData) { + DecodeAndCheckIllegalWrite(); var calc = GetCalcData(addr, true); calc->def = def; + UpdateChecksumAndEncode(); } } } @@ -2864,8 +3433,10 @@ public void SetSpAtk(ushort spatk) { fixed (byte* addr = m_pCalcData) { + DecodeAndCheckIllegalWrite(); var calc = GetCalcData(addr, true); calc->spatk = spatk; + UpdateChecksumAndEncode(); } } } @@ -2876,8 +3447,10 @@ public void SetSpDef(ushort spdef) { fixed (byte* addr = m_pCalcData) { + DecodeAndCheckIllegalWrite(); var calc = GetCalcData(addr, true); calc->spdef = spdef; + UpdateChecksumAndEncode(); } } } @@ -2888,8 +3461,10 @@ public void SetAgi(ushort agi) { fixed (byte* addr = m_pCalcData) { + DecodeAndCheckIllegalWrite(); var calc = GetCalcData(addr, true); calc->agi = agi; + UpdateChecksumAndEncode(); } } } @@ -2900,8 +3475,10 @@ public void SetGState(GState state) { fixed (byte* addr = m_pCalcData) { + DecodeAndCheckIllegalWrite(); var calc = GetCalcData(addr, true); calc->gState = (byte)state; + UpdateChecksumAndEncode(); } } } @@ -2917,81 +3494,37 @@ public void SetGState(GState state) private unsafe CoreDataBlockA* GetCoreDataBlockA(byte* _addr, bool forWrite) { - if (!m_accessState.isFastMode) - { - if (forWrite) - DecodeAndCheckIllegalWrite(); - else - DecodeAndCheckIllegalWrite(); - } - var header = GetCoreDataHeader(_addr); byte pos = GetCoreDataBlockPos(header->personalRnd, CoreDataBlockId.A); byte* blockStart = _addr + CoreDataHeader.SIZE + pos * CoreData.CORE_DATA_BLOCK_SIZE; - if (!m_accessState.isFastMode && !forWrite) - UpdateChecksumAndEncode(); - return (CoreDataBlockA*)blockStart; } private unsafe CoreDataBlockB* GetCoreDataBlockB(byte* _addr, bool forWrite) { - if (!m_accessState.isFastMode) - { - if (forWrite) - DecodeAndCheckIllegalWrite(); - else - DecodeAndCheckIllegalWrite(); - } - var header = GetCoreDataHeader(_addr); byte pos = GetCoreDataBlockPos(header->personalRnd, CoreDataBlockId.B); byte* blockStart = _addr + CoreDataHeader.SIZE + pos * CoreData.CORE_DATA_BLOCK_SIZE; - if (!m_accessState.isFastMode && !forWrite) - UpdateChecksumAndEncode(); - return (CoreDataBlockB*)blockStart; } private unsafe CoreDataBlockC* GetCoreDataBlockC(byte* _addr, bool forWrite) { - if (!m_accessState.isFastMode) - { - if (forWrite) - DecodeAndCheckIllegalWrite(); - else - DecodeAndCheckIllegalWrite(); - } - var header = GetCoreDataHeader(_addr); byte pos = GetCoreDataBlockPos(header->personalRnd, CoreDataBlockId.C); byte* blockStart = _addr + CoreDataHeader.SIZE + pos * CoreData.CORE_DATA_BLOCK_SIZE; - if (!m_accessState.isFastMode && !forWrite) - UpdateChecksumAndEncode(); - return (CoreDataBlockC*)blockStart; } private unsafe CoreDataBlockD* GetCoreDataBlockD(byte* _addr, bool forWrite) { - if (!m_accessState.isFastMode) - { - if (forWrite) - DecodeAndCheckIllegalWrite(); - else - DecodeAndCheckIllegalWrite(); - } - var header = GetCoreDataHeader(_addr); byte pos = GetCoreDataBlockPos(header->personalRnd, CoreDataBlockId.D); byte* blockStart = _addr + CoreDataHeader.SIZE + pos * CoreData.CORE_DATA_BLOCK_SIZE; - if (!m_accessState.isFastMode && !forWrite) - UpdateChecksumAndEncode(); - return (CoreDataBlockD*)blockStart; } @@ -3089,38 +3622,35 @@ private void DecodeAndCheckIllegalWrite() private unsafe void Serialize(void* bufferForCore, void* bufferForCalc) { - if (!m_accessState.isEncoded) - UpdateChecksumAndEncode(); - - fixed (byte* src = m_pCoreData) + var fastMode = IsFastMode(); + if (fastMode) EndFastMode(); + if (bufferForCore != null) { - Buffer.MemoryCopy(src, bufferForCore, CORE_DATA_SIZE, CORE_DATA_SIZE); + fixed (byte* src = m_pCoreData) + UnsafeUtility.MemCpy(bufferForCore, src, CORE_DATA_SIZE); } - - if (bufferForCalc != null && m_pCalcData != null) + if (bufferForCalc != null) { fixed (byte* src = m_pCalcData) - { - Buffer.MemoryCopy(src, bufferForCalc, CALC_DATA_SIZE, CALC_DATA_SIZE); - } + UnsafeUtility.MemCpy(bufferForCalc, src, CALC_DATA_SIZE); } + if (fastMode) StartFastMode(); } private unsafe void Deserialize(void* serializedCoreData, void* serializedCalcData) { - fixed (byte* dst = m_pCoreData) + if (serializedCoreData != null) { - Buffer.MemoryCopy(serializedCoreData, dst, CORE_DATA_SIZE, CORE_DATA_SIZE); + GFL.ASSERT(m_pCoreData != null); + fixed (byte* dst = m_pCoreData) + UnsafeUtility.MemCpy(dst, serializedCoreData, CORE_DATA_SIZE); } - - if (serializedCalcData != null && m_pCalcData != null) + if (serializedCalcData != null) { + GFL.ASSERT(m_pCalcData != null); fixed (byte* dst = m_pCalcData) - { - Buffer.MemoryCopy(serializedCalcData, dst, CALC_DATA_SIZE, CALC_DATA_SIZE); - } + UnsafeUtility.MemCpy(dst, serializedCalcData, CALC_DATA_SIZE); } - m_accessState.isEncoded = true; m_accessState.isFastMode = false; DecodeAndCheckIllegalWrite(); diff --git a/Assets/Scripts/Pml/PokePara/CoreDataBlockA.cs b/Assets/Scripts/Pml/PokePara/CoreDataBlockA.cs index e2c745969..17b497ffc 100644 --- a/Assets/Scripts/Pml/PokePara/CoreDataBlockA.cs +++ b/Assets/Scripts/Pml/PokePara/CoreDataBlockA.cs @@ -76,49 +76,49 @@ public struct CoreDataBlockA public bool tokusei1Flag { - get => (_bitsA >> bitsA0_loc & bitsA0_sz) != 0; + get => ((_bitsA & bitsA0_mask) >> bitsA0_loc) != 0; set => _bitsA = (ushort)((_bitsA & ~bitsA0_mask) | (value ? bitsA0_mask : 0)); } public bool tokusei2Flag { - get => (_bitsA >> bitsA1_loc & bitsA1_sz) != 0; + get => ((_bitsA & bitsA1_mask) >> bitsA1_loc) != 0; set => _bitsA = (ushort)((_bitsA & ~bitsA1_mask) | (value ? bitsA1_mask : 0)); } public bool tokusei3Flag { - get => (_bitsA >> bitsA2_loc & bitsA2_sz) != 0; + get => ((_bitsA & bitsA2_mask) >> bitsA2_loc) != 0; set => _bitsA = (ushort)((_bitsA & ~bitsA2_mask) | (value ? bitsA2_mask : 0)); } public bool favoriteFlag { - get => (_bitsA >> bitsA3_loc & bitsA3_sz) != 0; + get => ((_bitsA & bitsA3_mask) >> bitsA3_loc) != 0; set => _bitsA = (ushort)((_bitsA & ~bitsA3_mask) | (value ? bitsA3_mask : 0)); } public bool special_g_flag { - get => (_bitsA >> bitsA4_loc & bitsA4_sz) != 0; + get => ((_bitsA & bitsA4_mask) >> bitsA4_loc) != 0; set => _bitsA = (ushort)((_bitsA & ~bitsA4_mask) | (value ? bitsA4_mask : 0)); } public bool debug_edit_flag { - get => (_bitsA >> bitsA5_loc & bitsA5_sz) != 0; + get => ((_bitsA & bitsA5_mask) >> bitsA5_loc) != 0; set => _bitsA = (ushort)((_bitsA & ~bitsA5_mask) | (value ? bitsA5_mask : 0)); } public bool eventGetFlag { - get => (_bitsB >> bitsB0_loc & bitsB0_sz) != 0; + get => ((_bitsB & bitsB0_mask) >> bitsB0_loc) != 0; set => _bitsB = (byte)((_bitsB & ~bitsB0_mask) | (value ? bitsB0_mask : 0)); } public bool officialBattleEnableFlag { - get => (_bitsB >> bitsB1_loc & bitsB1_sz) != 0; + get => ((_bitsB & bitsB1_mask) >> bitsB1_loc) != 0; set => _bitsB = (byte)((_bitsB & ~bitsB1_mask) | (value ? bitsB1_mask : 0)); } @@ -130,13 +130,13 @@ public byte sex public uint camp_friendship { - get => (uint)((_bitsC & (uint)bitsC0_mask) >> bitsC0_loc); - set => _bitsC = (uint)((_bitsC & ~(uint)bitsC0_mask) | ((value << bitsC0_loc) & (uint)bitsC0_mask)); + get => (_bitsC & bitsC0_mask) >> bitsC0_loc; + set => _bitsC = (_bitsC & ~(uint)bitsC0_mask) | ((value << bitsC0_loc) & bitsC0_mask); } public bool dpr_illegal_flag { - get => (_bitsD >> bitsD0_loc & bitsD0_sz) != 0; + get => ((_bitsD & bitsD0_mask) >> bitsD0_loc) != 0; set => _bitsD = (byte)((_bitsD & ~bitsD0_mask) | (value ? bitsD0_mask : 0)); } } diff --git a/Assets/Scripts/Pml/PokePara/CoreDataBlockB.cs b/Assets/Scripts/Pml/PokePara/CoreDataBlockB.cs index cb0d64c78..b40b1a6a2 100644 --- a/Assets/Scripts/Pml/PokePara/CoreDataBlockB.cs +++ b/Assets/Scripts/Pml/PokePara/CoreDataBlockB.cs @@ -41,50 +41,50 @@ public struct CoreDataBlockB public uint talentHp { - get => (uint)((_bitsA & (uint)bitsA0_mask) >> bitsA0_loc); - set => _bitsA = (uint)((_bitsA & ~(uint)bitsA0_mask) | ((value << bitsA0_loc) & (uint)bitsA0_mask)); + get => (_bitsA & bitsA0_mask) >> bitsA0_loc; + set => _bitsA = (_bitsA & ~(uint)bitsA0_mask) | ((value << bitsA0_loc) & bitsA0_mask); } public uint talentAtk { - get => (uint)((_bitsA & (uint)bitsA1_mask) >> bitsA1_loc); - set => _bitsA = (uint)((_bitsA & ~(uint)bitsA1_mask) | ((value << bitsA1_loc) & (uint)bitsA1_mask)); + get => (_bitsA & bitsA1_mask) >> bitsA1_loc; + set => _bitsA = (_bitsA & ~(uint)bitsA1_mask) | ((value << bitsA1_loc) & bitsA1_mask); } public uint talentDef { - get => (uint)((_bitsA & (uint)bitsA2_mask) >> bitsA2_loc); - set => _bitsA = (uint)((_bitsA & ~(uint)bitsA2_mask) | ((value << bitsA2_loc) & (uint)bitsA2_mask)); + get => (_bitsA & bitsA2_mask) >> bitsA2_loc; + set => _bitsA = (_bitsA & ~(uint)bitsA2_mask) | ((value << bitsA2_loc) & bitsA2_mask); } public uint talentAgi { - get => (uint)((_bitsA & (uint)bitsA3_mask) >> bitsA3_loc); - set => _bitsA = (uint)((_bitsA & ~(uint)bitsA3_mask) | ((value << bitsA3_loc) & (uint)bitsA3_mask)); + get => (_bitsA & bitsA3_mask) >> bitsA3_loc; + set => _bitsA = (_bitsA & ~(uint)bitsA3_mask) | ((value << bitsA3_loc) & bitsA3_mask); } public uint talentSpatk { - get => (uint)((_bitsA & (uint)bitsA4_mask) >> bitsA4_loc); - set => _bitsA = (uint)((_bitsA & ~(uint)bitsA4_mask) | ((value << bitsA4_loc) & (uint)bitsA4_mask)); + get => (_bitsA & bitsA4_mask) >> bitsA4_loc; + set => _bitsA = (_bitsA & ~(uint)bitsA4_mask) | ((value << bitsA4_loc) & bitsA4_mask); } public uint talentSpdef { - get => (uint)((_bitsA & (uint)bitsA5_mask) >> bitsA5_loc); - set => _bitsA = (uint)((_bitsA & ~(uint)bitsA5_mask) | ((value << bitsA5_loc) & (uint)bitsA5_mask)); + get => (_bitsA & bitsA5_mask) >> bitsA5_loc; + set => _bitsA = (_bitsA & ~(uint)bitsA5_mask) | ((value << bitsA5_loc) & bitsA5_mask); } public bool tamagoFlag { - get => (_bitsA & (uint)bitsA6_mask) != 0; - set => _bitsA = (uint)((_bitsA & ~(uint)bitsA6_mask) | (value ? (uint)bitsA6_mask : 0)); + get => ((_bitsA & bitsA6_mask) >> bitsA6_loc) != 0; + set => _bitsA = (_bitsA & ~(uint)bitsA6_mask) | (uint)(value ? bitsA6_mask : 0); } public bool nicknameFlag { - get => (_bitsA & unchecked((uint)bitsA7_mask)) != 0; - set => _bitsA = (uint)((_bitsA & ~unchecked((uint)bitsA7_mask)) | (value ? unchecked((uint)bitsA7_mask) : 0)); + get => ((_bitsA & unchecked((uint)bitsA7_mask)) >> bitsA7_loc) != 0; + set => _bitsA = (_bitsA & ~unchecked((uint)bitsA7_mask)) | unchecked((uint)(value ? bitsA7_mask : 0)); } } } \ No newline at end of file From 8d568387e466535d6f7c8e3adadb413e9967d2de Mon Sep 17 00:00:00 2001 From: AstrandPallas Date: Tue, 10 Feb 2026 01:12:35 -0800 Subject: [PATCH 3/3] Implement GetNickName egg name by language logic from Ghidra --- Assets/Scripts/Pml/PokePara/Accessor.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Assets/Scripts/Pml/PokePara/Accessor.cs b/Assets/Scripts/Pml/PokePara/Accessor.cs index aa2cee488..3e238ca47 100644 --- a/Assets/Scripts/Pml/PokePara/Accessor.cs +++ b/Assets/Scripts/Pml/PokePara/Accessor.cs @@ -1,7 +1,9 @@ using System; using System.Runtime.InteropServices; using Unity.Collections.LowLevel.Unsafe; +using Dpr.Message; using Pml; +using Pml.Personal; namespace Pml.PokePara { @@ -1088,6 +1090,20 @@ public string GetNickName() { fixed (byte* addr = m_pCoreData) { + var header = GetCoreDataHeader(addr); + if (header->fuseiTamagoFlag) + { + DecodeAndCheckIllegalWrite(); + var blockC = GetCoreDataBlockC(addr, false); + byte langId = blockC->langId; + UpdateChecksumAndEncode(); + if (langId == 0) + { + langId = 1; + } + return PersonalSystem.GetMonsName(MonsNo.TAMAGO, (MessageEnumData.MsgLangId)langId); + } + DecodeAndCheckIllegalWrite(); var block = GetCoreDataBlockB(addr, false); var value = new string(block->nickname);