mirror of
https://github.com/pret/pokefirered.git
synced 2026-09-30 12:59:43 -05:00
updated up to Cmd_tryswapitems
This commit is contained in:
@@ -1099,34 +1099,34 @@
|
||||
.byte 0xcc
|
||||
.endm
|
||||
|
||||
.macro cureifburnedparalysedorpoisoned param0:req
|
||||
.macro cureifburnedparalysedorpoisoned failInstr:req
|
||||
.byte 0xcd
|
||||
.4byte \param0
|
||||
.4byte \failInstr
|
||||
.endm
|
||||
|
||||
.macro settorment param0:req
|
||||
.macro settorment failInstr:req
|
||||
.byte 0xce
|
||||
.4byte \param0
|
||||
.4byte \failInstr
|
||||
.endm
|
||||
|
||||
.macro jumpifnodamage param0:req
|
||||
.macro jumpifnodamage jumpInstr:req
|
||||
.byte 0xcf
|
||||
.4byte \param0
|
||||
.4byte \jumpInstr
|
||||
.endm
|
||||
|
||||
.macro settaunt param0:req
|
||||
.macro settaunt failInstr:req
|
||||
.byte 0xd0
|
||||
.4byte \param0
|
||||
.4byte \failInstr
|
||||
.endm
|
||||
|
||||
.macro trysethelpinghand param0:req
|
||||
.macro trysethelpinghand failInstr:req
|
||||
.byte 0xd1
|
||||
.4byte \param0
|
||||
.4byte \failInstr
|
||||
.endm
|
||||
|
||||
.macro tryswapitems param0:req
|
||||
.macro tryswapitems failInstr:req
|
||||
.byte 0xd2
|
||||
.4byte \param0
|
||||
.4byte \failInstr
|
||||
.endm
|
||||
|
||||
.macro trycopyability param0:req
|
||||
|
||||
@@ -1998,7 +1998,7 @@ BattleScript_EffectTrick::
|
||||
attackcanceler
|
||||
attackstring
|
||||
ppreduce
|
||||
jumpifstatus2 BS_TARGET, STATUS2_SUBSTITUTE, BattleScript_ButItFailed
|
||||
jumpifsubstituteblocks BattleScript_ButItFailed
|
||||
accuracycheck BattleScript_ButItFailed, ACC_CURR_MOVE
|
||||
tryswapitems BattleScript_ButItFailed
|
||||
attackanimation
|
||||
|
||||
@@ -87,19 +87,6 @@ enum {
|
||||
#define MOVE_TARGET_ALLY (1 << 7)
|
||||
#define MOVE_TARGET_ALL_BATTLERS ((1 << 8) | MOVE_TARGET_USER)
|
||||
|
||||
// For the second argument of GetMoveTarget, when no target override is needed
|
||||
#define NO_TARGET_OVERRIDE 0
|
||||
|
||||
// Constants for Parental Bond
|
||||
#define PARENTAL_BOND_1ST_HIT 2
|
||||
#define PARENTAL_BOND_2ND_HIT 1
|
||||
#define PARENTAL_BOND_OFF 0
|
||||
|
||||
// Constants for if HandleScriptMegaPrimalBurst should handle Mega Evolution, Primal Reversion, or Ultra Burst.
|
||||
#define HANDLE_TYPE_MEGA_EVOLUTION 0
|
||||
#define HANDLE_TYPE_PRIMAL_REVERSION 1
|
||||
#define HANDLE_TYPE_ULTRA_BURST 2
|
||||
|
||||
struct TrainerMonNoItemDefaultMoves
|
||||
{
|
||||
u16 iv;
|
||||
|
||||
@@ -1199,7 +1199,6 @@ extern const u8 BattleScript_EffectFollowMe[];
|
||||
extern const u8 BattleScript_EffectNaturePower[];
|
||||
extern const u8 BattleScript_EffectTaunt[];
|
||||
extern const u8 BattleScript_EffectHelpingHand[];
|
||||
extern const u8 BattleScript_EffectTrick[];
|
||||
extern const u8 BattleScript_EffectRolePlay[];
|
||||
extern const u8 BattleScript_EffectWish[];
|
||||
extern const u8 BattleScript_EffectAssist[];
|
||||
|
||||
@@ -238,6 +238,7 @@ s32 GetStealthHazardDamage(u8 hazardType, u32 battler);
|
||||
s32 GetStealthHazardDamageByTypesAndHP(u8 hazardType, u8 type1, u8 type2, u32 maxHp);
|
||||
bool32 DoBattlersShareType(u32 battler1, u32 battler2);
|
||||
bool32 MoveHasChargeTurnAdditionalEffect(u32 move);
|
||||
bool32 IsPartnerMonFromSameTrainer(u32 battler);
|
||||
|
||||
// battle_ai_util.h
|
||||
bool32 IsHealingMove(u32 move);
|
||||
|
||||
@@ -497,6 +497,33 @@
|
||||
// Indicator for the party summary bar to display an empty slot.
|
||||
#define HP_EMPTY_SLOT 0xFFFF
|
||||
|
||||
#define MOVE_TARGET_SELECTED 0
|
||||
#define MOVE_TARGET_DEPENDS (1 << 0)
|
||||
#define MOVE_TARGET_USER_OR_SELECTED (1 << 1)
|
||||
#define MOVE_TARGET_RANDOM (1 << 2)
|
||||
#define MOVE_TARGET_BOTH (1 << 3)
|
||||
#define MOVE_TARGET_USER (1 << 4)
|
||||
#define MOVE_TARGET_FOES_AND_ALLY (1 << 5)
|
||||
#define MOVE_TARGET_OPPONENTS_FIELD (1 << 6)
|
||||
#define MOVE_TARGET_ALLY (1 << 7)
|
||||
#define MOVE_TARGET_ALL_BATTLERS ((1 << 8) | MOVE_TARGET_USER)
|
||||
|
||||
// For the second argument of GetMoveTarget, when no target override is needed
|
||||
#define NO_TARGET_OVERRIDE 0
|
||||
|
||||
// Constants for Parental Bond
|
||||
#define PARENTAL_BOND_1ST_HIT 2
|
||||
#define PARENTAL_BOND_2ND_HIT 1
|
||||
#define PARENTAL_BOND_OFF 0
|
||||
|
||||
// Constants for if HandleScriptMegaPrimalBurst should handle Mega Evolution, Primal Reversion, or Ultra Burst.
|
||||
#define HANDLE_TYPE_MEGA_EVOLUTION 0
|
||||
#define HANDLE_TYPE_PRIMAL_REVERSION 1
|
||||
#define HANDLE_TYPE_ULTRA_BURST 2
|
||||
|
||||
// Constants for Torment
|
||||
#define PERMANENT_TORMENT 0xF
|
||||
|
||||
// Constants for B_VAR_STARTING_STATUS
|
||||
// Timer value controlled by B_VAR_STARTING_STATUS_TIMER
|
||||
#define STARTING_STATUS_NONE 0
|
||||
|
||||
@@ -798,12 +798,12 @@ void (* const gBattleScriptingCommandsTable[])(void) =
|
||||
Cmd_setforcedtarget, //0xCA // done
|
||||
Cmd_setcharge, //0xCB // done
|
||||
Cmd_callterrainattack, //0xCC // done
|
||||
Cmd_cureifburnedparalysedorpoisoned, //0xCD
|
||||
Cmd_settorment, //0xCE
|
||||
Cmd_jumpifnodamage, //0xCF
|
||||
Cmd_settaunt, //0xD0
|
||||
Cmd_trysethelpinghand, //0xD1
|
||||
Cmd_tryswapitems, //0xD2
|
||||
Cmd_cureifburnedparalysedorpoisoned, //0xCD // done
|
||||
Cmd_settorment, //0xCE // done
|
||||
Cmd_jumpifnodamage, //0xCF // done
|
||||
Cmd_settaunt, //0xD0 // done
|
||||
Cmd_trysethelpinghand, //0xD1 // done
|
||||
Cmd_tryswapitems, //0xD2 // done
|
||||
Cmd_trycopyability, //0xD3
|
||||
Cmd_trywish, //0xD4
|
||||
Cmd_settoxicspikes, //0xD5 // done
|
||||
@@ -14307,92 +14307,128 @@ u16 GetNaturePowerMove(void)
|
||||
// Refresh
|
||||
static void Cmd_cureifburnedparalysedorpoisoned(void)
|
||||
{
|
||||
if (gBattleMons[gBattlerAttacker].status1 & (STATUS1_POISON | STATUS1_BURN | STATUS1_PARALYSIS | STATUS1_TOXIC_POISON))
|
||||
CMD_ARGS(const u8 *failInstr);
|
||||
|
||||
if (gBattleMons[gBattlerAttacker].status1 & (STATUS1_POISON | STATUS1_BURN | STATUS1_PARALYSIS | STATUS1_TOXIC_POISON | STATUS1_FROSTBITE))
|
||||
{
|
||||
gBattleMons[gBattlerAttacker].status1 = 0;
|
||||
gBattlescriptCurrInstr += 5;
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
gActiveBattler = gBattlerAttacker;
|
||||
BtlController_EmitSetMonData(BUFFER_A, REQUEST_STATUS_BATTLE, 0, sizeof(gBattleMons[gActiveBattler].status1), &gBattleMons[gActiveBattler].status1);
|
||||
MarkBattlerForControllerExec(gActiveBattler);
|
||||
BtlController_EmitSetMonData(BUFFER_A, REQUEST_STATUS_BATTLE, 0, sizeof(gBattleMons[gBattlerAttacker].status1), &gBattleMons[gBattlerAttacker].status1);
|
||||
MarkBattlerForControllerExec(gBattlerAttacker);
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
|
||||
gBattlescriptCurrInstr = cmd->failInstr;
|
||||
}
|
||||
}
|
||||
|
||||
static void Cmd_settorment(void)
|
||||
{
|
||||
if (gBattleMons[gBattlerTarget].status2 & STATUS2_TORMENT)
|
||||
CMD_ARGS(const u8 *failInstr);
|
||||
|
||||
if (gBattleMons[gBattlerTarget].status2 & STATUS2_TORMENT
|
||||
/* || IsDynamaxed(gBattlerTarget) */) // TODO: Dynamax
|
||||
{
|
||||
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
|
||||
gBattlescriptCurrInstr = cmd->failInstr;
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattleMons[gBattlerTarget].status2 |= STATUS2_TORMENT;
|
||||
gBattlescriptCurrInstr += 5;
|
||||
gDisableStructs[gBattlerTarget].tormentTimer = PERMANENT_TORMENT; // permanent
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
}
|
||||
|
||||
static void Cmd_jumpifnodamage(void)
|
||||
{
|
||||
CMD_ARGS(const u8 *jumpInstr);
|
||||
|
||||
if (gProtectStructs[gBattlerAttacker].physicalDmg || gProtectStructs[gBattlerAttacker].specialDmg)
|
||||
gBattlescriptCurrInstr += 5;
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
else
|
||||
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
|
||||
gBattlescriptCurrInstr = cmd->jumpInstr;
|
||||
}
|
||||
|
||||
static void Cmd_settaunt(void)
|
||||
{
|
||||
if (gDisableStructs[gBattlerTarget].tauntTimer == 0)
|
||||
CMD_ARGS(const u8 *failInstr);
|
||||
|
||||
if (B_OBLIVIOUS_TAUNT >= GEN_6 && GetBattlerAbility(gBattlerTarget) == ABILITY_OBLIVIOUS)
|
||||
{
|
||||
gDisableStructs[gBattlerTarget].tauntTimer = 2;
|
||||
// gDisableStructs[gBattlerTarget].tauntTimer2 = 2;
|
||||
gBattlescriptCurrInstr += 5;
|
||||
gBattlescriptCurrInstr = BattleScript_NotAffectedAbilityPopUp;
|
||||
gLastUsedAbility = ABILITY_OBLIVIOUS;
|
||||
RecordAbilityBattle(gBattlerTarget, ABILITY_OBLIVIOUS);
|
||||
}
|
||||
else if (gDisableStructs[gBattlerTarget].tauntTimer == 0)
|
||||
{
|
||||
u8 turns;
|
||||
if (B_TAUNT_TURNS >= GEN_5)
|
||||
{
|
||||
turns = 4;
|
||||
if (GetBattlerTurnOrderNum(gBattlerTarget) > GetBattlerTurnOrderNum(gBattlerAttacker))
|
||||
turns--; // If the target hasn't yet moved this turn, Taunt lasts for only three turns (source: Bulbapedia)
|
||||
}
|
||||
else if (B_TAUNT_TURNS >= GEN_4)
|
||||
{
|
||||
turns = (Random() & 2) + 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
turns = 2;
|
||||
}
|
||||
|
||||
gDisableStructs[gBattlerTarget].tauntTimer = turns;
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
|
||||
gBattlescriptCurrInstr = cmd->failInstr;
|
||||
}
|
||||
}
|
||||
|
||||
static void Cmd_trysethelpinghand(void)
|
||||
{
|
||||
gBattlerTarget = GetBattlerAtPosition(GetBattlerPosition(gBattlerAttacker) ^ BIT_FLANK);
|
||||
CMD_ARGS(const u8 *failInstr);
|
||||
|
||||
gBattlerTarget = GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gBattlerAttacker)));
|
||||
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE
|
||||
&& !(gAbsentBattlerFlags & gBitTable[gBattlerTarget])
|
||||
&& !gProtectStructs[gBattlerAttacker].helpingHand
|
||||
&& !gProtectStructs[gBattlerTarget].helpingHand)
|
||||
{
|
||||
gProtectStructs[gBattlerTarget].helpingHand = 1;
|
||||
gBattlescriptCurrInstr += 5;
|
||||
gProtectStructs[gBattlerTarget].helpingHand = TRUE;
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
|
||||
gBattlescriptCurrInstr = cmd->failInstr;
|
||||
}
|
||||
}
|
||||
|
||||
// Trick
|
||||
static void Cmd_tryswapitems(void)
|
||||
{
|
||||
CMD_ARGS(const u8 *failInstr);
|
||||
|
||||
// opponent can't swap items with player in regular battles
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_TRAINER_TOWER
|
||||
|| (GetBattlerSide(gBattlerAttacker) == B_SIDE_OPPONENT
|
||||
&& !(gBattleTypeFlags & (BATTLE_TYPE_LINK
|
||||
| BATTLE_TYPE_BATTLE_TOWER
|
||||
| BATTLE_TYPE_EREADER_TRAINER))
|
||||
&& gTrainerBattleOpponent_A != TRAINER_SECRET_BASE))
|
||||
| BATTLE_TYPE_EREADER_TRAINER
|
||||
| (B_TRAINERS_KNOCK_OFF_ITEMS == TRUE ? BATTLE_TYPE_TRAINER : 0)))
|
||||
&& gTrainerBattleOpponent_A != TRAINER_SECRET_BASE))
|
||||
{
|
||||
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
|
||||
gBattlescriptCurrInstr = cmd->failInstr;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8 sideAttacker = GetBattlerSide(gBattlerAttacker);
|
||||
u8 sideTarget = GetBattlerSide(gBattlerTarget);
|
||||
|
||||
// you can't swap items if they were knocked off in regular battles
|
||||
// You can't swap items if they were knocked off in regular battles
|
||||
if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK
|
||||
| BATTLE_TYPE_BATTLE_TOWER
|
||||
| BATTLE_TYPE_EREADER_TRAINER))
|
||||
@@ -14400,20 +14436,20 @@ static void Cmd_tryswapitems(void)
|
||||
&& (gWishFutureKnock.knockedOffMons[sideAttacker] & gBitTable[gBattlerPartyIndexes[gBattlerAttacker]]
|
||||
|| gWishFutureKnock.knockedOffMons[sideTarget] & gBitTable[gBattlerPartyIndexes[gBattlerTarget]]))
|
||||
{
|
||||
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
|
||||
gBattlescriptCurrInstr = cmd->failInstr;
|
||||
}
|
||||
// can't swap if two pokemon don't have an item
|
||||
// can't swap if two Pokémon don't have an item
|
||||
// or if either of them is an enigma berry or a mail
|
||||
else if ((gBattleMons[gBattlerAttacker].item == ITEM_NONE && gBattleMons[gBattlerTarget].item == ITEM_NONE)
|
||||
|| gBattleMons[gBattlerAttacker].item == ITEM_ENIGMA_BERRY
|
||||
|| gBattleMons[gBattlerTarget].item == ITEM_ENIGMA_BERRY
|
||||
|| IS_ITEM_MAIL(gBattleMons[gBattlerAttacker].item)
|
||||
|| IS_ITEM_MAIL(gBattleMons[gBattlerTarget].item))
|
||||
|| !CanBattlerGetOrLoseItem(gBattlerAttacker, gBattleMons[gBattlerAttacker].item)
|
||||
|| !CanBattlerGetOrLoseItem(gBattlerAttacker, gBattleMons[gBattlerTarget].item)
|
||||
|| !CanBattlerGetOrLoseItem(gBattlerTarget, gBattleMons[gBattlerTarget].item)
|
||||
|| !CanBattlerGetOrLoseItem(gBattlerTarget, gBattleMons[gBattlerAttacker].item))
|
||||
{
|
||||
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
|
||||
gBattlescriptCurrInstr = cmd->failInstr;
|
||||
}
|
||||
// check if ability prevents swapping
|
||||
else if (gBattleMons[gBattlerTarget].ability == ABILITY_STICKY_HOLD)
|
||||
else if (GetBattlerAbility(gBattlerTarget) == ABILITY_STICKY_HOLD)
|
||||
{
|
||||
gBattlescriptCurrInstr = BattleScript_StickyHoldActivates;
|
||||
gLastUsedAbility = gBattleMons[gBattlerTarget].ability;
|
||||
@@ -14431,6 +14467,9 @@ static void Cmd_tryswapitems(void)
|
||||
gBattleMons[gBattlerAttacker].item = ITEM_NONE;
|
||||
gBattleMons[gBattlerTarget].item = oldItemAtk;
|
||||
|
||||
RecordItemEffectBattle(gBattlerAttacker, 0);
|
||||
RecordItemEffectBattle(gBattlerTarget, ItemId_GetHoldEffect(oldItemAtk));
|
||||
|
||||
gActiveBattler = gBattlerAttacker;
|
||||
BtlController_EmitSetMonData(BUFFER_A, REQUEST_HELDITEM_BATTLE, 0, sizeof(*newItemAtk), newItemAtk);
|
||||
MarkBattlerForControllerExec(gBattlerAttacker);
|
||||
@@ -14439,23 +14478,39 @@ static void Cmd_tryswapitems(void)
|
||||
BtlController_EmitSetMonData(BUFFER_A, REQUEST_HELDITEM_BATTLE, 0, sizeof(gBattleMons[gBattlerTarget].item), &gBattleMons[gBattlerTarget].item);
|
||||
MarkBattlerForControllerExec(gBattlerTarget);
|
||||
|
||||
*(u8 *)((u8 *)(&gBattleStruct->choicedMove[gBattlerTarget]) + 0) = 0;
|
||||
*(u8 *)((u8 *)(&gBattleStruct->choicedMove[gBattlerTarget]) + 1) = 0;
|
||||
gBattleStruct->choicedMove[gBattlerTarget] = MOVE_NONE;
|
||||
gBattleStruct->choicedMove[gBattlerAttacker] = MOVE_NONE;
|
||||
|
||||
*(u8 *)((u8 *)(&gBattleStruct->choicedMove[gBattlerAttacker]) + 0) = 0;
|
||||
*(u8 *)((u8 *)(&gBattleStruct->choicedMove[gBattlerAttacker]) + 1) = 0;
|
||||
|
||||
gBattlescriptCurrInstr += 5;
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
|
||||
PREPARE_ITEM_BUFFER(gBattleTextBuff1, *newItemAtk)
|
||||
PREPARE_ITEM_BUFFER(gBattleTextBuff2, oldItemAtk)
|
||||
|
||||
if (!(sideAttacker == sideTarget && IsPartnerMonFromSameTrainer(gBattlerAttacker)))
|
||||
{
|
||||
// if targeting your own side and you aren't in a multi battle, don't save items as stolen
|
||||
if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER)
|
||||
TrySaveExchangedItem(gBattlerAttacker, oldItemAtk);
|
||||
if (GetBattlerSide(gBattlerTarget) == B_SIDE_PLAYER)
|
||||
TrySaveExchangedItem(gBattlerTarget, *newItemAtk);
|
||||
}
|
||||
|
||||
if (oldItemAtk != ITEM_NONE && *newItemAtk != ITEM_NONE)
|
||||
{
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_ITEM_SWAP_BOTH; // attacker's item -> <- target's item
|
||||
}
|
||||
else if (oldItemAtk == ITEM_NONE && *newItemAtk != ITEM_NONE)
|
||||
{
|
||||
if (GetBattlerAbility(gBattlerAttacker) == ABILITY_UNBURDEN && gBattleResources->flags->flags[gBattlerAttacker] & RESOURCE_FLAG_UNBURDEN)
|
||||
gBattleResources->flags->flags[gBattlerAttacker] &= ~RESOURCE_FLAG_UNBURDEN;
|
||||
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_ITEM_SWAP_TAKEN; // nothing -> <- target's item
|
||||
}
|
||||
else
|
||||
{
|
||||
CheckSetUnburden(gBattlerAttacker);
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_ITEM_SWAP_GIVEN; // attacker's item -> <- nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9520,6 +9520,18 @@ bool32 MoveHasChargeTurnAdditionalEffect(u32 move)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 IsPartnerMonFromSameTrainer(u32 battler)
|
||||
{
|
||||
if (GetBattlerSide(battler) == B_SIDE_OPPONENT && gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS)
|
||||
return FALSE;
|
||||
else if (GetBattlerSide(battler) == B_SIDE_PLAYER && gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER)
|
||||
return FALSE;
|
||||
else if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
|
||||
return FALSE;
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// battle_ai_util.c
|
||||
|
||||
Reference in New Issue
Block a user