Merge branch 'battle_engine' of https://github.com/rh-hideout/pokeemerald-expansion into mimicry

This commit is contained in:
LOuroboros 2021-11-03 20:42:26 -03:00
commit f6628e301f
9 changed files with 93 additions and 18 deletions

View File

@ -1838,6 +1838,10 @@
.macro trytoclearprimalweather
various BS_ATTACKER, VARIOUS_TRY_TO_CLEAR_PRIMAL_WEATHER
.endm
.macro setattackertostickywebuser
various BS_TARGET, VARIOUS_SET_ATTACKER_STICKY_WEB_USER
.endm
.macro getrototillertargets ptr:req
various BS_ATTACKER, VARIOUS_GET_ROTOTILLER_TARGETS

View File

@ -2906,6 +2906,34 @@ BattleScript_StatDownPrintString::
BattleScript_StatDownEnd::
goto BattleScript_MoveEnd
BattleScript_MirrorArmorReflect::
pause B_WAIT_TIME_SHORT
call BattleScript_AbilityPopUp
jumpifsubstituteblocks BattleScript_AbilityNoSpecificStatLoss
BattleScript_MirrorArmorReflectStatLoss:
statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_BUFF_NOT_PROTECT_AFFECTED | STAT_BUFF_ALLOW_PTR, BattleScript_MirrorArmorReflectEnd
jumpifbyte CMP_LESS_THAN, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_DECREASE, BattleScript_MirrorArmorReflectAnim
goto BattleScript_MirrorArmorReflectWontFall
BattleScript_MirrorArmorReflectAnim:
setgraphicalstatchangevalues
playanimation BS_ATTACKER, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1
BattleScript_MirrorArmorReflectPrintString:
printfromtable gStatDownStringIds
waitmessage B_WAIT_TIME_LONG
BattleScript_MirrorArmorReflectEnd:
return
BattleScript_MirrorArmorReflectWontFall:
copybyte gBattlerTarget, gBattlerAttacker @ STRINGID_STATSWONTDECREASE uses target
goto BattleScript_MirrorArmorReflectPrintString
@ gBattlerTarget is battler with Mirror Armor
BattleScript_MirrorArmorReflectStickyWeb:
call BattleScript_AbilityPopUp
setattackertostickywebuser
jumpifbyteequal gBattlerAttacker, gBattlerTarget, BattleScript_StickyWebOnSwitchInEnd @ Sticky web user not on field -> no stat loss
goto BattleScript_MirrorArmorReflectStatLoss
BattleScript_StatDown::
playanimation BS_EFFECT_BATTLER, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1
printfromtable gStatDownStringIds
@ -6381,6 +6409,7 @@ BattleScript_StickyWebOnSwitchIn::
copybyte gBattlerTarget, sBATTLER
printstring STRINGID_STICKYWEBSWITCHIN
waitmessage B_WAIT_TIME_LONG
jumpifability BS_TARGET, ABILITY_MIRROR_ARMOR, BattleScript_MirrorArmorReflectStickyWeb
statbuffchange STAT_BUFF_ALLOW_PTR, BattleScript_StickyWebOnSwitchInEnd
jumpifbyte CMP_LESS_THAN, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_DECREASE, BattleScript_StickyWebOnSwitchInStatAnim
jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_FELL_EMPTY, BattleScript_StickyWebOnSwitchInEnd
@ -7955,6 +7984,7 @@ BattleScript_GrassyTerrainHealEnd:
BattleScript_AbilityNoSpecificStatLoss::
pause B_WAIT_TIME_SHORT
call BattleScript_AbilityPopUp
BattleScript_AbilityNoSpecificStatLossPrint:
printstring STRINGID_PKMNSXPREVENTSYLOSS
waitmessage B_WAIT_TIME_LONG
setbyte cMULTISTRING_CHOOSER, B_MSG_STAT_FELL_EMPTY
@ -8235,6 +8265,13 @@ BattleScript_CuteCharmActivates::
call BattleScript_TryDestinyKnotTarget
return
BattleScript_GooeyActivates::
waitstate
call BattleScript_AbilityPopUp
swapattackerwithtarget @ for defiant, mirror armor
seteffectsecondary
return
BattleScript_AbilityStatusEffect::
waitstate
call BattleScript_AbilityPopUp

View File

@ -612,6 +612,7 @@ struct BattleStruct
struct StolenItem itemStolen[PARTY_SIZE]; // Player's team that had items stolen (two bytes per party member)
u8 blunderPolicy:1; // should blunder policy activate
u8 ballSpriteIds[2]; // item gfx, window gfx
u8 stickyWebUser;
};
#define GET_MOVE_TYPE(move, typeArg) \

View File

@ -404,6 +404,8 @@ extern const u8 BattleScript_PrimalReversion[];
extern const u8 BattleScript_HyperspaceFuryRemoveProtect[];
extern const u8 BattleScript_SelectingNotAllowedMoveGorillaTactics[];
extern const u8 BattleScript_WanderingSpiritActivates[];
extern const u8 BattleScript_MirrorArmorReflect[];
extern const u8 BattleScript_GooeyActivates[];
extern const u8 BattleScript_MimicryActivatesEnd3[];
extern const u8 BattleScript_ApplyMimicry[];

