Fix Full Restore / Antidote not reseting Toxic Counter (#4135)
* Fix Full Restore / Antidote not reseting Toxic Counter * Update battle_scripts_2.s --------- Co-authored-by: Bassoonian <iasperbassoonian@gmail.com>
This commit is contained in:
parent
452432533a
commit
31ac151e29
@ -1332,12 +1332,14 @@
|
||||
.4byte \jumpInstr
|
||||
.endm
|
||||
|
||||
.macro itemrestorehp
|
||||
.macro itemrestorehp jumpInstr:req
|
||||
callnative BS_ItemRestoreHP
|
||||
.4byte \jumpInstr
|
||||
.endm
|
||||
|
||||
.macro itemcurestatus
|
||||
.macro itemcurestatus jumpInstr:req
|
||||
callnative BS_ItemCureStatus
|
||||
.4byte \jumpInstr
|
||||
.endm
|
||||
|
||||
.macro itemincreasestat
|
||||
|
||||
@ -45,16 +45,21 @@ BattleScript_UseItemMessage:
|
||||
printfromtable gTrainerUsedItemStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
return
|
||||
|
||||
BattleScript_ItemRestoreHP::
|
||||
call BattleScript_UseItemMessage
|
||||
itemrestorehp
|
||||
|
||||
BattleScript_ItemRestoreHPRet:
|
||||
bichalfword gMoveResultFlags, MOVE_RESULT_NO_EFFECT
|
||||
orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE
|
||||
healthbarupdate BS_SCRIPTING
|
||||
datahpupdate BS_SCRIPTING
|
||||
printstring STRINGID_ITEMRESTOREDSPECIESHEALTH
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
return
|
||||
|
||||
BattleScript_ItemRestoreHP::
|
||||
call BattleScript_UseItemMessage
|
||||
itemrestorehp BattleScript_ItemRestoreHPEnd
|
||||
call BattleScript_ItemRestoreHPRet
|
||||
BattleScript_ItemRestoreHPEnd:
|
||||
end
|
||||
|
||||
BattleScript_ItemRestoreHP_Party::
|
||||
@ -72,26 +77,19 @@ BattleScript_ItemRestoreHP_SendOutRevivedBattler:
|
||||
|
||||
BattleScript_ItemCureStatus::
|
||||
call BattleScript_UseItemMessage
|
||||
itemcurestatus
|
||||
BattleScript_ItemCureStatusAfterItemMsg:
|
||||
itemcurestatus BattleScript_ItemCureStatusEnd
|
||||
updatestatusicon BS_SCRIPTING
|
||||
printstring STRINGID_ITEMCUREDSPECIESSTATUS
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
BattleScript_ItemCureStatusEnd:
|
||||
end
|
||||
|
||||
BattleScript_ItemHealAndCureStatus::
|
||||
call BattleScript_UseItemMessage
|
||||
itemrestorehp
|
||||
itemcurestatus
|
||||
printstring STRINGID_ITEMRESTOREDSPECIESHEALTH
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
bichalfword gMoveResultFlags, MOVE_RESULT_NO_EFFECT
|
||||
orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE
|
||||
healthbarupdate BS_SCRIPTING
|
||||
datahpupdate BS_SCRIPTING
|
||||
updatestatusicon BS_SCRIPTING
|
||||
printstring STRINGID_ITEMRESTOREDSPECIESHEALTH
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
end
|
||||
itemrestorehp BattleScript_ItemCureStatusAfterItemMsg
|
||||
call BattleScript_ItemRestoreHPRet
|
||||
goto BattleScript_ItemCureStatusAfterItemMsg
|
||||
|
||||
BattleScript_ItemIncreaseStat::
|
||||
call BattleScript_UseItemMessage
|
||||
@ -118,7 +116,7 @@ BattleScript_ItemSetFocusEnergy::
|
||||
setfocusenergy
|
||||
playmoveanimation BS_ATTACKER, MOVE_FOCUS_ENERGY
|
||||
waitanimation
|
||||
copybyte sBATTLER, gBattlerAttacker
|
||||
copybyte sBATTLER, gBattlerAttacker
|
||||
printstring STRINGID_PKMNUSEDXTOGETPUMPED
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
end
|
||||
|
||||
@ -15793,7 +15793,7 @@ void ApplyExperienceMultipliers(s32 *expAmount, u8 expGetterMonId, u8 faintedBat
|
||||
|
||||
void BS_ItemRestoreHP(void)
|
||||
{
|
||||
NATIVE_ARGS();
|
||||
NATIVE_ARGS(const u8 *alreadyMaxHpInstr);
|
||||
u16 healAmount;
|
||||
u32 battler = MAX_BATTLERS_COUNT;
|
||||
u32 healParam = GetItemEffect(gLastUsedItem)[6];
|
||||
@ -15803,90 +15803,113 @@ void BS_ItemRestoreHP(void)
|
||||
u16 maxHP = GetMonData(&party[gBattleStruct->itemPartyIndex[gBattlerAttacker]], MON_DATA_MAX_HP);
|
||||
gBattleCommunication[MULTIUSE_STATE] = 0;
|
||||
|
||||
// Track the number of Revives used in a battle.
|
||||
if (hp == 0 && side == B_SIDE_PLAYER && gBattleResults.numRevivesUsed < 255)
|
||||
gBattleResults.numRevivesUsed++;
|
||||
|
||||
// Check if the recipient is an active battler.
|
||||
if (gBattleStruct->itemPartyIndex[gBattlerAttacker] == gBattlerPartyIndexes[gBattlerAttacker])
|
||||
battler = gBattlerAttacker;
|
||||
else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE
|
||||
&& gBattleStruct->itemPartyIndex[gBattlerAttacker] == gBattlerPartyIndexes[BATTLE_PARTNER(gBattlerAttacker)])
|
||||
battler = BATTLE_PARTNER(gBattlerAttacker);
|
||||
|
||||
// Get amount to heal.
|
||||
switch (healParam)
|
||||
if (hp == maxHP)
|
||||
{
|
||||
case ITEM6_HEAL_HP_FULL:
|
||||
healAmount = maxHP;
|
||||
break;
|
||||
case ITEM6_HEAL_HP_HALF:
|
||||
healAmount = maxHP / 2;
|
||||
break;
|
||||
case ITEM6_HEAL_HP_QUARTER:
|
||||
healAmount = maxHP / 4;
|
||||
break;
|
||||
default:
|
||||
healAmount = healParam;
|
||||
break;
|
||||
}
|
||||
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;
|
||||
gBattlescriptCurrInstr = cmd->alreadyMaxHpInstr;
|
||||
}
|
||||
else
|
||||
{
|
||||
hp += healAmount;
|
||||
SetMonData(&party[gBattleStruct->itemPartyIndex[gBattlerAttacker]], MON_DATA_HP, &hp);
|
||||
// Track the number of Revives used in a battle.
|
||||
if (hp == 0 && side == B_SIDE_PLAYER && gBattleResults.numRevivesUsed < 255)
|
||||
gBattleResults.numRevivesUsed++;
|
||||
|
||||
// Revived battlers on the field need to be brought back.
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && battler != MAX_BATTLERS_COUNT)
|
||||
// Check if the recipient is an active battler.
|
||||
if (gBattleStruct->itemPartyIndex[gBattlerAttacker] == gBattlerPartyIndexes[gBattlerAttacker])
|
||||
battler = gBattlerAttacker;
|
||||
else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE
|
||||
&& gBattleStruct->itemPartyIndex[gBattlerAttacker] == gBattlerPartyIndexes[BATTLE_PARTNER(gBattlerAttacker)])
|
||||
battler = BATTLE_PARTNER(gBattlerAttacker);
|
||||
|
||||
// Get amount to heal.
|
||||
switch (healParam)
|
||||
{
|
||||
gAbsentBattlerFlags &= ~gBitTable[battler];
|
||||
gBattleCommunication[MULTIUSE_STATE] = TRUE;
|
||||
case ITEM6_HEAL_HP_FULL:
|
||||
healAmount = maxHP;
|
||||
break;
|
||||
case ITEM6_HEAL_HP_HALF:
|
||||
healAmount = maxHP / 2;
|
||||
break;
|
||||
case ITEM6_HEAL_HP_QUARTER:
|
||||
healAmount = maxHP / 4;
|
||||
break;
|
||||
default:
|
||||
healAmount = healParam;
|
||||
break;
|
||||
}
|
||||
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
|
||||
{
|
||||
hp += healAmount;
|
||||
SetMonData(&party[gBattleStruct->itemPartyIndex[gBattlerAttacker]], MON_DATA_HP, &hp);
|
||||
|
||||
// Revived battlers on the field need to be brought back.
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && battler != MAX_BATTLERS_COUNT)
|
||||
{
|
||||
gAbsentBattlerFlags &= ~gBitTable[battler];
|
||||
gBattleCommunication[MULTIUSE_STATE] = TRUE;
|
||||
}
|
||||
gBattlescriptCurrInstr = BattleScript_ItemRestoreHP_Party;
|
||||
}
|
||||
gBattlescriptCurrInstr = BattleScript_ItemRestoreHP_Party;
|
||||
}
|
||||
}
|
||||
|
||||
void BS_ItemCureStatus(void)
|
||||
{
|
||||
NATIVE_ARGS();
|
||||
NATIVE_ARGS(const u8 *noStatusInstr);
|
||||
u32 battler = gBattlerAttacker;
|
||||
u32 side = GetBattlerSide(gBattlerAttacker);
|
||||
u32 previousStatus2 = 0;
|
||||
bool32 statusChanged = FALSE;
|
||||
struct Pokemon *party = GetSideParty(side);
|
||||
|
||||
// Heal Status2 conditions if battler is active.
|
||||
if (gBattleStruct->itemPartyIndex[gBattlerAttacker] == gBattlerPartyIndexes[gBattlerAttacker])
|
||||
{
|
||||
previousStatus2 = gBattleMons[battler].status2;
|
||||
gBattleMons[gBattlerAttacker].status2 &= ~GetItemStatus2Mask(gLastUsedItem);
|
||||
}
|
||||
else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE
|
||||
&& gBattleStruct->itemPartyIndex[gBattlerAttacker] == gBattlerPartyIndexes[BATTLE_PARTNER(gBattlerAttacker)])
|
||||
{
|
||||
gBattleMons[gBattlerAttacker].status2 &= ~GetItemStatus2Mask(gLastUsedItem);
|
||||
battler = BATTLE_PARTNER(gBattlerAttacker);
|
||||
previousStatus2 = gBattleMons[battler].status2;
|
||||
gBattleMons[battler].status2 &= ~GetItemStatus2Mask(gLastUsedItem);
|
||||
}
|
||||
|
||||
if (previousStatus2 != gBattleMons[battler].status2)
|
||||
statusChanged = TRUE;
|
||||
|
||||
// Heal Status1 conditions.
|
||||
HealStatusConditions(&party[gBattleStruct->itemPartyIndex[gBattlerAttacker]], GetItemStatus1Mask(gLastUsedItem), battler);
|
||||
if (!HealStatusConditions(&party[gBattleStruct->itemPartyIndex[gBattlerAttacker]], GetItemStatus1Mask(gLastUsedItem), battler))
|
||||
{
|
||||
statusChanged = TRUE;
|
||||
if (GetItemStatus1Mask(gLastUsedItem) & STATUS1_SLEEP)
|
||||
gBattleMons[battler].status2 &= ~STATUS2_NIGHTMARE;
|
||||
if (GetItemStatus2Mask(gLastUsedItem) & STATUS2_CONFUSION)
|
||||
gStatuses4[battler] &= ~STATUS4_INFINITE_CONFUSION;
|
||||
}
|
||||
|
||||
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;
|
||||
if (statusChanged)
|
||||
{
|
||||
gBattleScripting.battler = battler;
|
||||
PREPARE_SPECIES_BUFFER(gBattleTextBuff1, GetMonData(&party[gBattleStruct->itemPartyIndex[gBattlerAttacker]], MON_DATA_SPECIES));
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattlescriptCurrInstr = cmd->noStatusInstr;
|
||||
}
|
||||
}
|
||||
|
||||
void BS_ItemIncreaseStat(void)
|
||||
|
||||
@ -974,11 +974,11 @@ u32 GetItemStatus1Mask(u16 itemId)
|
||||
case ITEM3_BURN:
|
||||
return STATUS1_BURN;
|
||||
case ITEM3_POISON:
|
||||
return STATUS1_POISON | STATUS1_TOXIC_POISON;
|
||||
return STATUS1_PSN_ANY | STATUS1_TOXIC_COUNTER;
|
||||
case ITEM3_SLEEP:
|
||||
return STATUS1_SLEEP;
|
||||
case ITEM3_STATUS_ALL:
|
||||
return STATUS1_ANY;
|
||||
return STATUS1_ANY | STATUS1_TOXIC_COUNTER;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -46,6 +46,24 @@ SINGLE_BATTLE_TEST("Antidote heals a battler from being badly poisoned")
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Antidote resets Toxic Counter")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gItems[ITEM_ANTIDOTE].battleUsage == EFFECT_ITEM_CURE_STATUS);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_TOXIC); }
|
||||
TURN { ; }
|
||||
TURN { USE_ITEM(player, ITEM_ANTIDOTE, partyIndex: 0); }
|
||||
} SCENE {
|
||||
MESSAGE("Foe Wobbuffet used Toxic!");
|
||||
MESSAGE("Wobbuffet had its status healed!");
|
||||
} THEN {
|
||||
EXPECT_EQ(player->status1, STATUS1_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Awakening heals a battler from being asleep")
|
||||
{
|
||||
GIVEN {
|
||||
|
||||
@ -1,6 +1,11 @@
|
||||
#include "global.h"
|
||||
#include "test/battle.h"
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(gItems[ITEM_FULL_RESTORE].battleUsage == EFFECT_ITEM_HEAL_AND_CURE_STATUS);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Full Restore restores a battler's HP and cures any primary status")
|
||||
{
|
||||
u16 status;
|
||||
@ -10,24 +15,48 @@ SINGLE_BATTLE_TEST("Full Restore restores a battler's HP and cures any primary s
|
||||
PARAMETRIZE{ status = STATUS1_POISON; }
|
||||
PARAMETRIZE{ status = STATUS1_TOXIC_POISON; }
|
||||
PARAMETRIZE{ status = STATUS1_SLEEP; }
|
||||
PARAMETRIZE{ status = STATUS1_NONE; }
|
||||
GIVEN {
|
||||
ASSUME(gItems[ITEM_FULL_RESTORE].battleUsage == EFFECT_ITEM_HEAL_AND_CURE_STATUS);
|
||||
PLAYER(SPECIES_WOBBUFFET) { HP(1); MaxHP(300); Status1(status); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN{ USE_ITEM(player, ITEM_FULL_RESTORE, partyIndex: 0); }
|
||||
} SCENE {
|
||||
MESSAGE("Wobbuffet had its HP restored!");
|
||||
if (status != STATUS1_NONE) {
|
||||
MESSAGE("Wobbuffet had its status healed!"); // The message is not printed if status wasn't healed.
|
||||
}
|
||||
} THEN {
|
||||
EXPECT_EQ(player->hp, player->maxHP);
|
||||
EXPECT_EQ(player->status1, STATUS1_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Full Restore heals a battler from any primary status")
|
||||
{
|
||||
u16 status;
|
||||
PARAMETRIZE{ status = STATUS1_BURN; }
|
||||
PARAMETRIZE{ status = STATUS1_FREEZE; }
|
||||
PARAMETRIZE{ status = STATUS1_PARALYSIS; }
|
||||
PARAMETRIZE{ status = STATUS1_POISON; }
|
||||
PARAMETRIZE{ status = STATUS1_TOXIC_POISON; }
|
||||
PARAMETRIZE{ status = STATUS1_SLEEP; }
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { Status1(status); }
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
} WHEN {
|
||||
TURN { USE_ITEM(player, ITEM_FULL_RESTORE, partyIndex: 0); }
|
||||
} SCENE {
|
||||
NOT MESSAGE("Wobbuffet had its HP restored!"); // The message is not printed if mon has max HP.
|
||||
MESSAGE("Wobbuffet had its status healed!");
|
||||
} THEN {
|
||||
EXPECT_EQ(player->status1, STATUS1_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Full Restore restores a battler's HP and cures confusion")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gItems[ITEM_FULL_RESTORE].battleUsage == EFFECT_ITEM_HEAL_AND_CURE_STATUS);
|
||||
PLAYER(SPECIES_WOBBUFFET) { HP(1); MaxHP(300); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
@ -41,3 +70,21 @@ SINGLE_BATTLE_TEST("Full Restore restores a battler's HP and cures confusion")
|
||||
EXPECT_EQ(player->hp, player->maxHP);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Full Restore resets Toxic Counter")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_TOXIC); }
|
||||
TURN { ; }
|
||||
TURN { USE_ITEM(player, ITEM_FULL_RESTORE, partyIndex: 0); }
|
||||
} SCENE {
|
||||
MESSAGE("Foe Wobbuffet used Toxic!");
|
||||
MESSAGE("Wobbuffet had its HP restored!");
|
||||
MESSAGE("Wobbuffet had its status healed!");
|
||||
} THEN {
|
||||
EXPECT_EQ(player->status1, STATUS1_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user