Merge pull request #2117 from AgustinGDLV/symbiosis

ABILITY_SYMBIOSIS
This commit is contained in:
Eduardo Quezada D'Ottone 2022-09-24 14:30:39 -03:00 committed by GitHub
commit 0f743c4f00
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 109 additions and 21 deletions

View File

@ -2132,3 +2132,8 @@
.macro skydropyawn .macro skydropyawn
various 0, VARIOUS_SKY_DROP_YAWN various 0, VARIOUS_SKY_DROP_YAWN
.endm .endm
@ Used by effects that may proc Symbiosis but do not call removeitem.
.macro trysymbiosis
various BS_ATTACKER, VARIOUS_TRY_SYMBIOSIS
.endm

View File

@ -706,6 +706,7 @@ BattleScript_EffectFlingConsumeBerry:
restorebattleritem BS_TARGET restorebattleritem BS_TARGET
BattleScript_FlingEnd: BattleScript_FlingEnd:
tryfaintmon BS_TARGET tryfaintmon BS_TARGET
trysymbiosis
goto BattleScript_MoveEnd goto BattleScript_MoveEnd
BattleScript_FlingFlameOrb: BattleScript_FlingFlameOrb:
@ -1392,6 +1393,7 @@ BattleScript_MoveEffectBugBite::
consumeberry BS_ATTACKER, TRUE @ consume the berry, then restore the item from changedItems consumeberry BS_ATTACKER, TRUE @ consume the berry, then restore the item from changedItems
bicword gHitMarker, HITMARKER_NO_ANIMATIONS bicword gHitMarker, HITMARKER_NO_ANIMATIONS
setbyte sBERRY_OVERRIDE, FALSE setbyte sBERRY_OVERRIDE, FALSE
trysymbiosis
return return
BattleScript_EffectCoreEnforcer: BattleScript_EffectCoreEnforcer:
@ -1763,6 +1765,7 @@ BattleScript_EffectBestow:
waitanimation waitanimation
printstring STRINGID_BESTOWITEMGIVING printstring STRINGID_BESTOWITEMGIVING
waitmessage B_WAIT_TIME_LONG waitmessage B_WAIT_TIME_LONG
trysymbiosis
goto BattleScript_MoveEnd goto BattleScript_MoveEnd
BattleScript_EffectAfterYou: BattleScript_EffectAfterYou:
@ -9841,3 +9844,9 @@ BattleScript_MagicianActivates::
call BattleScript_AbilityPopUp call BattleScript_AbilityPopUp
call BattleScript_ItemSteal call BattleScript_ItemSteal
return return
BattleScript_SymbiosisActivates::
call BattleScript_AbilityPopUp
printstring STRINGID_SYMBIOSISITEMPASS
waitmessage B_WAIT_TIME_LONG
return

View File

@ -428,6 +428,7 @@ extern const u8 BattleScript_BeakBlastBurn[];
extern const u8 BattleScript_DefDownSpeedUp[]; extern const u8 BattleScript_DefDownSpeedUp[];
extern const u8 BattleScript_AffectionBasedStatusHeal[]; extern const u8 BattleScript_AffectionBasedStatusHeal[];
extern const u8 BattleScript_AffectionBasedEndurance[]; extern const u8 BattleScript_AffectionBasedEndurance[];
extern const u8 BattleScript_SymbiosisActivates[];
// zmoves // zmoves
extern const u8 BattleScript_ZMoveActivateDamaging[]; extern const u8 BattleScript_ZMoveActivateDamaging[];

View File

@ -103,6 +103,7 @@
#define B_STURDY GEN_LATEST // In Gen5+, Sturdy causes the Pokémon to have 1 HP remaining if another Pokémon's attack or confusion damage would have brought it from full health to 0 HP. #define B_STURDY GEN_LATEST // In Gen5+, Sturdy causes the Pokémon to have 1 HP remaining if another Pokémon's attack or confusion damage would have brought it from full health to 0 HP.
#define B_PLUS_MINUS_INTERACTION GEN_LATEST // In Gen5+, Plus and Minus can be activated with themselves and the opposite ability. Before, only the opposing ability could activate it. #define B_PLUS_MINUS_INTERACTION GEN_LATEST // In Gen5+, Plus and Minus can be activated with themselves and the opposite ability. Before, only the opposing ability could activate it.
#define B_WEATHER_FORMS GEN_LATEST // In Gen5+, Castform and Cherrim revert to their base form upon losing their respective ability. Cherrim needs Flower Gift to swap forms. #define B_WEATHER_FORMS GEN_LATEST // In Gen5+, Castform and Cherrim revert to their base form upon losing their respective ability. Cherrim needs Flower Gift to swap forms.
#define B_SYMBIOSIS_GEMS GEN_LATEST // In Gen7+, Symbiosis passes an item after a gem-boosted attack. Previously, items are passed before the gem-boosted attack hits, making the item effect apply.
// Item settings // Item settings
#define B_HP_BERRIES GEN_LATEST // In Gen4+, berries which restore hp activate immediately after HP drops to half. In Gen3, the effect occurs at the end of the turn. #define B_HP_BERRIES GEN_LATEST // In Gen4+, berries which restore hp activate immediately after HP drops to half. In Gen3, the effect occurs at the end of the turn.

