Add PLA+ obedience mechanics (with config)

This commit is contained in:
Bassoonian 2023-01-11 08:15:57 +01:00
parent 5eb62199cd
commit 333917941b
11 changed files with 26 additions and 6 deletions

View File

@ -184,6 +184,7 @@
#define B_WILD_NATURAL_ENEMIES TRUE // If set to TRUE, certain wild mon species will attack other species when partnered in double wild battles (eg. Zangoose vs Seviper)
#define B_AFFECTION_MECHANICS FALSE // In Gen6+, there's a stat called affection that can trigger different effects in battle. From LGPE onwards, those effects use friendship instead.
#define B_TRAINER_CLASS_POKE_BALLS GEN_LATEST // In Gen7+, trainers will use certain types of Poké Balls depending on their trainer class.
#define B_OBEDIENCE_MECHANICS GEN_LATEST // In PLA+ (here Gen8+), obedience restrictions also apply to non-outsider Pokémon, albeit based on their level met rather than actual level
// Animation Settings
#define B_NEW_SWORD_PARTICLE FALSE // If set to TRUE, it updates Swords Dance's particle.

View File

@ -291,6 +291,7 @@ struct BattlePokemon
/*0x4D*/ u32 status1;
/*0x51*/ u32 status2;
/*0x55*/ u32 otId;
/*0x59*/ u8 metLevel;
};
struct SpeciesInfo

View File

@ -595,6 +595,7 @@ static u32 CopyLinkOpponentMonData(u8 monId, u8 *dst)
battleMon.spDefense = GetMonData(&gEnemyParty[monId], MON_DATA_SPDEF);
battleMon.abilityNum = GetMonData(&gEnemyParty[monId], MON_DATA_ABILITY_NUM);
battleMon.otId = GetMonData(&gEnemyParty[monId], MON_DATA_OT_ID);
battleMon.metLevel = GetMonData(&gEnemyParty[monId], MON_DATA_MET_LEVEL);
GetMonData(&gEnemyParty[monId], MON_DATA_NICKNAME, nickname);
StringCopy_Nickname(battleMon.nickname, nickname);
GetMonData(&gEnemyParty[monId], MON_DATA_OT_NAME, battleMon.otName);

View File

@ -489,6 +489,7 @@ static u32 CopyLinkPartnerMonData(u8 monId, u8 *dst)
battleMon.spDefense = GetMonData(&gPlayerParty[monId], MON_DATA_SPDEF);
battleMon.abilityNum = GetMonData(&gPlayerParty[monId], MON_DATA_ABILITY_NUM);
battleMon.otId = GetMonData(&gPlayerParty[monId], MON_DATA_OT_ID);
battleMon.metLevel = GetMonData(&gPlayerParty[monId], MON_DATA_MET_LEVEL);
GetMonData(&gPlayerParty[monId], MON_DATA_NICKNAME, nickname);
StringCopy_Nickname(battleMon.nickname, nickname);
GetMonData(&gPlayerParty[monId], MON_DATA_OT_NAME, battleMon.otName);

View File

@ -612,6 +612,7 @@ static u32 GetOpponentMonData(u8 monId, u8 *dst)
battleMon.spDefense = GetMonData(&gEnemyParty[monId], MON_DATA_SPDEF);
battleMon.abilityNum = GetMonData(&gEnemyParty[monId], MON_DATA_ABILITY_NUM);
battleMon.otId = GetMonData(&gEnemyParty[monId], MON_DATA_OT_ID);
battleMon.metLevel = GetMonData(&gEnemyParty[monId], MON_DATA_MET_LEVEL);
GetMonData(&gEnemyParty[monId], MON_DATA_NICKNAME, nickname);
StringCopy_Nickname(battleMon.nickname, nickname);
GetMonData(&gEnemyParty[monId], MON_DATA_OT_NAME, battleMon.otName);

View File

@ -1866,6 +1866,7 @@ static u32 CopyPlayerMonData(u8 monId, u8 *dst)
battleMon.spDefense = GetMonData(&gPlayerParty[monId], MON_DATA_SPDEF);
battleMon.abilityNum = GetMonData(&gPlayerParty[monId], MON_DATA_ABILITY_NUM);
battleMon.otId = GetMonData(&gPlayerParty[monId], MON_DATA_OT_ID);
battleMon.metLevel = GetMonData(&gPlayerParty[monId], MON_DATA_MET_LEVEL);
GetMonData(&gPlayerParty[monId], MON_DATA_NICKNAME, nickname);
StringCopy_Nickname(battleMon.nickname, nickname);
GetMonData(&gPlayerParty[monId], MON_DATA_OT_NAME, battleMon.otName);

View File

@ -675,6 +675,7 @@ static u32 CopyPlayerPartnerMonData(u8 monId, u8 *dst)
battleMon.spDefense = GetMonData(&gPlayerParty[monId], MON_DATA_SPDEF);
battleMon.abilityNum = GetMonData(&gPlayerParty[monId], MON_DATA_ABILITY_NUM);
battleMon.otId = GetMonData(&gPlayerParty[monId], MON_DATA_OT_ID);
battleMon.metLevel = GetMonData(&gPlayerParty[monId], MON_DATA_MET_LEVEL);
GetMonData(&gPlayerParty[monId], MON_DATA_NICKNAME, nickname);
StringCopy_Nickname(battleMon.nickname, nickname);
GetMonData(&gPlayerParty[monId], MON_DATA_OT_NAME, battleMon.otName);

