Fix item usage in double battles (#3977)

* Fix item usage in double battles

* fix failing tests

---------

Co-authored-by: Eduardo Quezada D'Ottone <eduardo602002@gmail.com>
This commit is contained in:
Alex 2024-01-15 21:55:35 +01:00 committed by GitHub
parent 95a81badb0
commit f6c08c08b6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 44 additions and 31 deletions

View File

@ -49,11 +49,17 @@ BattleScript_UseItemMessage:
BattleScript_ItemRestoreHP::
call BattleScript_UseItemMessage
itemrestorehp
jumpifbyte CMP_EQUAL, gBattleCommunication, TRUE, BattleScript_ItemRestoreHP_SendOutRevivedBattler
bichalfword gMoveResultFlags, MOVE_RESULT_NO_EFFECT
orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE
healthbarupdate BS_ATTACKER
datahpupdate BS_ATTACKER
healthbarupdate BS_SCRIPTING
datahpupdate BS_SCRIPTING
printstring STRINGID_ITEMRESTOREDSPECIESHEALTH
waitmessage B_WAIT_TIME_LONG
end
BattleScript_ItemRestoreHP_Party::
jumpifbyte CMP_EQUAL, gBattleCommunication, TRUE, BattleScript_ItemRestoreHP_SendOutRevivedBattler
bichalfword gMoveResultFlags, MOVE_RESULT_NO_EFFECT
printstring STRINGID_ITEMRESTOREDSPECIESHEALTH
waitmessage B_WAIT_TIME_LONG
end
@ -67,7 +73,7 @@ BattleScript_ItemRestoreHP_SendOutRevivedBattler:
BattleScript_ItemCureStatus::
call BattleScript_UseItemMessage
itemcurestatus
updatestatusicon BS_ATTACKER
updatestatusicon BS_SCRIPTING
printstring STRINGID_ITEMCUREDSPECIESSTATUS
waitmessage B_WAIT_TIME_LONG
end
@ -80,9 +86,9 @@ BattleScript_ItemHealAndCureStatus::
waitmessage B_WAIT_TIME_LONG
bichalfword gMoveResultFlags, MOVE_RESULT_NO_EFFECT
orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE
healthbarupdate BS_ATTACKER
datahpupdate BS_ATTACKER
updatestatusicon BS_ATTACKER
healthbarupdate BS_SCRIPTING
datahpupdate BS_SCRIPTING
updatestatusicon BS_SCRIPTING
printstring STRINGID_ITEMRESTOREDSPECIESHEALTH
waitmessage B_WAIT_TIME_LONG
end

View File

@ -490,6 +490,7 @@ extern const u8 BattleScript_TheRainbowDisappeared[];
extern const u8 BattleScript_HurtByTheSeaOfFire[];
extern const u8 BattleScript_TheSeaOfFireDisappeared[];
extern const u8 BattleScript_TheSwampDisappeared[];
extern const u8 BattleScript_ItemRestoreHP_Party[];
// zmoves
extern const u8 BattleScript_ZMoveActivateDamaging[];

View File

@ -627,7 +627,7 @@ void PokemonToBattleMon(struct Pokemon *src, struct BattlePokemon *dst);
void CopyPlayerPartyMonToBattleData(u8 battlerId, u8 partyIndex);
bool8 ExecuteTableBasedItemEffect(struct Pokemon *mon, u16 item, u8 partyIndex, u8 moveIndex);
bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 moveIndex, u8 e);
bool8 HealStatusConditions(struct Pokemon *mon, u32 battlePartyId, u32 healMask, u8 battlerId);
bool8 HealStatusConditions(struct Pokemon *mon, u32 healMask, u8 battlerId);
u8 GetItemEffectParamOffset(u32 battler, u16 itemId, u8 effectByte, u8 effectBit);
u8 *UseStatIncreaseItem(u16 itemId);
u8 GetNature(struct Pokemon *mon);

View File