View File

@ -242,6 +242,7 @@
#define VARIOUS_SET_BEAK_BLAST 151 #define VARIOUS_SET_BEAK_BLAST 151
#define VARIOUS_SWAP_SIDE_STATUSES 152 #define VARIOUS_SWAP_SIDE_STATUSES 152
#define VARIOUS_SET_Z_EFFECT 153 #define VARIOUS_SET_Z_EFFECT 153
#define VARIOUS_TRY_SYMBIOSIS 154
// Cmd_manipulatedamage // Cmd_manipulatedamage
#define DMG_CHANGE_SIGN 0 #define DMG_CHANGE_SIGN 0
@ -312,8 +313,9 @@
#define MOVEEND_DANCER 28 #define MOVEEND_DANCER 28
#define MOVEEND_EMERGENCY_EXIT 29 #define MOVEEND_EMERGENCY_EXIT 29
#define MOVEEND_WEATHER_FORM 30 #define MOVEEND_WEATHER_FORM 30
#define MOVEEND_CLEAR_BITS 31 #define MOVEEND_SYMBIOSIS 31
#define MOVEEND_COUNT 32 #define MOVEEND_CLEAR_BITS 32
#define MOVEEND_COUNT 33
// switch cases // switch cases
#define B_SWITCH_NORMAL 0 #define B_SWITCH_NORMAL 0

View File

@ -607,7 +607,7 @@ static const u8 sText_HarvestBerry[] = _("{B_ATK_NAME_WITH_PREFIX} harvested\nit
static const u8 sText_LastAbilityRaisedBuff1[] = _("{B_ATK_NAME_WITH_PREFIX}'s {B_LAST_ABILITY}\nraised its {B_BUFF1}!"); static const u8 sText_LastAbilityRaisedBuff1[] = _("{B_ATK_NAME_WITH_PREFIX}'s {B_LAST_ABILITY}\nraised its {B_BUFF1}!");
static const u8 sText_MagicBounceActivates[] = _("The {B_DEF_NAME_WITH_PREFIX} bounced the\n{B_ATK_NAME_WITH_PREFIX} back!"); static const u8 sText_MagicBounceActivates[] = _("The {B_DEF_NAME_WITH_PREFIX} bounced the\n{B_ATK_NAME_WITH_PREFIX} back!");
static const u8 sText_ProteanTypeChange[] = _("{B_ATK_NAME_WITH_PREFIX}'s {B_ATK_ABILITY} transformed\nit into the {B_BUFF1} type!"); static const u8 sText_ProteanTypeChange[] = _("{B_ATK_NAME_WITH_PREFIX}'s {B_ATK_ABILITY} transformed\nit into the {B_BUFF1} type!");
static const u8 sText_SymbiosisItemPass[] = _("{B_ATK_NAME_WITH_PREFIX} passed its {B_LAST_ITEM}\nto {B_SCR_ACTIVE_NAME_WITH_PREFIX} through {B_ATK_ABILITY}!"); static const u8 sText_SymbiosisItemPass[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} passed its {B_LAST_ITEM}\nto {B_ATK_NAME_WITH_PREFIX} through {B_LAST_ABILITY}!");
static const u8 sText_StealthRockDmg[] = _("Pointed stones dug into\n{B_SCR_ACTIVE_NAME_WITH_PREFIX}!"); static const u8 sText_StealthRockDmg[] = _("Pointed stones dug into\n{B_SCR_ACTIVE_NAME_WITH_PREFIX}!");
static const u8 sText_ToxicSpikesAbsorbed[] = _("The poison spikes disappeared\nfrom around the opposing team's feet!"); static const u8 sText_ToxicSpikesAbsorbed[] = _("The poison spikes disappeared\nfrom around the opposing team's feet!");
static const u8 sText_ToxicSpikesPoisoned[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} was poisoned!"); static const u8 sText_ToxicSpikesPoisoned[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} was poisoned!");

View File