View File

@ -581,6 +581,7 @@ static u32 CopyRecordedOpponentMonData(u8 monId, u8 *dst)
battleMon.spDefense = GetMonData(&gEnemyParty[monId], MON_DATA_SPDEF);
battleMon.abilityNum = GetMonData(&gEnemyParty[monId], MON_DATA_ABILITY_NUM);
battleMon.otId = GetMonData(&gEnemyParty[monId], MON_DATA_OT_ID);
battleMon.metLevel = GetMonData(&gEnemyParty[monId], MON_DATA_MET_LEVEL);
GetMonData(&gEnemyParty[monId], MON_DATA_NICKNAME, nickname);
StringCopy_Nickname(battleMon.nickname, nickname);
GetMonData(&gEnemyParty[monId], MON_DATA_OT_NAME, battleMon.otName);

View File

@ -562,6 +562,7 @@ static u32 CopyRecordedPlayerMonData(u8 monId, u8 *dst)
battleMon.spDefense = GetMonData(&gPlayerParty[monId], MON_DATA_SPDEF);
battleMon.abilityNum = GetMonData(&gPlayerParty[monId], MON_DATA_ABILITY_NUM);
battleMon.otId = GetMonData(&gPlayerParty[monId], MON_DATA_OT_ID);
battleMon.metLevel = GetMonData(&gPlayerParty[monId], MON_DATA_MET_LEVEL);
GetMonData(&gPlayerParty[monId], MON_DATA_NICKNAME, nickname);
StringCopy_Nickname(battleMon.nickname, nickname);
GetMonData(&gPlayerParty[monId], MON_DATA_OT_NAME, battleMon.otName);

View File

@ -491,6 +491,7 @@ static u32 CopyWallyMonData(u8 monId, u8 *dst)
battleMon.spDefense = GetMonData(&gPlayerParty[monId], MON_DATA_SPDEF);
battleMon.abilityNum = GetMonData(&gPlayerParty[monId], MON_DATA_ABILITY_NUM);
battleMon.otId = GetMonData(&gPlayerParty[monId], MON_DATA_OT_ID);
battleMon.metLevel = GetMonData(&gPlayerParty[monId], MON_DATA_MET_LEVEL);
GetMonData(&gPlayerParty[monId], MON_DATA_NICKNAME, nickname);
StringCopy_Nickname(battleMon.nickname, nickname);
GetMonData(&gPlayerParty[monId], MON_DATA_OT_NAME, battleMon.otName);

View File

@ -8018,6 +8018,7 @@ u8 IsMonDisobedient(void)
s32 rnd;
s32 calc;
u8 obedienceLevel = 0;
u8 levelReferenced;
if (gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_RECORDED_LINK))
return 0;
@ -8032,8 +8033,10 @@ u8 IsMonDisobedient(void)
return 0;
if (gBattleTypeFlags & BATTLE_TYPE_RECORDED)
return 0;
#if B_OBEDIENCE_MECHANICS < GEN_8
if (!IsOtherTrainer(gBattleMons[gBattlerAttacker].otId, gBattleMons[gBattlerAttacker].otName))
return 0;
#endif
if (FlagGet(FLAG_BADGE08_GET))
return 0;
@ -8047,10 +8050,17 @@ u8 IsMonDisobedient(void)
obedienceLevel = 70;
}
if (gBattleMons[gBattlerAttacker].level <= obedienceLevel)
#if B_OBEDIENCE_MECHANICS >= GEN_8
if (!IsOtherTrainer(gBattleMons[gBattlerAttacker].otId, gBattleMons[gBattlerAttacker].otName))
levelReferenced = gBattleMons[gBattlerAttacker].metLevel;
else
#endif
levelReferenced = gBattleMons[gBattlerAttacker].level;
if (levelReferenced <= obedienceLevel)
return 0;
rnd = (Random() & 255);
calc = (gBattleMons[gBattlerAttacker].level + obedienceLevel) * rnd >> 8;
calc = (levelReferenced + obedienceLevel) * rnd >> 8;
if (calc < obedienceLevel)
return 0;
@ -8064,7 +8074,7 @@ u8 IsMonDisobedient(void)
}
rnd = (Random() & 255);
calc = (gBattleMons[gBattlerAttacker].level + obedienceLevel) * rnd >> 8;
calc = (levelReferenced + obedienceLevel) * rnd >> 8;
if (calc < obedienceLevel)
{
calc = CheckMoveLimitations(gBattlerAttacker, gBitTable[gCurrMovePos], MOVE_LIMITATIONS_ALL);
@ -8092,7 +8102,7 @@ u8 IsMonDisobedient(void)
}
else
{
obedienceLevel = gBattleMons[gBattlerAttacker].level - obedienceLevel;
obedienceLevel = levelReferenced - obedienceLevel;
calc = (Random() & 255);
if (calc < obedienceLevel && CanSleep(gBattlerAttacker))