@ -14985,7 +14985,7 @@ static void Cmd_handleballthrow(void)
if (gLastUsedItem == ITEM_HEAL_BALL)
{
MonRestorePP(&gEnemyParty[gBattlerPartyIndexes[gBattlerTarget]]);
HealStatusConditions(&gEnemyParty[gBattlerPartyIndexes[gBattlerTarget]], gBattlerPartyIndexes[gBattlerTarget], STATUS1_ANY, gBattlerTarget);
HealStatusConditions(&gEnemyParty[gBattlerPartyIndexes[gBattlerTarget]], STATUS1_ANY, gBattlerTarget);
gBattleMons[gBattlerTarget].hp = gBattleMons[gBattlerTarget].maxHP;
SetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattlerTarget]], MON_DATA_HP, &gBattleMons[gBattlerTarget].hp);
}
@ -15039,7 +15039,7 @@ static void Cmd_handleballthrow(void)
if (gLastUsedItem == ITEM_HEAL_BALL)
{
MonRestorePP(&gEnemyParty[gBattlerPartyIndexes[gBattlerTarget]]);
HealStatusConditions(&gEnemyParty[gBattlerPartyIndexes[gBattlerTarget]], gBattlerPartyIndexes[gBattlerTarget], STATUS1_ANY, gBattlerTarget);
HealStatusConditions(&gEnemyParty[gBattlerPartyIndexes[gBattlerTarget]], STATUS1_ANY, gBattlerTarget);
gBattleMons[gBattlerTarget].hp = gBattleMons[gBattlerTarget].maxHP;
SetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattlerTarget]], MON_DATA_HP, &gBattleMons[gBattlerTarget].hp);
}
@ -15866,10 +15866,14 @@ void BS_ItemRestoreHP(void)
if (hp + healAmount > maxHP)
healAmount = maxHP - hp;
gBattleScripting.battler = battler;
PREPARE_SPECIES_BUFFER(gBattleTextBuff1, GetMonData(&party[gBattleStruct->itemPartyIndex[gBattlerAttacker]], MON_DATA_SPECIES));
// Heal is applied as move damage if battler is active.
if (battler != MAX_BATTLERS_COUNT && hp != 0)
{
gBattleMoveDamage = -healAmount;
gBattlescriptCurrInstr = cmd->nextInstr;
}
else
{
@ -15880,21 +15884,18 @@ void BS_ItemRestoreHP(void)
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && battler != MAX_BATTLERS_COUNT)
{
gAbsentBattlerFlags &= ~gBitTable[battler];
gBattleScripting.battler = battler;
gBattleCommunication[MULTIUSE_STATE] = TRUE;
}
gBattlescriptCurrInstr = BattleScript_ItemRestoreHP_Party;
}
PREPARE_SPECIES_BUFFER(gBattleTextBuff1, GetMonData(&party[gBattleStruct->itemPartyIndex[gBattlerAttacker]], MON_DATA_SPECIES));
gBattlescriptCurrInstr = cmd->nextInstr;
}
void BS_ItemCureStatus(void)
{
NATIVE_ARGS();
struct Pokemon *party = GetBattlerParty(gBattlerAttacker);
// Heal Status1 conditions.
HealStatusConditions(&party[gBattleStruct->itemPartyIndex[gBattlerAttacker]], gBattleStruct->itemPartyIndex[gBattlerAttacker], GetItemStatus1Mask(gLastUsedItem), gBattlerAttacker);
u32 battler = gBattlerAttacker;
u32 side = GetBattlerSide(gBattlerAttacker);
struct Pokemon *party = GetSideParty(side);
// Heal Status2 conditions if battler is active.
if (gBattleStruct->itemPartyIndex[gBattlerAttacker] == gBattlerPartyIndexes[gBattlerAttacker])
@ -15905,14 +15906,18 @@ void BS_ItemCureStatus(void)
&& gBattleStruct->itemPartyIndex[gBattlerAttacker] == gBattlerPartyIndexes[BATTLE_PARTNER(gBattlerAttacker)])
{
gBattleMons[gBattlerAttacker].status2 &= ~GetItemStatus2Mask(gLastUsedItem);
gBattlerTarget = BATTLE_PARTNER(gBattlerAttacker);
battler = BATTLE_PARTNER(gBattlerAttacker);
}
if (GetItemStatus1Mask(gLastUsedItem) & STATUS1_SLEEP)
gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_NIGHTMARE;
if (GetItemStatus2Mask(gLastUsedItem) & STATUS2_CONFUSION)
gStatuses4[gBattlerAttacker] &= ~STATUS4_INFINITE_CONFUSION;
// Heal Status1 conditions.
HealStatusConditions(&party[gBattleStruct->itemPartyIndex[gBattlerAttacker]], GetItemStatus1Mask(gLastUsedItem), battler);
if (GetItemStatus1Mask(gLastUsedItem) & STATUS1_SLEEP)
gBattleMons[battler].status2 &= ~STATUS2_NIGHTMARE;
if (GetItemStatus2Mask(gLastUsedItem) & STATUS2_CONFUSION)
gStatuses4[battler] &= ~STATUS4_INFINITE_CONFUSION;
gBattleScripting.battler = battler;
PREPARE_SPECIES_BUFFER(gBattleTextBuff1, GetMonData(&party[gBattleStruct->itemPartyIndex[gBattlerAttacker]], MON_DATA_SPECIES));
gBattlescriptCurrInstr = cmd->nextInstr;
}
@ -15975,6 +15980,7 @@ void BS_ItemRestorePP(void)
}
}
}
gBattleScripting.battler = battler;
PREPARE_SPECIES_BUFFER(gBattleTextBuff1, GetMonData(mon, MON_DATA_SPECIES));
gBattlescriptCurrInstr = cmd->nextInstr;
}

