Merge pull request #1581 from ghoulslash/bug_bite

Bug Bite and Stuff Cheeks
This commit is contained in:
Eduardo Quezada D'Ottone 2021-10-14 20:09:58 -03:00 committed by GitHub
commit 8a6aee7546
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 107 additions and 14 deletions

View File

@ -1768,6 +1768,11 @@
.macro tryactivategrimneigh, battler:req
various \battler, VARIOUS_TRY_ACTIVATE_GRIM_NEIGH
.endm
.macro consumeberry battler:req, restoreItem=FALSE
various \battler, VARIOUS_CONSUME_BERRY
.byte \restoreItem
.endm
.macro activateitemeffects battler:req
various \battler, VARIOUS_MOVEEND_ITEM_EFFECTS

View File

@ -380,6 +380,30 @@ gBattleScriptsForMoveEffects::
.4byte BattleScript_EffectHit @ EFFECT_SNIPE_SHOT
.4byte BattleScript_EffectTripleHit @ EFFECT_TRIPLE_HIT
.4byte BattleScript_EffectRecoilHP25 @ EFFECT_RECOIL_HP_25
.4byte BattleScript_EffectStuffCheeks @ EFFECT_STUFF_CHEEKS
BattleScript_EffectStuffCheeks::
attackcanceler
attackstring
ppreduce
jumpifnotberry BS_ATTACKER, BattleScript_ButItFailed
attackanimation
waitanimation
BattleScript_StuffCheeksEatBerry:
setbyte sBERRY_OVERRIDE, TRUE
orword gHitMarker, HITMARKER_NO_ANIMATIONS
consumeberry BS_ATTACKER
bicword gHitMarker, HITMARKER_NO_ANIMATIONS
setbyte sBERRY_OVERRIDE, FALSE
setstatchanger STAT_DEF, 2, FALSE
statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_BUFF_ALLOW_PTR, BattleScript_StuffCheeksEnd
setgraphicalstatchangevalues
jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_INCREASE, BattleScript_StuffCheeksEnd @ cant raise def
playanimation BS_ATTACKER, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1
printfromtable gStatUpStringIds
waitmessage B_WAIT_TIME_LONG
BattleScript_StuffCheeksEnd:
goto BattleScript_MoveEnd
BattleScript_EffectDecorate:
attackcanceler
@ -636,6 +660,11 @@ BattleScript_MoveEffectIncinerate::
BattleScript_MoveEffectBugBite::
printstring STRINGID_BUGBITE
waitmessage B_WAIT_TIME_LONG
orword gHitMarker, HITMARKER_NO_ANIMATIONS
setbyte sBERRY_OVERRIDE, TRUE @ override the requirements for eating berries
consumeberry BS_ATTACKER, TRUE @ consume the berry, then restore the item from changedItems
bicword gHitMarker, HITMARKER_NO_ANIMATIONS
setbyte sBERRY_OVERRIDE, FALSE
return
BattleScript_EffectCoreEnforcer:
@ -6398,6 +6427,10 @@ BattleScript_SelectingNotAllowedMoveGravity::
printselectionstring STRINGID_GRAVITYPREVENTSUSAGE
endselectionscript
BattleScript_SelectingNotAllowedStuffCheeks::
printselectionstring STRINGID_STUFFCHEEKSCANTSELECT
endselectionscript
BattleScript_SelectingNotAllowedBelch::
printselectionstring STRINGID_BELCHCANTSELECT
endselectionscript

View File

@ -679,6 +679,7 @@ struct BattleScripting
bool8 fixedPopup; // Force ability popup to stick until manually called back
u16 abilityPopupOverwrite;
u8 switchCase; // Special switching conditions, eg. red card
u8 overrideBerryRequirements;
};
// rom_80A5C6C

View File