@ -317,6 +317,7 @@ static void PutMonIconOnLvlUpBanner(void);
static void DrawLevelUpBannerText(void); static void DrawLevelUpBannerText(void);
static void SpriteCB_MonIconOnLvlUpBanner(struct Sprite *sprite); static void SpriteCB_MonIconOnLvlUpBanner(struct Sprite *sprite);
static bool32 CriticalCapture(u32 odds); static bool32 CriticalCapture(u32 odds);
static void BestowItem(u32 battlerAtk, u32 battlerDef);
static void Cmd_attackcanceler(void); static void Cmd_attackcanceler(void);
static void Cmd_accuracycheck(void); static void Cmd_accuracycheck(void);
@ -5084,6 +5085,15 @@ static bool32 TryKnockOffBattleScript(u32 battlerDef)
return FALSE; return FALSE;
} }
#define SYMBIOSIS_CHECK(battler, ally) \
GetBattlerAbility(ally) == ABILITY_SYMBIOSIS \
&& gBattleMons[battler].item == ITEM_NONE \
&& gBattleMons[ally].item != ITEM_NONE \
&& CanBattlerGetOrLoseItem(battler, gBattleMons[ally].item) \
&& CanBattlerGetOrLoseItem(ally, gBattleMons[ally].item) \
&& gBattleMons[battler].hp != 0 \
&& gBattleMons[ally].hp != 0
static u32 GetNextTarget(u32 moveTarget) static u32 GetNextTarget(u32 moveTarget)
{ {
u32 i; u32 i;
@ -5748,13 +5758,11 @@ static void Cmd_moveend(void)
switch (gBattleMons[i].species) switch (gBattleMons[i].species)
{ {
case SPECIES_CASTFORM: case SPECIES_CASTFORM:
case SPECIES_CHERRIM:
#ifdef POKEMON_EXPANSION
case SPECIES_CASTFORM_RAINY: case SPECIES_CASTFORM_RAINY:
case SPECIES_CASTFORM_SNOWY: case SPECIES_CASTFORM_SNOWY:
case SPECIES_CASTFORM_SUNNY: case SPECIES_CASTFORM_SUNNY:
case SPECIES_CHERRIM:
case SPECIES_CHERRIM_SUNSHINE: case SPECIES_CHERRIM_SUNSHINE:
#endif
effect = TryWeatherFormChange(i); effect = TryWeatherFormChange(i);
if (effect) if (effect)
{ {
@ -5766,6 +5774,26 @@ static void Cmd_moveend(void)
} }
gBattleScripting.moveendState++; gBattleScripting.moveendState++;
break; break;
case MOVEEND_SYMBIOSIS:
for (i = 0; i < gBattlersCount; i++)
{
if ((gSpecialStatuses[i].berryReduced
#if B_SYMBIOSIS_GEMS >= GEN_7
|| gSpecialStatuses[i].gemBoost
#endif
) && SYMBIOSIS_CHECK(i, BATTLE_PARTNER(i)))
{
BestowItem(BATTLE_PARTNER(i), i);
gLastUsedAbility = gBattleMons[BATTLE_PARTNER(i)].ability;
gBattleScripting.battler = gBattlerAbility = BATTLE_PARTNER(i);
gBattlerAttacker = i;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_SymbiosisActivates;
effect = TRUE;
}
}
gBattleScripting.moveendState++;
break;
case MOVEEND_CLEAR_BITS: // Clear/Set bits for things like using a move for all targets and all hits. case MOVEEND_CLEAR_BITS: // Clear/Set bits for things like using a move for all targets and all hits.
if (gSpecialStatuses[gBattlerAttacker].instructedChosenTarget) if (gSpecialStatuses[gBattlerAttacker].instructedChosenTarget)
*(gBattleStruct->moveTarget + gBattlerAttacker) = gSpecialStatuses[gBattlerAttacker].instructedChosenTarget & 0x3; *(gBattleStruct->moveTarget + gBattlerAttacker) = gSpecialStatuses[gBattlerAttacker].instructedChosenTarget & 0x3;
@ -7244,6 +7272,49 @@ static bool32 TryCheekPouch(u32 battlerId, u32 itemId)
return FALSE; return FALSE;
} }
// Used by Bestow and Symbiosis to take an item from one battler and give to another.
static void BestowItem(u32 battlerAtk, u32 battlerDef)
{
gLastUsedItem = gBattleMons[battlerAtk].item;
gActiveBattler = battlerAtk;
gBattleMons[battlerAtk].item = ITEM_NONE;
BtlController_EmitSetMonData(BUFFER_A, REQUEST_HELDITEM_BATTLE, 0, sizeof(gBattleMons[battlerAtk].item), &gBattleMons[battlerAtk].item);
MarkBattlerForControllerExec(battlerAtk);
CheckSetUnburden(battlerAtk);
gActiveBattler = battlerDef;
gBattleMons[battlerDef].item = gLastUsedItem;
BtlController_EmitSetMonData(BUFFER_A, REQUEST_HELDITEM_BATTLE, 0, sizeof(gBattleMons[battlerDef].item), &gBattleMons[battlerDef].item);
MarkBattlerForControllerExec(battlerDef);
gBattleResources->flags->flags[battlerDef] &= ~RESOURCE_FLAG_UNBURDEN;
}
// Called by Cmd_removeitem. itemId represents the item that was removed, not being given.
static bool32 TrySymbiosis(u32 battler, u32 itemId)
{
if (!gBattleStruct->itemStolen[gBattlerPartyIndexes[battler]].stolen
&& gBattleStruct->changedItems[battler] == ITEM_NONE
&& GetBattlerHoldEffect(battler, TRUE) != HOLD_EFFECT_EJECT_BUTTON
&& GetBattlerHoldEffect(battler, TRUE) != HOLD_EFFECT_EJECT_PACK
#if B_SYMBIOSIS_GEMS >= GEN_7
&& !(gSpecialStatuses[battler].gemBoost)
#endif
&& gCurrentMove != MOVE_FLING //Fling and damage-reducing berries are handled separately.
&& !gSpecialStatuses[battler].berryReduced
&& SYMBIOSIS_CHECK(battler, BATTLE_PARTNER(battler)))
{
BestowItem(BATTLE_PARTNER(battler), battler);
gLastUsedAbility = gBattleMons[BATTLE_PARTNER(battler)].ability;
gBattleScripting.battler = gBattlerAbility = BATTLE_PARTNER(battler);
gBattlerAttacker = battler;
BattleScriptPush(gBattlescriptCurrInstr + 2);
gBattlescriptCurrInstr = BattleScript_SymbiosisActivates;
return TRUE;
}
return FALSE;
}
static void Cmd_removeitem(void) static void Cmd_removeitem(void)
{ {
u16 itemId = 0; u16 itemId = 0;
@ -7262,7 +7333,7 @@ static void Cmd_removeitem(void)
MarkBattlerForControllerExec(gActiveBattler); MarkBattlerForControllerExec(gActiveBattler);
ClearBattlerItemEffectHistory(gActiveBattler); ClearBattlerItemEffectHistory(gActiveBattler);
if (!TryCheekPouch(gActiveBattler, itemId)) if (!TryCheekPouch(gActiveBattler, itemId) && !TrySymbiosis(gActiveBattler, itemId))
gBattlescriptCurrInstr += 2; gBattlescriptCurrInstr += 2;
} }
@ -9045,20 +9116,7 @@ static void Cmd_various(void)
} }
else else
{ {
gLastUsedItem = gBattleMons[gBattlerAttacker].item; BestowItem(gBattlerAttacker, gBattlerTarget);
gActiveBattler = gBattlerAttacker;
gBattleMons[gActiveBattler].item = ITEM_NONE;
BtlController_EmitSetMonData(BUFFER_A, REQUEST_HELDITEM_BATTLE, 0, sizeof(gBattleMons[gActiveBattler].item), &gBattleMons[gActiveBattler].item);
MarkBattlerForControllerExec(gActiveBattler);
CheckSetUnburden(gBattlerAttacker);
gActiveBattler = gBattlerTarget;
gBattleMons[gActiveBattler].item = gLastUsedItem;
BtlController_EmitSetMonData(BUFFER_A, REQUEST_HELDITEM_BATTLE, 0, sizeof(gBattleMons[gActiveBattler].item), &gBattleMons[gActiveBattler].item);
MarkBattlerForControllerExec(gActiveBattler);
gBattleResources->flags->flags[gBattlerTarget] &= ~RESOURCE_FLAG_UNBURDEN;
gBattlescriptCurrInstr += 7; gBattlescriptCurrInstr += 7;
} }
return; return;
@ -9788,6 +9846,18 @@ static void Cmd_various(void)
case VARIOUS_SWAP_SIDE_STATUSES: case VARIOUS_SWAP_SIDE_STATUSES:
CourtChangeSwapSideStatuses(); CourtChangeSwapSideStatuses();
break; break;
case VARIOUS_TRY_SYMBIOSIS: //called by Bestow, Fling, and Bug Bite, which don't work with Cmd_removeitem.
if (SYMBIOSIS_CHECK(gActiveBattler, BATTLE_PARTNER(gActiveBattler)))
{
BestowItem(BATTLE_PARTNER(gActiveBattler), gActiveBattler);
gLastUsedAbility = gBattleMons[BATTLE_PARTNER(gActiveBattler)].ability;
gBattleScripting.battler = gBattlerAbility = BATTLE_PARTNER(gActiveBattler);
gBattlerAttacker = gActiveBattler;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_SymbiosisActivates;
return;
}
break;
} // End of switch (gBattlescriptCurrInstr[2]) } // End of switch (gBattlescriptCurrInstr[2])
gBattlescriptCurrInstr += 3; gBattlescriptCurrInstr += 3;