View File

@ -858,7 +858,7 @@ void CreateBoxMon(struct BoxPokemon *boxMon, u16 species, u8 level, u8 fixedIV,
SetBoxMonData(boxMon, MON_DATA_SPATK_IV, &iv);
SetBoxMonData(boxMon, MON_DATA_SPDEF_IV, &iv);
}
else if (P_LEGENDARY_PERFECT_IVS >= GEN_6
else if (P_LEGENDARY_PERFECT_IVS >= GEN_6
&& (gSpeciesInfo[species].isLegendary
|| gSpeciesInfo[species].isMythical
|| gSpeciesInfo[species].isUltraBeast))
@ -1824,11 +1824,11 @@ void SetMultiuseSpriteTemplateToPokemon(u16 speciesTag, u8 battlerPosition)
gMultiuseSpriteTemplate.paletteTag = speciesTag;
if (battlerPosition == B_POSITION_PLAYER_LEFT || battlerPosition == B_POSITION_PLAYER_RIGHT)
gMultiuseSpriteTemplate.anims = gAnims_MonPic;
else
else
{
if (speciesTag > SPECIES_SHINY_TAG)
speciesTag = speciesTag - SPECIES_SHINY_TAG;
speciesTag = SanitizeSpeciesId(speciesTag);
if (gSpeciesInfo[speciesTag].frontAnimFrames != NULL)
gMultiuseSpriteTemplate.anims = gSpeciesInfo[speciesTag].frontAnimFrames;
@ -3206,15 +3206,15 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 mov
}
// Cure status
if ((itemEffect[i] & ITEM3_SLEEP) && HealStatusConditions(mon, partyIndex, STATUS1_SLEEP, battlerId) == 0)
if ((itemEffect[i] & ITEM3_SLEEP) && HealStatusConditions(mon, STATUS1_SLEEP, battlerId) == 0)
retVal = FALSE;
if ((itemEffect[i] & ITEM3_POISON) && HealStatusConditions(mon, partyIndex, STATUS1_PSN_ANY | STATUS1_TOXIC_COUNTER, battlerId) == 0)
if ((itemEffect[i] & ITEM3_POISON) && HealStatusConditions(mon, STATUS1_PSN_ANY | STATUS1_TOXIC_COUNTER, battlerId) == 0)
retVal = FALSE;
if ((itemEffect[i] & ITEM3_BURN) && HealStatusConditions(mon, partyIndex, STATUS1_BURN, battlerId) == 0)
if ((itemEffect[i] & ITEM3_BURN) && HealStatusConditions(mon, STATUS1_BURN, battlerId) == 0)
retVal = FALSE;
if ((itemEffect[i] & ITEM3_FREEZE) && HealStatusConditions(mon, partyIndex, STATUS1_FREEZE | STATUS1_FROSTBITE, battlerId) == 0)
if ((itemEffect[i] & ITEM3_FREEZE) && HealStatusConditions(mon, STATUS1_FREEZE | STATUS1_FROSTBITE, battlerId) == 0)
retVal = FALSE;
if ((itemEffect[i] & ITEM3_PARALYSIS) && HealStatusConditions(mon, partyIndex, STATUS1_PARALYSIS, battlerId) == 0)
if ((itemEffect[i] & ITEM3_PARALYSIS) && HealStatusConditions(mon, STATUS1_PARALYSIS, battlerId) == 0)
retVal = FALSE;
break;
@ -3550,7 +3550,7 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 mov
return retVal;
}
bool8 HealStatusConditions(struct Pokemon *mon, u32 battlePartyId, u32 healMask, u8 battlerId)
bool8 HealStatusConditions(struct Pokemon *mon, u32 healMask, u8 battlerId)
{
u32 status = GetMonData(mon, MON_DATA_STATUS, 0);