@ -298,6 +298,7 @@ extern const u8 BattleScript_ProteanActivates[];
extern const u8 BattleScript_DazzlingProtected[];
extern const u8 BattleScript_MoveUsedPsychicTerrainPrevents[];
extern const u8 BattleScript_MoveUsedPowder[];
extern const u8 BattleScript_SelectingNotAllowedStuffCheeks[];
extern const u8 BattleScript_SelectingNotAllowedBelch[];
extern const u8 BattleScript_SelectingNotAllowedBelchInPalace[];
extern const u8 BattleScript_PsychicSurgeActivates[];

View File

@ -32,6 +32,7 @@
#define ITEMEFFECT_TARGET 0x5
#define ITEMEFFECT_ORBS 0x6
#define ITEMEFFECT_LIFEORB_SHELLBELL 0x7
#define ITEMEFFECT_BATTLER_MOVE_END 0x8 // move end effects for just the battler, not whole field
#define WEATHER_HAS_EFFECT ((!IsAbilityOnField(ABILITY_CLOUD_NINE) && !IsAbilityOnField(ABILITY_AIR_LOCK)))

View File

@ -364,7 +364,8 @@
#define EFFECT_SNIPE_SHOT 358
#define EFFECT_TRIPLE_HIT 359
#define EFFECT_RECOIL_HP_25 360
#define EFFECT_STUFF_CHEEKS 361
#define NUM_BATTLE_MOVE_EFFECTS 361
#define NUM_BATTLE_MOVE_EFFECTS 362
#endif // GUARD_CONSTANTS_BATTLE_MOVE_EFFECTS_H

View File

@ -38,6 +38,7 @@
#define sFIXED_ABILITY_POPUP gBattleScripting + 0x33
#define sABILITY_OVERWRITE gBattleScripting + 0x34
#define sSWITCH_CASE gBattleScripting + 0x36
#define sBERRY_OVERRIDE gBattleScripting + 0x37
#define cMULTISTRING_CHOOSER gBattleCommunication + 5
#define cMISS_TYPE gBattleCommunication + 6
@ -188,6 +189,7 @@
#define VARIOUS_GET_ROTOTILLER_TARGETS 116
#define VARIOUS_JUMP_IF_NOT_ROTOTILLER_AFFECTED 117
#define VARIOUS_TRY_ACTIVATE_BATTLE_BOND 118
#define VARIOUS_CONSUME_BERRY 119
// Cmd_manipulatedamage
#define DMG_CHANGE_SIGN 0

View File

@ -592,8 +592,9 @@
#define STRINGID_STRONGWINDSDISSIPATED 588
#define STRINGID_MYSTERIOUSAIRCURRENTBLOWSON 589
#define STRINGID_ATTACKWEAKENEDBSTRONGWINDS 590
#define STRINGID_STUFFCHEEKSCANTSELECT 591
#define BATTLESTRINGS_COUNT 591
#define BATTLESTRINGS_COUNT 592
// The below IDs are all indexes into battle message tables,
// used to determine which of a set of messages to print.

View File

@ -824,21 +824,17 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
if (!BattlerStatCanRise(battlerAtk, AI_DATA->atkAbility, STAT_ATK) || !HasMoveWithSplit(battlerAtk, SPLIT_PHYSICAL))
score -= 10;
break;
case EFFECT_DEFENSE_UP_2:
if (move == MOVE_STUFF_CHEEKS && ItemId_GetPocket(gBattleMons[battlerAtk].item) != POCKET_BERRIES)
score -= 10;
case EFFECT_STUFF_CHEEKS:
if (ItemId_GetPocket(gBattleMons[battlerAtk].item) != POCKET_BERRIES)
return 0; // cannot even select
//fallthrough
case EFFECT_DEFENSE_UP:
case EFFECT_DEFENSE_UP_2:
case EFFECT_DEFENSE_UP_3:
case EFFECT_DEFENSE_CURL:
if (!BattlerStatCanRise(battlerAtk, AI_DATA->atkAbility, STAT_DEF))
score -= 10;
break;
case EFFECT_SPEED_UP:
case EFFECT_SPEED_UP_2:
if (!BattlerStatCanRise(battlerAtk, AI_DATA->atkAbility, STAT_SPEED))
score -= 10;
break;
case EFFECT_SPECIAL_ATTACK_UP:
case EFFECT_SPECIAL_ATTACK_UP_2:
case EFFECT_SPECIAL_ATTACK_UP_3:

View File

@ -718,9 +718,11 @@ static const u8 sText_MysteriousAirCurrent[] = _("A mysterious air current is\np
static const u8 sText_StrongWindsDissipated[] = _("The mysterious strong winds\nhave dissipated!{PAUSE 64}");
static const u8 sText_MysteriousAirCurrentBlowsOn[] = _("The mysterious air current\nblows on regardless!");
static const u8 sText_AttackWeakenedByStrongWinds[] = _("The mysterious strong winds\nweakened the attack!");
static const u8 sText_StuffCheeksCantSelect[] = _("Stuff Cheeks cannot be\nselected without a Berry!\p");
const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
{
[STRINGID_STUFFCHEEKSCANTSELECT - 12] = sText_StuffCheeksCantSelect,
[STRINGID_ATTACKWEAKENEDBSTRONGWINDS - 12] = sText_AttackWeakenedByStrongWinds,
[STRINGID_MYSTERIOUSAIRCURRENTBLOWSON - 12] = sText_MysteriousAirCurrentBlowsOn,
[STRINGID_STRONGWINDSDISSIPATED - 12] = sText_StrongWindsDissipated,

View File

@ -3373,16 +3373,22 @@ void SetMoveEffect(bool32 primary, u32 certain)
}
break;
case MOVE_EFFECT_BUG_BITE:
if ((gBattleMons[gEffectBattler].item >= FIRST_BERRY_INDEX && gBattleMons[gEffectBattler].item <= LAST_BERRY_INDEX)
if (ItemId_GetPocket(gBattleMons[gEffectBattler].item) == POCKET_BERRIES
&& GetBattlerAbility(gEffectBattler) != ABILITY_STICKY_HOLD)
{
// target loses their berry
gLastUsedItem = gBattleMons[gEffectBattler].item;
gBattleMons[gEffectBattler].item = 0;
CheckSetUnburden(gEffectBattler);
gActiveBattler = gEffectBattler;
BtlController_EmitSetMonData(0, REQUEST_HELDITEM_BATTLE, 0, 2, &gBattleMons[gEffectBattler].item);
MarkBattlerForControllerExec(gActiveBattler);
// attacker temporarily gains their item
gBattleStruct->changedItems[gBattlerAttacker] = gBattleMons[gBattlerAttacker].item;
gBattleMons[gBattlerAttacker].item = gLastUsedItem;
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_MoveEffectBugBite;
}
@ -8882,6 +8888,27 @@ static void Cmd_various(void)
return;
}
break;
case VARIOUS_CONSUME_BERRY:
if (ItemId_GetHoldEffect(gBattleMons[gActiveBattler].item) == HOLD_EFFECT_NONE)
{
gBattlescriptCurrInstr += 4;
return;
}
gBattleScripting.battler = gEffectBattler = gBattlerTarget = gActiveBattler; // Cover all berry effect battlerId cases. e.g. ChangeStatBuffs uses target ID
// Do move end berry effects for just a single battler, instead of looping through all battlers
if (ItemBattleEffects(ITEMEFFECT_BATTLER_MOVE_END, gActiveBattler, FALSE))
return;
if (gBattlescriptCurrInstr[3])
{
gBattleMons[gActiveBattler].item = gBattleStruct->changedItems[gActiveBattler];
gBattleStruct->changedItems[gActiveBattler] = ITEM_NONE;
gBattleResources->flags->flags[gActiveBattler] &= ~(RESOURCE_FLAG_UNBURDEN);
}
gBattlescriptCurrInstr += 4;
return;
}
gBattlescriptCurrInstr += 3;