View File

@ -197,7 +197,8 @@
#define VARIOUS_UPDATE_ABILITY_POPUP 124
#define VARIOUS_JUMP_IF_WEATHER_AFFECTED 125
#define VARIOUS_JUMP_IF_LEAF_GUARD_PROTECTED 126
#define VARIOUS_TRY_TO_APPLY_MIMICRY 127
#define VARIOUS_SET_ATTACKER_STICKY_WEB_USER 127
#define VARIOUS_TRY_TO_APPLY_MIMICRY 128
// Cmd_manipulatedamage
#define DMG_CHANGE_SIGN 0

View File

@ -559,7 +559,7 @@ static const struct BgTemplate sBgTemplates[] =
},
{
.bg = 1,
.charBaseIndex = 10,
.charBaseIndex = 2,
.mapBaseIndex = 20,
.screenSize = 0,
.paletteMode = 0,

View File

@ -2933,6 +2933,8 @@ static void BattleStartClearSetData(void)
gBattleStruct->mega.triggerSpriteId = 0xFF;
gBattleStruct->stickyWebUser = 0xFF;
for (i = 0; i < PARTY_SIZE; i++)
{
gBattleStruct->usedHeldItems[i][0] = 0;
@ -3030,6 +3032,9 @@ void SwitchInClearSetData(void)
gBattleStruct->lastTakenMoveFrom[gActiveBattler][3] = 0;
gBattleStruct->lastMoveFailed &= ~(gBitTable[gActiveBattler]);
gBattleStruct->palaceFlags &= ~(gBitTable[gActiveBattler]);
if (gActiveBattler == gBattleStruct->stickyWebUser)
gBattleStruct->stickyWebUser = 0xFF; // Switched into sticky web user slot so reset it
for (i = 0; i < gBattlersCount; i++)
{
@ -3127,6 +3132,9 @@ void FaintClearSetData(void)
gBattleStruct->lastTakenMoveFrom[gActiveBattler][3] = 0;
gBattleStruct->palaceFlags &= ~(gBitTable[gActiveBattler]);
if (gActiveBattler == gBattleStruct->stickyWebUser)
gBattleStruct->stickyWebUser = 0xFF; // User of sticky web fainted, so reset the stored battler ID
for (i = 0; i < gBattlersCount; i++)
{

View File

@ -2586,6 +2586,8 @@ void SetMoveEffect(bool32 primary, u32 certain)
{
s32 i, byTwo, affectsUser = 0;
bool32 statusChanged = FALSE;
bool32 mirrorArmorReflected = (GetBattlerAbility(gBattlerTarget) == ABILITY_MIRROR_ARMOR);
u32 flags = 0;
switch (gBattleScripting.moveEffect) // Set move effects which happen later on
{
@ -3016,11 +3018,16 @@ void SetMoveEffect(bool32 primary, u32 certain)
case MOVE_EFFECT_SP_DEF_MINUS_1:
case MOVE_EFFECT_ACC_MINUS_1:
case MOVE_EFFECT_EVS_MINUS_1:
flags = affectsUser;
if (mirrorArmorReflected && !affectsUser)
flags |= STAT_BUFF_ALLOW_PTR;
if (ChangeStatBuffs(SET_STAT_BUFF_VALUE(1) | STAT_BUFF_NEGATIVE,
gBattleScripting.moveEffect - MOVE_EFFECT_ATK_MINUS_1 + 1,
affectsUser, 0))
gBattleScripting.moveEffect - MOVE_EFFECT_ATK_MINUS_1 + 1,
flags, gBattlescriptCurrInstr + 1))
{
gBattlescriptCurrInstr++;
if (!mirrorArmorReflected)
gBattlescriptCurrInstr++;
}
else
{
@ -3058,11 +3065,15 @@ void SetMoveEffect(bool32 primary, u32 certain)
case MOVE_EFFECT_SP_DEF_MINUS_2:
case MOVE_EFFECT_ACC_MINUS_2:
case MOVE_EFFECT_EVS_MINUS_2:
flags = affectsUser;
if (mirrorArmorReflected && !affectsUser)
flags |= STAT_BUFF_ALLOW_PTR;
if (ChangeStatBuffs(SET_STAT_BUFF_VALUE(2) | STAT_BUFF_NEGATIVE,
gBattleScripting.moveEffect - MOVE_EFFECT_ATK_MINUS_2 + 1,
affectsUser, 0))
flags, gBattlescriptCurrInstr + 1))
{
gBattlescriptCurrInstr++;
if (!mirrorArmorReflected)
gBattlescriptCurrInstr++;
}
else
{
@ -9005,6 +9016,14 @@ static void Cmd_various(void)
gBattlescriptCurrInstr += 7;
}
return;
case VARIOUS_SET_ATTACKER_STICKY_WEB_USER:
// For Mirror Armor: "If the Pokémon with this Ability is affected by Sticky Web, the effect is reflected back to the Pokémon which set it up.
// If Pokémon which set up Sticky Web is not on the field, no Pokémon have their Speed lowered."
gBattlerAttacker = gBattlerTarget; // Initialize 'fail' condition
SET_STATCHANGER(STAT_SPEED, 1, TRUE);
if (gBattleStruct->stickyWebUser != 0xFF)
gBattlerAttacker = gBattleStruct->stickyWebUser;
break;
case VARIOUS_TRY_TO_APPLY_MIMICRY:
{
bool8 isMimicryDone = FALSE;
@ -9553,8 +9572,9 @@ static u32 ChangeStatBuffs(s8 statValue, u32 statId, u32 flags, const u8 *BS_ptr
bool32 certain = FALSE;
bool32 notProtectAffected = FALSE;
u32 index;
bool32 affectsUser = (flags & MOVE_EFFECT_AFFECTS_USER);
if (flags & MOVE_EFFECT_AFFECTS_USER)
if (affectsUser)
gActiveBattler = gBattlerAttacker;
else
gActiveBattler = gBattlerTarget;
@ -9655,8 +9675,9 @@ static u32 ChangeStatBuffs(s8 statValue, u32 statId, u32 flags, const u8 *BS_ptr
}
return STAT_CHANGE_DIDNT_WORK;
}
else if (GetBattlerAbility(gActiveBattler) == ABILITY_KEEN_EYE
&& !certain && statId == STAT_ACC)
else if (!certain
&& ((GetBattlerAbility(gActiveBattler) == ABILITY_KEEN_EYE && statId == STAT_ACC)
|| (GetBattlerAbility(gActiveBattler) == ABILITY_HYPER_CUTTER && statId == STAT_ATK)))
{
if (flags == STAT_BUFF_ALLOW_PTR)
{
@ -9669,17 +9690,16 @@ static u32 ChangeStatBuffs(s8 statValue, u32 statId, u32 flags, const u8 *BS_ptr
}
return STAT_CHANGE_DIDNT_WORK;
}
else if (GetBattlerAbility(gActiveBattler) == ABILITY_HYPER_CUTTER
&& !certain && statId == STAT_ATK)
else if (GetBattlerAbility(gActiveBattler) == ABILITY_MIRROR_ARMOR && !affectsUser && gBattlerAttacker != gBattlerTarget && gActiveBattler == gBattlerTarget)
{
if (flags == STAT_BUFF_ALLOW_PTR)
{
SET_STATCHANGER(statId, GET_STAT_BUFF_VALUE(statValue) | STAT_BUFF_NEGATIVE, TRUE);
BattleScriptPush(BS_ptr);
gBattleScripting.battler = gActiveBattler;
gBattlerAbility = gActiveBattler;
gBattlescriptCurrInstr = BattleScript_AbilityNoSpecificStatLoss;
gLastUsedAbility = GetBattlerAbility(gActiveBattler);
RecordAbilityBattle(gActiveBattler, gLastUsedAbility);
gBattlescriptCurrInstr = BattleScript_MirrorArmorReflect;
RecordAbilityBattle(gActiveBattler, gBattleMons[gActiveBattler].ability);
}
return STAT_CHANGE_DIDNT_WORK;
}
@ -11575,6 +11595,7 @@ static void Cmd_setstickyweb(void)
{
gSideStatuses[targetSide] |= SIDE_STATUS_STICKY_WEB;
gSideTimers[targetSide].stickyWebAmount = 1;
gBattleStruct->stickyWebUser = gBattlerAttacker; // For Mirror Armor
gBattlescriptCurrInstr += 5;
}
}

View File

@ -4986,15 +4986,16 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
case ABILITY_TANGLING_HAIR:
if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
&& gBattleMons[gBattlerAttacker].hp != 0
&& CompareStat(gBattlerAttacker, STAT_SPEED, MIN_STAT_STAGE, CMP_GREATER_THAN)
&& (CompareStat(gBattlerAttacker, STAT_SPEED, MIN_STAT_STAGE, CMP_GREATER_THAN) || GetBattlerAbility(gBattlerAttacker) == ABILITY_MIRROR_ARMOR)
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
&& TARGET_TURN_DAMAGED
&& IsMoveMakingContact(move, gBattlerAttacker))
{
gBattleScripting.moveEffect = MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_SPD_MINUS_1;
SET_STATCHANGER(STAT_SPEED, 1, TRUE);
gBattleScripting.moveEffect = MOVE_EFFECT_SPD_MINUS_1;
PREPARE_ABILITY_BUFFER(gBattleTextBuff1, gLastUsedAbility);
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_AbilityStatusEffect;
gBattlescriptCurrInstr = BattleScript_GooeyActivates;
gHitMarker |= HITMARKER_IGNORE_SAFEGUARD;
effect++;
}