View File

@ -1725,6 +1725,21 @@ u8 TrySetCantSelectMoveBattleScript(void)
limitations++;
}
}
if (move == MOVE_STUFF_CHEEKS && ItemId_GetPocket(gBattleMons[gActiveBattler].item) != POCKET_BERRIES)
{
gCurrentMove = move;
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
{
gPalaceSelectionBattleScripts[gActiveBattler] = BattleScript_SelectingNotAllowedBelchInPalace;
gProtectStructs[gActiveBattler].palaceUnableToUseMove = 1;
}
else
{
gSelectionBattleScripts[gActiveBattler] = BattleScript_SelectingNotAllowedStuffCheeks;
limitations++;
}
}
gPotentialItemEffectBattler = gActiveBattler;
if (HOLD_EFFECT_CHOICE(holdEffect) && *choicedMove != 0 && *choicedMove != 0xFFFF && *choicedMove != move)
@ -1808,6 +1823,8 @@ u8 CheckMoveLimitations(u8 battlerId, u8 unusableMoves, u8 check)
unusableMoves |= gBitTable[i];
else if (gDisableStructs[battlerId].throatChopTimer && gBattleMoves[gBattleMons[battlerId].moves[i]].flags & FLAG_SOUND)
unusableMoves |= gBitTable[i];
else if (gBattleMons[battlerId].moves[i] == MOVE_STUFF_CHEEKS && ItemId_GetPocket(gBattleMons[gActiveBattler].item) != POCKET_BERRIES)
unusableMoves |= gBitTable[i];
}
return unusableMoves;
}
@ -5628,6 +5645,8 @@ bool32 HasEnoughHpToEatBerry(u32 battlerId, u32 hpFraction, u32 itemId)
if (gBattleMons[battlerId].hp == 0)
return FALSE;
if (gBattleScripting.overrideBerryRequirements)
return TRUE;
// Unnerve prevents consumption of opponents' berries.
if (isBerry && IsUnnerveAbilityOnOpposingSide(battlerId))
return FALSE;
@ -5831,7 +5850,8 @@ u8 TryHandleSeed(u8 battler, u32 terrainFlag, u8 statId, u16 itemId, bool32 exec
static u8 ItemHealHp(u32 battlerId, u32 itemId, bool32 end2, bool32 percentHeal)
{
if (HasEnoughHpToEatBerry(battlerId, 2, itemId))
if (HasEnoughHpToEatBerry(battlerId, 2, itemId)
&& !(gBattleScripting.overrideBerryRequirements && gBattleMons[battlerId].hp == gBattleMons[battlerId].maxHP))
{
if (percentHeal)
gBattleMoveDamage = (gBattleMons[battlerId].maxHP * GetBattlerHoldEffectParam(battlerId) / 100) * -1;
@ -6458,11 +6478,14 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn)
}
}
break;
case ITEMEFFECT_BATTLER_MOVE_END:
goto DO_ITEMEFFECT_MOVE_END; // this hurts a bit to do, but is an easy solution
case ITEMEFFECT_MOVE_END:
for (battlerId = 0; battlerId < gBattlersCount; battlerId++)
{
gLastUsedItem = gBattleMons[battlerId].item;
battlerHoldEffect = GetBattlerHoldEffect(battlerId, TRUE);
DO_ITEMEFFECT_MOVE_END:
switch (battlerHoldEffect)
{
case HOLD_EFFECT_MICLE_BERRY:

View File

@ -10780,7 +10780,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
[MOVE_STUFF_CHEEKS] =
{
.effect = EFFECT_DEFENSE_UP_2,
.effect = EFFECT_STUFF_CHEEKS,
.power = 0,
.type = TYPE_NORMAL,
.accuracy = 0,