Merge branch '_RHH/master' into _RHH/upcoming
# Conflicts: # src/battle_script_commands.c
@ -1632,7 +1632,11 @@
|
||||
.macro trygulpmissile
|
||||
callnative BS_TryGulpMissile
|
||||
.endm
|
||||
|
||||
|
||||
.macro tryactivategulpmissile
|
||||
callnative BS_TryActivateGulpMissile
|
||||
.endm
|
||||
|
||||
.macro tryquash failInstr:req
|
||||
callnative BS_TryQuash
|
||||
.4byte \failInstr
|
||||
|
||||
@ -84,6 +84,7 @@ BattleScript_EffectShedTail::
|
||||
jumpifcantswitch SWITCH_IGNORE_ESCAPE_PREVENTION | BS_ATTACKER, BattleScript_ButItFailed
|
||||
setsubstitute
|
||||
jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_SUBSTITUTE_FAILED, BattleScript_SubstituteString
|
||||
orword gHitMarker, HITMARKER_PASSIVE_DAMAGE
|
||||
attackanimation
|
||||
waitanimation
|
||||
healthbarupdate BS_ATTACKER
|
||||
@ -108,7 +109,7 @@ BattleScript_EffectFilletAway::
|
||||
jumpifstat BS_ATTACKER, CMP_EQUAL, STAT_SPEED, MAX_STAT_STAGE, BattleScript_ButItFailed
|
||||
BattleScript_FilletAwayTryAttack::
|
||||
halvehp BattleScript_ButItFailed
|
||||
orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE
|
||||
orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_DAMAGE
|
||||
attackanimation
|
||||
waitanimation
|
||||
setbyte sSTAT_ANIM_PLAYED, FALSE
|
||||
@ -1715,6 +1716,8 @@ BattleScript_EffectCopycat::
|
||||
trycopycat BattleScript_CopycatFail
|
||||
attackanimation
|
||||
waitanimation
|
||||
setbyte sB_ANIM_TURN, 0
|
||||
setbyte sB_ANIM_TARGETS_HIT, 0
|
||||
jumptocalledmove TRUE
|
||||
BattleScript_CopycatFail:
|
||||
ppreduce
|
||||
@ -3866,6 +3869,7 @@ BattleScript_EffectSubstitute::
|
||||
jumpifstatus2 BS_ATTACKER, STATUS2_SUBSTITUTE, BattleScript_AlreadyHasSubstitute
|
||||
setsubstitute
|
||||
jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_SUBSTITUTE_FAILED, BattleScript_SubstituteString
|
||||
orword gHitMarker, HITMARKER_PASSIVE_DAMAGE
|
||||
attackanimation
|
||||
waitanimation
|
||||
healthbarupdate BS_ATTACKER
|
||||
@ -4600,7 +4604,7 @@ BattleScript_EffectBellyDrum::
|
||||
ppreduce
|
||||
jumpifstat BS_ATTACKER, CMP_EQUAL, STAT_ATK, MAX_STAT_STAGE, BattleScript_ButItFailed
|
||||
halvehp BattleScript_ButItFailed
|
||||
orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE
|
||||
orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_DAMAGE
|
||||
attackanimation
|
||||
waitanimation
|
||||
healthbarupdate BS_ATTACKER
|
||||
@ -5490,6 +5494,7 @@ BattleScript_EffectCamouflage::
|
||||
|
||||
BattleScript_FaintAttacker::
|
||||
tryillusionoff BS_ATTACKER
|
||||
tryactivategulpmissile
|
||||
playfaintcry BS_ATTACKER
|
||||
pause B_WAIT_TIME_LONG
|
||||
dofaintanimation BS_ATTACKER
|
||||
@ -5502,6 +5507,7 @@ BattleScript_FaintAttacker::
|
||||
|
||||
BattleScript_FaintTarget::
|
||||
tryillusionoff BS_TARGET
|
||||
tryactivategulpmissile
|
||||
playfaintcry BS_TARGET
|
||||
pause B_WAIT_TIME_LONG
|
||||
dofaintanimation BS_TARGET
|
||||
|
||||
|
Before Width: | Height: | Size: 345 B |
|
Before Width: | Height: | Size: 362 B |
BIN
graphics/pokemon/unown/b/front.png
Normal file
|
After Width: | Height: | Size: 385 B |
|
Before Width: | Height: | Size: 403 B |
BIN
graphics/pokemon/unown/c/front.png
Normal file
|
After Width: | Height: | Size: 436 B |
|
Before Width: | Height: | Size: 359 B |
BIN
graphics/pokemon/unown/d/front.png
Normal file
|
After Width: | Height: | Size: 380 B |
|
Before Width: | Height: | Size: 332 B |
BIN
graphics/pokemon/unown/e/front.png
Normal file
|
After Width: | Height: | Size: 357 B |
|
Before Width: | Height: | Size: 301 B |
BIN
graphics/pokemon/unown/exclamation_mark/front.png
Normal file
|
After Width: | Height: | Size: 327 B |
|
Before Width: | Height: | Size: 372 B |
BIN
graphics/pokemon/unown/f/front.png
Normal file
|
After Width: | Height: | Size: 394 B |
BIN
graphics/pokemon/unown/front.png
Normal file
|
After Width: | Height: | Size: 371 B |
|
Before Width: | Height: | Size: 369 B |
BIN
graphics/pokemon/unown/g/front.png
Normal file
|
After Width: | Height: | Size: 393 B |
|
Before Width: | Height: | Size: 433 B |
BIN
graphics/pokemon/unown/h/front.png
Normal file
|
After Width: | Height: | Size: 454 B |
|
Before Width: | Height: | Size: 311 B |
BIN
graphics/pokemon/unown/i/front.png
Normal file
|
After Width: | Height: | Size: 332 B |
|
Before Width: | Height: | Size: 342 B |
BIN
graphics/pokemon/unown/j/front.png
Normal file
|
After Width: | Height: | Size: 362 B |
|
Before Width: | Height: | Size: 354 B |
BIN
graphics/pokemon/unown/k/front.png
Normal file
|
After Width: | Height: | Size: 369 B |
|
Before Width: | Height: | Size: 321 B |
BIN
graphics/pokemon/unown/l/front.png
Normal file
|
After Width: | Height: | Size: 344 B |
|
Before Width: | Height: | Size: 423 B |
BIN
graphics/pokemon/unown/m/front.png
Normal file
|
After Width: | Height: | Size: 437 B |
|
Before Width: | Height: | Size: 385 B |
BIN
graphics/pokemon/unown/n/front.png
Normal file
|
After Width: | Height: | Size: 406 B |
|
Before Width: | Height: | Size: 426 B |
BIN
graphics/pokemon/unown/o/front.png
Normal file
|
After Width: | Height: | Size: 443 B |
|
Before Width: | Height: | Size: 318 B |
BIN
graphics/pokemon/unown/p/front.png
Normal file
|
After Width: | Height: | Size: 345 B |
|
Before Width: | Height: | Size: 327 B |
BIN
graphics/pokemon/unown/q/front.png
Normal file
|
After Width: | Height: | Size: 350 B |
|
Before Width: | Height: | Size: 339 B |
BIN
graphics/pokemon/unown/question_mark/front.png
Normal file
|
After Width: | Height: | Size: 366 B |
|
Before Width: | Height: | Size: 319 B |
BIN
graphics/pokemon/unown/r/front.png
Normal file
|
After Width: | Height: | Size: 342 B |
|
Before Width: | Height: | Size: 373 B |
BIN
graphics/pokemon/unown/s/front.png
Normal file
|
After Width: | Height: | Size: 386 B |
|
Before Width: | Height: | Size: 323 B |
BIN
graphics/pokemon/unown/t/front.png
Normal file
|
After Width: | Height: | Size: 350 B |
|
Before Width: | Height: | Size: 397 B |
BIN
graphics/pokemon/unown/u/front.png
Normal file
|
After Width: | Height: | Size: 424 B |
|
Before Width: | Height: | Size: 358 B |
BIN
graphics/pokemon/unown/v/front.png
Normal file
|
After Width: | Height: | Size: 384 B |
|
Before Width: | Height: | Size: 363 B |
BIN
graphics/pokemon/unown/w/front.png
Normal file
|
After Width: | Height: | Size: 379 B |
|
Before Width: | Height: | Size: 344 B |
BIN
graphics/pokemon/unown/x/front.png
Normal file
|
After Width: | Height: | Size: 369 B |
|
Before Width: | Height: | Size: 355 B |
BIN
graphics/pokemon/unown/y/front.png
Normal file
|
After Width: | Height: | Size: 379 B |
|
Before Width: | Height: | Size: 332 B |
BIN
graphics/pokemon/unown/z/front.png
Normal file
|
After Width: | Height: | Size: 343 B |
@ -32,13 +32,13 @@
|
||||
#define BEST_DAMAGE_MOVE 1 // Move with the most amount of hits with the best accuracy/effect
|
||||
#define POWERFUL_STATUS_MOVE 10 // Moves with this score will be chosen over a move that faints target
|
||||
|
||||
// Temporary scores that are added together to determine a final score at the at of AI_CalcMoveScore
|
||||
// Temporary scores that are added together to determine a final score at the at of AI_CalcMoveEffectScore
|
||||
#define WEAK_EFFECT 1
|
||||
#define DECENT_EFFECT 2
|
||||
#define GOOD_EFFECT 4
|
||||
#define BEST_EFFECT 6
|
||||
|
||||
// AI_CalcMoveScore final score
|
||||
// AI_CalcMoveEffectScore final score
|
||||
#define NOT_GOOD_ENOUGH 0 // Not worth using over a damaging move
|
||||
#define GOOD_MOVE_EFFECTS 2 // Worth using over a damaging move
|
||||
#define PREFERRED_MOVE_EFFECTS 3 // Worth using over a damagin move and is better then DECENT_EFFECT
|
||||
|
||||
@ -179,6 +179,7 @@ bool32 SideHasMoveCategory(u32 battlerId, u32 category);
|
||||
|
||||
// score increases
|
||||
void IncreaseStatUpScore(u32 battlerAtk, u32 battlerDef, u32 statId, s32 *score);
|
||||
void IncreaseStatUpScoreContrary(u32 battlerAtk, u32 battlerDef, u32 statId, s32 *score);
|
||||
void IncreasePoisonScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score);
|
||||
void IncreaseBurnScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score);
|
||||
void IncreaseParalyzeScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score);
|
||||
|
||||
@ -120,4 +120,7 @@
|
||||
// param1: status
|
||||
#define FORM_CHANGE_STATUS 20
|
||||
|
||||
// Form change that activates after move is used. Currently only used for activating Gulp Missile.
|
||||
#define FORM_CHANGE_HIT_BY_MOVE 21
|
||||
|
||||
#endif // GUARD_CONSTANTS_FORM_CHANGE_TYPES_H
|
||||
|
||||
@ -838,7 +838,22 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
||||
break;
|
||||
case AI_EFFECTIVENESS_x0_125:
|
||||
case AI_EFFECTIVENESS_x0_25:
|
||||
RETURN_SCORE_MINUS(10);
|
||||
switch (moveEffect)
|
||||
{
|
||||
case EFFECT_FIXED_DAMAGE_ARG:
|
||||
case EFFECT_LEVEL_DAMAGE:
|
||||
case EFFECT_PSYWAVE:
|
||||
case EFFECT_OHKO:
|
||||
case EFFECT_BIDE:
|
||||
case EFFECT_SUPER_FANG:
|
||||
case EFFECT_ENDEAVOR:
|
||||
case EFFECT_COUNTER:
|
||||
case EFFECT_MIRROR_COAT:
|
||||
case EFFECT_METAL_BURST:
|
||||
break;
|
||||
default:
|
||||
RETURN_SCORE_MINUS(10);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -3162,7 +3177,7 @@ static s32 AI_CompareDamagingMoves(u32 battlerAtk, u32 battlerDef, u32 currId)
|
||||
return score;
|
||||
}
|
||||
|
||||
static u32 AI_CalcMoveScore(u32 battlerAtk, u32 battlerDef, u32 move)
|
||||
static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
|
||||
{
|
||||
// move data
|
||||
u32 moveEffect = gMovesInfo[move].effect;
|
||||
@ -3593,7 +3608,7 @@ static u32 AI_CalcMoveScore(u32 battlerAtk, u32 battlerDef, u32 move)
|
||||
else
|
||||
ADJUST_SCORE(WEAK_EFFECT);
|
||||
}
|
||||
else if (aiData->abilities[battlerAtk] != ABILITY_CONTRARY)
|
||||
else
|
||||
{
|
||||
IncreaseStatUpScore(battlerAtk, battlerDef, STAT_CHANGE_ATK, &score);
|
||||
IncreaseStatUpScore(battlerAtk, battlerDef, STAT_CHANGE_DEF, &score);
|
||||
@ -4408,56 +4423,88 @@ static u32 AI_CalcMoveScore(u32 battlerAtk, u32 battlerDef, u32 move)
|
||||
// Consider move effects that target self
|
||||
if (gMovesInfo[move].additionalEffects[i].self)
|
||||
{
|
||||
u32 oneStageStatId = STAT_CHANGE_ATK + gMovesInfo[move].additionalEffects[i].moveEffect - MOVE_EFFECT_ATK_PLUS_1;
|
||||
u32 twoStageStatId = STAT_CHANGE_ATK_2 + gMovesInfo[move].additionalEffects[i].moveEffect - MOVE_EFFECT_ATK_PLUS_1;
|
||||
u32 StageStatId;
|
||||
|
||||
switch (gMovesInfo[move].additionalEffects[i].moveEffect)
|
||||
if (aiData->abilities[battlerAtk] != ABILITY_CONTRARY)
|
||||
{
|
||||
case MOVE_EFFECT_SPD_PLUS_2:
|
||||
case MOVE_EFFECT_SPD_PLUS_1:
|
||||
if (aiData->abilities[battlerAtk] != ABILITY_CONTRARY && !AI_STRIKES_FIRST(battlerAtk, battlerDef, move))
|
||||
ADJUST_SCORE(GOOD_EFFECT);
|
||||
break;
|
||||
switch (gMovesInfo[move].additionalEffects[i].moveEffect)
|
||||
{
|
||||
case MOVE_EFFECT_ATK_PLUS_1:
|
||||
case MOVE_EFFECT_DEF_PLUS_1:
|
||||
case MOVE_EFFECT_SPD_PLUS_1:
|
||||
case MOVE_EFFECT_SP_ATK_PLUS_1:
|
||||
case MOVE_EFFECT_SP_DEF_PLUS_1:
|
||||
case MOVE_EFFECT_ACC_PLUS_1:
|
||||
case MOVE_EFFECT_EVS_PLUS_1:
|
||||
IncreaseStatUpScore(battlerAtk, battlerDef, oneStageStatId, &score);
|
||||
StageStatId = STAT_CHANGE_ATK + gMovesInfo[move].additionalEffects[i].moveEffect - MOVE_EFFECT_ATK_PLUS_1;
|
||||
IncreaseStatUpScore(battlerAtk, battlerDef, StageStatId, &score);
|
||||
break;
|
||||
case MOVE_EFFECT_ATK_PLUS_2:
|
||||
case MOVE_EFFECT_DEF_PLUS_2:
|
||||
case MOVE_EFFECT_SPD_PLUS_2:
|
||||
case MOVE_EFFECT_SP_ATK_PLUS_2:
|
||||
case MOVE_EFFECT_SP_DEF_PLUS_2:
|
||||
case MOVE_EFFECT_ACC_PLUS_2:
|
||||
case MOVE_EFFECT_EVS_PLUS_2:
|
||||
IncreaseStatUpScore(battlerAtk, battlerDef, twoStageStatId, &score);
|
||||
StageStatId = STAT_CHANGE_ATK_2 + gMovesInfo[move].additionalEffects[i].moveEffect - MOVE_EFFECT_ATK_PLUS_1;
|
||||
IncreaseStatUpScore(battlerAtk, battlerDef, StageStatId, &score);
|
||||
break;
|
||||
// Effects that lower stat(s) - only need to consider Contrary
|
||||
case MOVE_EFFECT_ATK_MINUS_1:
|
||||
case MOVE_EFFECT_DEF_MINUS_1:
|
||||
case MOVE_EFFECT_SPD_MINUS_1:
|
||||
case MOVE_EFFECT_SP_ATK_MINUS_1:
|
||||
case MOVE_EFFECT_SP_DEF_MINUS_1:
|
||||
case MOVE_EFFECT_DEF_SPDEF_DOWN:
|
||||
case MOVE_EFFECT_ATK_DEF_DOWN:
|
||||
case MOVE_EFFECT_SP_ATK_TWO_DOWN:
|
||||
if (aiData->abilities[battlerAtk] == ABILITY_CONTRARY)
|
||||
IncreaseStatUpScore(battlerAtk, battlerDef, oneStageStatId, &score);
|
||||
case MOVE_EFFECT_V_CREATE:
|
||||
if (aiData->abilities[battlerAtk] == ABILITY_CONTRARY)
|
||||
{
|
||||
IncreaseStatUpScore(battlerAtk, battlerDef, STAT_CHANGE_DEF, &score);
|
||||
IncreaseStatUpScore(battlerAtk, battlerDef, STAT_CHANGE_SPEED, &score);
|
||||
IncreaseStatUpScore(battlerAtk, battlerDef, STAT_CHANGE_SPDEF, &score);
|
||||
}
|
||||
case MOVE_EFFECT_ACC_PLUS_1:
|
||||
case MOVE_EFFECT_ACC_PLUS_2:
|
||||
IncreaseStatUpScore(battlerAtk, battlerDef, STAT_CHANGE_ACC, &score);
|
||||
break;
|
||||
case MOVE_EFFECT_EVS_PLUS_1:
|
||||
case MOVE_EFFECT_EVS_PLUS_2:
|
||||
IncreaseStatUpScore(battlerAtk, battlerDef, STAT_CHANGE_EVASION, &score);
|
||||
break;
|
||||
case MOVE_EFFECT_RAPID_SPIN:
|
||||
if ((gSideStatuses[GetBattlerSide(battlerAtk)] & SIDE_STATUS_HAZARDS_ANY && CountUsablePartyMons(battlerAtk) != 0)
|
||||
|| (gStatuses3[battlerAtk] & STATUS3_LEECHSEED || gBattleMons[battlerAtk].status2 & STATUS2_WRAPPED))
|
||||
ADJUST_SCORE(GOOD_EFFECT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (gMovesInfo[move].additionalEffects[i].moveEffect)
|
||||
{
|
||||
case MOVE_EFFECT_ATK_MINUS_1:
|
||||
case MOVE_EFFECT_DEF_MINUS_1:
|
||||
case MOVE_EFFECT_SPD_MINUS_1:
|
||||
case MOVE_EFFECT_SP_ATK_MINUS_1:
|
||||
case MOVE_EFFECT_SP_DEF_MINUS_1:
|
||||
StageStatId = STAT_CHANGE_ATK + gMovesInfo[move].additionalEffects[i].moveEffect - MOVE_EFFECT_ATK_MINUS_1;
|
||||
IncreaseStatUpScoreContrary(battlerAtk, battlerDef, StageStatId, &score);
|
||||
break;
|
||||
case MOVE_EFFECT_ATK_MINUS_2:
|
||||
case MOVE_EFFECT_DEF_MINUS_2:
|
||||
case MOVE_EFFECT_SPD_MINUS_2:
|
||||
case MOVE_EFFECT_SP_ATK_MINUS_2:
|
||||
case MOVE_EFFECT_SP_DEF_MINUS_2:
|
||||
StageStatId = STAT_CHANGE_ATK + gMovesInfo[move].additionalEffects[i].moveEffect - MOVE_EFFECT_ATK_MINUS_2;
|
||||
IncreaseStatUpScoreContrary(battlerAtk, battlerDef, StageStatId, &score);
|
||||
break;
|
||||
case MOVE_EFFECT_ACC_MINUS_1:
|
||||
case MOVE_EFFECT_ACC_MINUS_2:
|
||||
IncreaseStatUpScoreContrary(battlerAtk, battlerDef, STAT_CHANGE_ACC, &score);
|
||||
break;
|
||||
case MOVE_EFFECT_EVS_MINUS_1:
|
||||
case MOVE_EFFECT_EVS_MINUS_2:
|
||||
IncreaseStatUpScoreContrary(battlerAtk, battlerDef, STAT_CHANGE_EVASION, &score);
|
||||
break;
|
||||
case MOVE_EFFECT_DEF_SPDEF_DOWN:
|
||||
IncreaseStatUpScoreContrary(battlerAtk, battlerDef, STAT_CHANGE_DEF, &score);
|
||||
IncreaseStatUpScoreContrary(battlerAtk, battlerDef, STAT_CHANGE_SPDEF, &score);
|
||||
break;
|
||||
case MOVE_EFFECT_ATK_DEF_DOWN:
|
||||
IncreaseStatUpScoreContrary(battlerAtk, battlerDef, STAT_CHANGE_ATK, &score);
|
||||
IncreaseStatUpScoreContrary(battlerAtk, battlerDef, STAT_CHANGE_DEF, &score);
|
||||
break;
|
||||
case MOVE_EFFECT_SP_ATK_TWO_DOWN:
|
||||
IncreaseStatUpScoreContrary(battlerAtk, battlerDef, STAT_CHANGE_SPATK_2, &score);
|
||||
break;
|
||||
case MOVE_EFFECT_V_CREATE:
|
||||
IncreaseStatUpScoreContrary(battlerAtk, battlerDef, STAT_CHANGE_DEF, &score);
|
||||
IncreaseStatUpScoreContrary(battlerAtk, battlerDef, STAT_CHANGE_SPEED, &score);
|
||||
IncreaseStatUpScoreContrary(battlerAtk, battlerDef, STAT_CHANGE_SPDEF, &score);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else // consider move effects that hinder the target
|
||||
@ -4640,8 +4687,7 @@ static s32 AI_CheckViability(u32 battlerAtk, u32 battlerDef, u32 move, s32 score
|
||||
score += AI_CompareDamagingMoves(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex);
|
||||
}
|
||||
|
||||
// Calculates score based on effects of a move
|
||||
score += AI_CalcMoveScore(battlerAtk, battlerDef, move);
|
||||
score += AI_CalcMoveEffectScore(battlerAtk, battlerDef, move);
|
||||
|
||||
return score;
|
||||
}
|
||||
|
||||
@ -431,6 +431,7 @@ bool32 IsDamageMoveUnusable(u32 move, u32 battlerAtk, u32 battlerDef)
|
||||
return TRUE;
|
||||
break;
|
||||
case EFFECT_LOW_KICK:
|
||||
case EFFECT_HEAT_CRASH:
|
||||
if (IsDynamaxed(battlerDef))
|
||||
return TRUE;
|
||||
break;
|
||||
@ -644,22 +645,35 @@ static bool32 AI_IsMoveEffectInPlus(u32 battlerAtk, u32 battlerDef, u32 move, s3
|
||||
switch (gMovesInfo[move].additionalEffects[i].moveEffect)
|
||||
{
|
||||
case MOVE_EFFECT_ATK_PLUS_1:
|
||||
case MOVE_EFFECT_ATK_PLUS_2:
|
||||
if (BattlerStatCanRise(battlerAtk, abilityAtk, STAT_ATK))
|
||||
return TRUE;
|
||||
break;
|
||||
case MOVE_EFFECT_DEF_PLUS_2:
|
||||
case MOVE_EFFECT_DEF_PLUS_1:
|
||||
case MOVE_EFFECT_DEF_PLUS_2:
|
||||
if (BattlerStatCanRise(battlerAtk, abilityAtk, STAT_DEF))
|
||||
return TRUE;
|
||||
break;
|
||||
case MOVE_EFFECT_SPD_PLUS_1:
|
||||
case MOVE_EFFECT_SPD_PLUS_2:
|
||||
if (BattlerStatCanRise(battlerAtk, abilityAtk, STAT_SPEED))
|
||||
return TRUE;
|
||||
break;
|
||||
case MOVE_EFFECT_SP_ATK_PLUS_1:
|
||||
case MOVE_EFFECT_SP_ATK_PLUS_2:
|
||||
if (BattlerStatCanRise(battlerAtk, abilityAtk, STAT_SPATK))
|
||||
return TRUE;
|
||||
break;
|
||||
case MOVE_EFFECT_EVS_PLUS_1:
|
||||
case MOVE_EFFECT_EVS_PLUS_2:
|
||||
if (BattlerStatCanRise(battlerAtk, abilityAtk, STAT_EVASION))
|
||||
return TRUE;
|
||||
break;
|
||||
case MOVE_EFFECT_ACC_PLUS_1:
|
||||
case MOVE_EFFECT_ACC_PLUS_2:
|
||||
if (BattlerStatCanRise(battlerAtk, abilityAtk, STAT_ACC))
|
||||
return TRUE;
|
||||
break;
|
||||
case MOVE_EFFECT_ALL_STATS_UP:
|
||||
for (i = STAT_ATK; i <= NUM_STATS; i++)
|
||||
{
|
||||
@ -754,18 +768,45 @@ static bool32 AI_IsMoveEffectInMinus(u32 battlerAtk, u32 battlerDef, u32 move, s
|
||||
case MOVE_EFFECT_DEF_MINUS_1:
|
||||
case MOVE_EFFECT_SPD_MINUS_1:
|
||||
case MOVE_EFFECT_SP_ATK_MINUS_1:
|
||||
case MOVE_EFFECT_SP_DEF_MINUS_1:
|
||||
case MOVE_EFFECT_EVS_MINUS_1:
|
||||
case MOVE_EFFECT_ACC_MINUS_1:
|
||||
case MOVE_EFFECT_ATK_MINUS_2:
|
||||
case MOVE_EFFECT_DEF_MINUS_2:
|
||||
case MOVE_EFFECT_SPD_MINUS_2:
|
||||
case MOVE_EFFECT_SP_ATK_MINUS_2:
|
||||
case MOVE_EFFECT_SP_DEF_MINUS_2:
|
||||
case MOVE_EFFECT_EVS_MINUS_2:
|
||||
case MOVE_EFFECT_ACC_MINUS_2:
|
||||
case MOVE_EFFECT_SP_ATK_TWO_DOWN:
|
||||
case MOVE_EFFECT_V_CREATE:
|
||||
case MOVE_EFFECT_ATK_DEF_DOWN:
|
||||
case MOVE_EFFECT_DEF_SPDEF_DOWN:
|
||||
case MOVE_EFFECT_SP_DEF_MINUS_1:
|
||||
case MOVE_EFFECT_SP_DEF_MINUS_2:
|
||||
if ((gMovesInfo[move].additionalEffects[i].self && GetBattlerAbility(battlerAtk) != ABILITY_CONTRARY)
|
||||
|| (noOfHitsToKo != 1 && abilityDef == ABILITY_CONTRARY && !IsMoldBreakerTypeAbility(abilityAtk)))
|
||||
if ((gMovesInfo[move].additionalEffects[i].self && abilityAtk != ABILITY_CONTRARY)
|
||||
|| (noOfHitsToKo != 1 && abilityDef == ABILITY_CONTRARY && !DoesBattlerIgnoreAbilityChecks(abilityAtk, move)))
|
||||
return TRUE;
|
||||
break;
|
||||
case MOVE_EFFECT_RECHARGE:
|
||||
return gMovesInfo[move].additionalEffects[i].self;
|
||||
case MOVE_EFFECT_ATK_PLUS_1:
|
||||
case MOVE_EFFECT_DEF_PLUS_1:
|
||||
case MOVE_EFFECT_SPD_PLUS_1:
|
||||
case MOVE_EFFECT_SP_ATK_PLUS_1:
|
||||
case MOVE_EFFECT_SP_DEF_PLUS_1:
|
||||
case MOVE_EFFECT_EVS_PLUS_1:
|
||||
case MOVE_EFFECT_ACC_PLUS_1:
|
||||
case MOVE_EFFECT_ATK_PLUS_2:
|
||||
case MOVE_EFFECT_DEF_PLUS_2:
|
||||
case MOVE_EFFECT_SPD_PLUS_2:
|
||||
case MOVE_EFFECT_SP_ATK_PLUS_2:
|
||||
case MOVE_EFFECT_SP_DEF_PLUS_2:
|
||||
case MOVE_EFFECT_EVS_PLUS_2:
|
||||
case MOVE_EFFECT_ACC_PLUS_2:
|
||||
case MOVE_EFFECT_ALL_STATS_UP:
|
||||
if ((gMovesInfo[move].additionalEffects[i].self && abilityAtk == ABILITY_CONTRARY)
|
||||
|| (noOfHitsToKo != 1 && !(abilityDef == ABILITY_CONTRARY && !DoesBattlerIgnoreAbilityChecks(abilityAtk, move))))
|
||||
return TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -3405,13 +3446,13 @@ bool32 IsRecycleEncouragedItem(u32 item)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void IncreaseStatUpScore(u32 battlerAtk, u32 battlerDef, u32 statId, s32 *score)
|
||||
static void IncreaseStatUpScoreInternal(u32 battlerAtk, u32 battlerDef, u32 statId, s32 *score, bool32 considerContrary)
|
||||
{
|
||||
u32 noOfHitsToFaint = NoOfHitsForTargetToFaintAI(battlerDef, battlerAtk);
|
||||
u32 aiIsFaster = GetWhichBattlerFaster(battlerAtk, battlerDef, TRUE) == AI_IS_FASTER;
|
||||
u32 shouldSetUp = ((noOfHitsToFaint >= 2 && aiIsFaster) || (noOfHitsToFaint >= 3 && !aiIsFaster) || noOfHitsToFaint == UNKNOWN_NO_OF_HITS);
|
||||
|
||||
if (AI_DATA->abilities[battlerAtk] == ABILITY_CONTRARY)
|
||||
if (considerContrary && AI_DATA->abilities[battlerAtk] == ABILITY_CONTRARY)
|
||||
return;
|
||||
|
||||
// Don't increase stat if AI is at +4
|
||||
@ -3505,6 +3546,16 @@ void IncreaseStatUpScore(u32 battlerAtk, u32 battlerDef, u32 statId, s32 *score)
|
||||
}
|
||||
}
|
||||
|
||||
void IncreaseStatUpScore(u32 battlerAtk, u32 battlerDef, u32 statId, s32 *score)
|
||||
{
|
||||
IncreaseStatUpScoreInternal(battlerAtk, battlerDef, statId, score, TRUE);
|
||||
}
|
||||
|
||||
void IncreaseStatUpScoreContrary(u32 battlerAtk, u32 battlerDef, u32 statId, s32 *score)
|
||||
{
|
||||
IncreaseStatUpScoreInternal(battlerAtk, battlerDef, statId, score, FALSE);
|
||||
}
|
||||
|
||||
void IncreasePoisonScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score)
|
||||
{
|
||||
if (((AI_THINKING_STRUCT->aiFlags[battlerAtk] & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0))
|
||||
|
||||
@ -899,8 +899,8 @@ void HandleSpeciesGfxDataChange(u8 battlerAtk, u8 battlerDef, bool32 megaEvo, bo
|
||||
{
|
||||
if (B_TRANSFORM_SHINY >= GEN_4 && trackEnemyPersonality)
|
||||
{
|
||||
personalityValue = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerAtk]], MON_DATA_PERSONALITY);
|
||||
isShiny = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerAtk]], MON_DATA_IS_SHINY);
|
||||
personalityValue = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerDef]], MON_DATA_PERSONALITY);
|
||||
isShiny = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerDef]], MON_DATA_IS_SHINY);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -917,8 +917,8 @@ void HandleSpeciesGfxDataChange(u8 battlerAtk, u8 battlerDef, bool32 megaEvo, bo
|
||||
{
|
||||
if (B_TRANSFORM_SHINY >= GEN_4 && trackEnemyPersonality)
|
||||
{
|
||||
personalityValue = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerAtk]], MON_DATA_PERSONALITY);
|
||||
isShiny = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerAtk]], MON_DATA_IS_SHINY);
|
||||
personalityValue = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerDef]], MON_DATA_PERSONALITY);
|
||||
isShiny = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerDef]], MON_DATA_IS_SHINY);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@ -3290,11 +3290,13 @@ static void ClearSetBScriptingStruct(void)
|
||||
{
|
||||
// windowsType is set up earlier in BattleInitBgsAndWindows, so we need to save the value
|
||||
u32 temp = gBattleScripting.windowsType;
|
||||
u32 specialBattleType = gBattleScripting.specialTrainerBattleType;
|
||||
memset(&gBattleScripting, 0, sizeof(gBattleScripting));
|
||||
|
||||
gBattleScripting.windowsType = temp;
|
||||
gBattleScripting.battleStyle = gSaveBlock2Ptr->optionsBattleStyle;
|
||||
gBattleScripting.expOnCatch = (B_EXP_CATCH >= GEN_6);
|
||||
gBattleScripting.specialTrainerBattleType = specialBattleType;
|
||||
}
|
||||
|
||||
static void BattleStartClearSetData(void)
|
||||
|
||||
@ -3162,7 +3162,6 @@ void SetMoveEffect(bool32 primary, bool32 certain)
|
||||
}
|
||||
else
|
||||
{
|
||||
u8 side;
|
||||
switch (gBattleScripting.moveEffect)
|
||||
{
|
||||
case MOVE_EFFECT_CONFUSION:
|
||||
@ -3176,7 +3175,7 @@ void SetMoveEffect(bool32 primary, bool32 certain)
|
||||
|
||||
// If the confusion is activating due to being released from Sky Drop, go to "confused due to fatigue" script.
|
||||
// Otherwise, do normal confusion script.
|
||||
if(gCurrentMove == MOVE_SKY_DROP)
|
||||
if (gCurrentMove == MOVE_SKY_DROP)
|
||||
{
|
||||
gBattleMons[gEffectBattler].status2 &= ~(STATUS2_LOCK_CONFUSE);
|
||||
gBattlerAttacker = gEffectBattler;
|
||||
@ -3420,35 +3419,13 @@ void SetMoveEffect(bool32 primary, bool32 certain)
|
||||
break;
|
||||
case MOVE_EFFECT_STEAL_ITEM:
|
||||
{
|
||||
if (!CanStealItem(gBattlerAttacker, gBattlerTarget, gBattleMons[gBattlerTarget].item))
|
||||
{
|
||||
gBattlescriptCurrInstr++;
|
||||
break;
|
||||
}
|
||||
|
||||
side = GetBattlerSide(gBattlerAttacker);
|
||||
if (GetBattlerSide(gBattlerAttacker) == B_SIDE_OPPONENT
|
||||
&& !(gBattleTypeFlags &
|
||||
(BATTLE_TYPE_EREADER_TRAINER
|
||||
| BATTLE_TYPE_FRONTIER
|
||||
| BATTLE_TYPE_LINK
|
||||
| BATTLE_TYPE_RECORDED_LINK
|
||||
| BATTLE_TYPE_SECRET_BASE)))
|
||||
if (!CanStealItem(gBattlerAttacker, gBattlerTarget, gBattleMons[gBattlerTarget].item)
|
||||
|| gBattleMons[gBattlerAttacker].item != ITEM_NONE
|
||||
|| gBattleMons[gBattlerTarget].item == ITEM_NONE)
|
||||
{
|
||||
gBattlescriptCurrInstr++;
|
||||
}
|
||||
else if (!(gBattleTypeFlags &
|
||||
(BATTLE_TYPE_EREADER_TRAINER
|
||||
| BATTLE_TYPE_FRONTIER
|
||||
| BATTLE_TYPE_LINK
|
||||
| BATTLE_TYPE_RECORDED_LINK
|
||||
| BATTLE_TYPE_SECRET_BASE))
|
||||
&& (gWishFutureKnock.knockedOffMons[side] & gBitTable[gBattlerPartyIndexes[gBattlerAttacker]]))
|
||||
{
|
||||
gBattlescriptCurrInstr++;
|
||||
}
|
||||
else if (gBattleMons[gBattlerTarget].item
|
||||
&& GetBattlerAbility(gBattlerTarget) == ABILITY_STICKY_HOLD)
|
||||
else if (GetBattlerAbility(gBattlerTarget) == ABILITY_STICKY_HOLD)
|
||||
{
|
||||
BattleScriptPushCursor();
|
||||
gBattlescriptCurrInstr = BattleScript_NoItemSteal;
|
||||
@ -3456,12 +3433,6 @@ void SetMoveEffect(bool32 primary, bool32 certain)
|
||||
gLastUsedAbility = gBattleMons[gBattlerTarget].ability;
|
||||
RecordAbilityBattle(gBattlerTarget, gLastUsedAbility);
|
||||
}
|
||||
else if (gBattleMons[gBattlerAttacker].item != ITEM_NONE
|
||||
|| gBattleMons[gBattlerTarget].item == ITEM_ENIGMA_BERRY_E_READER
|
||||
|| gBattleMons[gBattlerTarget].item == ITEM_NONE)
|
||||
{
|
||||
gBattlescriptCurrInstr++;
|
||||
}
|
||||
else
|
||||
{
|
||||
StealTargetItem(gBattlerAttacker, gBattlerTarget); // Attacker steals target item
|
||||
@ -4438,15 +4409,19 @@ static void Cmd_getexp(void)
|
||||
gBattleMoveDamage += GetSoftLevelCapExpValue(gPlayerParty[*expMonId].level, gBattleStruct->expShareExpValue);;
|
||||
}
|
||||
|
||||
if (EXP_CAP_HARD && gBattleMoveDamage != 0)
|
||||
ApplyExperienceMultipliers(&gBattleMoveDamage, *expMonId, gBattlerFainted);
|
||||
|
||||
if (B_EXP_CAP_TYPE == EXP_CAP_HARD && gBattleMoveDamage != 0)
|
||||
{
|
||||
u32 growthRate = gSpeciesInfo[GetMonData(&gPlayerParty[*expMonId], MON_DATA_SPECIES)].growthRate;
|
||||
if (gExperienceTables[growthRate][GetCurrentLevelCap()] < gExperienceTables[growthRate][GetMonData(&gPlayerParty[*expMonId], MON_DATA_LEVEL)] + gBattleMoveDamage)
|
||||
gBattleMoveDamage = gExperienceTables[growthRate][GetCurrentLevelCap()];
|
||||
}
|
||||
u32 currentExp = GetMonData(&gPlayerParty[*expMonId], MON_DATA_EXP);
|
||||
u32 levelCap = GetCurrentLevelCap();
|
||||
|
||||
if (!EXP_CAP_HARD || gBattleMoveDamage != 0) // Edge case for hard level caps. Prevents mons from getting 1 exp
|
||||
ApplyExperienceMultipliers(&gBattleMoveDamage, *expMonId, gBattlerFainted);
|
||||
if (GetMonData(&gPlayerParty[*expMonId], MON_DATA_LEVEL) >= levelCap)
|
||||
gBattleMoveDamage = 0;
|
||||
else if (gExperienceTables[growthRate][levelCap] < currentExp + gBattleMoveDamage)
|
||||
gBattleMoveDamage = gExperienceTables[growthRate][levelCap] - currentExp;
|
||||
}
|
||||
|
||||
if (IsTradedMon(&gPlayerParty[*expMonId]))
|
||||
{
|
||||
@ -16712,7 +16687,7 @@ void BS_TryCopycat(void)
|
||||
{
|
||||
NATIVE_ARGS(const u8 *failInstr);
|
||||
|
||||
if (gLastUsedMove == MOVE_NONE || gLastUsedMove == MOVE_UNAVAILABLE || gMovesInfo[gLastUsedMove].copycatBanned)
|
||||
if (gLastUsedMove == MOVE_NONE || gLastUsedMove == MOVE_UNAVAILABLE || gMovesInfo[gLastUsedMove].copycatBanned || IsZMove(gLastUsedMove))
|
||||
{
|
||||
gBattlescriptCurrInstr = cmd->failInstr;
|
||||
}
|
||||
@ -16919,6 +16894,40 @@ void BS_TryGulpMissile(void)
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
|
||||
void BS_TryActivateGulpMissile(void)
|
||||
{
|
||||
NATIVE_ARGS();
|
||||
|
||||
if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
|
||||
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
|
||||
&& TARGET_TURN_DAMAGED
|
||||
&& gBattleMons[gBattlerTarget].species != SPECIES_CRAMORANT
|
||||
&& GetBattlerAbility(gBattlerTarget) == ABILITY_GULP_MISSILE)
|
||||
{
|
||||
if (GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD)
|
||||
{
|
||||
gBattleMoveDamage = GetNonDynamaxMaxHP(gBattlerAttacker) / 4;
|
||||
if (gBattleMoveDamage == 0)
|
||||
gBattleMoveDamage = 1;
|
||||
}
|
||||
|
||||
switch(gBattleMons[gBattlerTarget].species)
|
||||
{
|
||||
case SPECIES_CRAMORANT_GORGING:
|
||||
BattleScriptPushCursor();
|
||||
TryBattleFormChange(gBattlerTarget, FORM_CHANGE_HIT_BY_MOVE);
|
||||
gBattlescriptCurrInstr = BattleScript_GulpMissileGorging;
|
||||
return;
|
||||
case SPECIES_CRAMORANT_GULPING:
|
||||
BattleScriptPushCursor();
|
||||
TryBattleFormChange(gBattlerTarget, FORM_CHANGE_HIT_BY_MOVE);
|
||||
gBattlescriptCurrInstr = BattleScript_GulpMissileGulping;
|
||||
return;
|
||||
}
|
||||
}
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
|
||||
void BS_TryQuash(void)
|
||||
{
|
||||
NATIVE_ARGS(const u8 *failInstr);
|
||||
|
||||
@ -3002,6 +3002,15 @@ bool32 HandleWishPerishSongOnTurnEnd(void)
|
||||
{
|
||||
struct Pokemon *party;
|
||||
|
||||
if (gWishFutureKnock.futureSightCounter[battler] == 0
|
||||
&& gWishFutureKnock.futureSightCounter[BATTLE_PARTNER(battler)] == 0)
|
||||
{
|
||||
gSideStatuses[GetBattlerSide(battler)] &= ~SIDE_STATUS_FUTUREATTACK;
|
||||
}
|
||||
|
||||
if (!IsBattlerAlive(battler))
|
||||
continue;
|
||||
|
||||
if (gWishFutureKnock.futureSightMove[battler] == MOVE_FUTURE_SIGHT)
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_FUTURE_SIGHT;
|
||||
else
|
||||
@ -3020,12 +3029,6 @@ bool32 HandleWishPerishSongOnTurnEnd(void)
|
||||
|
||||
BattleScriptExecute(BattleScript_MonTookFutureAttack);
|
||||
|
||||
if (gWishFutureKnock.futureSightCounter[battler] == 0
|
||||
&& gWishFutureKnock.futureSightCounter[BATTLE_PARTNER(battler)] == 0)
|
||||
{
|
||||
gSideStatuses[GetBattlerSide(gBattlerTarget)] &= ~SIDE_STATUS_FUTUREATTACK;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
@ -5646,34 +5649,30 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
||||
if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
|
||||
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
|
||||
&& TARGET_TURN_DAMAGED
|
||||
&& IsBattlerAlive(battler))
|
||||
&& IsBattlerAlive(battler)
|
||||
&& gBattleMons[gBattlerTarget].species != SPECIES_CRAMORANT)
|
||||
{
|
||||
// TODO: Convert this to a proper FORM_CHANGE type.
|
||||
if (gBattleMons[gBattlerTarget].species == SPECIES_CRAMORANT_GORGING)
|
||||
if (GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD)
|
||||
{
|
||||
gBattleMons[gBattlerTarget].species = SPECIES_CRAMORANT;
|
||||
if (GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD)
|
||||
{
|
||||
gBattleMoveDamage = GetNonDynamaxMaxHP(gBattlerAttacker) / 4;
|
||||
if (gBattleMoveDamage == 0)
|
||||
gBattleMoveDamage = 1;
|
||||
}
|
||||
BattleScriptPushCursor();
|
||||
gBattlescriptCurrInstr = BattleScript_GulpMissileGorging;
|
||||
effect++;
|
||||
gBattleMoveDamage = GetNonDynamaxMaxHP(gBattlerAttacker) / 4;
|
||||
if (gBattleMoveDamage == 0)
|
||||
gBattleMoveDamage = 1;
|
||||
}
|
||||
else if (gBattleMons[gBattlerTarget].species == SPECIES_CRAMORANT_GULPING)
|
||||
|
||||
switch(gBattleMons[gBattlerTarget].species)
|
||||
{
|
||||
gBattleMons[gBattlerTarget].species = SPECIES_CRAMORANT;
|
||||
if (GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD)
|
||||
{
|
||||
gBattleMoveDamage = GetNonDynamaxMaxHP(gBattlerAttacker) / 4;
|
||||
if (gBattleMoveDamage == 0)
|
||||
gBattleMoveDamage = 1;
|
||||
}
|
||||
BattleScriptPushCursor();
|
||||
gBattlescriptCurrInstr = BattleScript_GulpMissileGulping;
|
||||
effect++;
|
||||
case SPECIES_CRAMORANT_GORGING:
|
||||
TryBattleFormChange(battler, FORM_CHANGE_HIT_BY_MOVE);
|
||||
BattleScriptPushCursor();
|
||||
gBattlescriptCurrInstr = BattleScript_GulpMissileGorging;
|
||||
effect++;
|
||||
break;
|
||||
case SPECIES_CRAMORANT_GULPING:
|
||||
TryBattleFormChange(battler, FORM_CHANGE_HIT_BY_MOVE);
|
||||
BattleScriptPushCursor();
|
||||
gBattlescriptCurrInstr = BattleScript_GulpMissileGulping;
|
||||
effect++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -10613,6 +10612,7 @@ u16 GetBattleFormChangeTargetSpecies(u32 battler, u16 method)
|
||||
}
|
||||
break;
|
||||
case FORM_CHANGE_BATTLE_TURN_END:
|
||||
case FORM_CHANGE_HIT_BY_MOVE:
|
||||
if (formChanges[i].param1 == GetBattlerAbility(battler))
|
||||
targetSpecies = formChanges[i].targetSpecies;
|
||||
break;
|
||||
|
||||
@ -2383,6 +2383,7 @@ static u8 GetTreeMutationValue(u8 id)
|
||||
return 0;
|
||||
myMutation.asField.a = tree->mutationA;
|
||||
myMutation.asField.b = tree->mutationB;
|
||||
myMutation.asField.unused = 0;
|
||||
return sBerryMutations[myMutation.value - 1][2];
|
||||
#else
|
||||
return 0;
|
||||
|
||||
@ -3146,115 +3146,115 @@ const u8 gMonFootprint_QuestionMark[] = INCBIN_U8("graphics/pokemon/question_mar
|
||||
const u8 gMonFootprint_Unown[] = INCBIN_U8("graphics/pokemon/unown/footprint.1bpp");
|
||||
#endif //P_FOOTPRINTS
|
||||
|
||||
const u32 gMonFrontPic_UnownA[] = INCBIN_U32("graphics/pokemon/unown/anim_front.4bpp.lz");
|
||||
const u32 gMonFrontPic_UnownA[] = INCBIN_U32("graphics/pokemon/unown/front.4bpp.lz");
|
||||
const u32 gMonBackPic_UnownA[] = INCBIN_U32("graphics/pokemon/unown/back.4bpp.lz");
|
||||
const u8 gMonIcon_UnownA[] = INCBIN_U8("graphics/pokemon/unown/icon.4bpp");
|
||||
|
||||
const u32 gMonFrontPic_UnownB[] = INCBIN_U32("graphics/pokemon/unown/b/anim_front.4bpp.lz");
|
||||
const u32 gMonFrontPic_UnownB[] = INCBIN_U32("graphics/pokemon/unown/b/front.4bpp.lz");
|
||||
const u32 gMonBackPic_UnownB[] = INCBIN_U32("graphics/pokemon/unown/b/back.4bpp.lz");
|
||||
const u8 gMonIcon_UnownB[] = INCBIN_U8("graphics/pokemon/unown/b/icon.4bpp");
|
||||
|
||||
const u32 gMonFrontPic_UnownC[] = INCBIN_U32("graphics/pokemon/unown/c/anim_front.4bpp.lz");
|
||||
const u32 gMonFrontPic_UnownC[] = INCBIN_U32("graphics/pokemon/unown/c/front.4bpp.lz");
|
||||
const u32 gMonBackPic_UnownC[] = INCBIN_U32("graphics/pokemon/unown/c/back.4bpp.lz");
|
||||
const u8 gMonIcon_UnownC[] = INCBIN_U8("graphics/pokemon/unown/c/icon.4bpp");
|
||||
|
||||
const u32 gMonFrontPic_UnownD[] = INCBIN_U32("graphics/pokemon/unown/d/anim_front.4bpp.lz");
|
||||
const u32 gMonFrontPic_UnownD[] = INCBIN_U32("graphics/pokemon/unown/d/front.4bpp.lz");
|
||||
const u32 gMonBackPic_UnownD[] = INCBIN_U32("graphics/pokemon/unown/d/back.4bpp.lz");
|
||||
const u8 gMonIcon_UnownD[] = INCBIN_U8("graphics/pokemon/unown/d/icon.4bpp");
|
||||
|
||||
const u32 gMonFrontPic_UnownE[] = INCBIN_U32("graphics/pokemon/unown/e/anim_front.4bpp.lz");
|
||||
const u32 gMonFrontPic_UnownE[] = INCBIN_U32("graphics/pokemon/unown/e/front.4bpp.lz");
|
||||
const u32 gMonBackPic_UnownE[] = INCBIN_U32("graphics/pokemon/unown/e/back.4bpp.lz");
|
||||
const u8 gMonIcon_UnownE[] = INCBIN_U8("graphics/pokemon/unown/e/icon.4bpp");
|
||||
|
||||
const u32 gMonFrontPic_UnownF[] = INCBIN_U32("graphics/pokemon/unown/f/anim_front.4bpp.lz");
|
||||
const u32 gMonFrontPic_UnownF[] = INCBIN_U32("graphics/pokemon/unown/f/front.4bpp.lz");
|
||||
const u32 gMonBackPic_UnownF[] = INCBIN_U32("graphics/pokemon/unown/f/back.4bpp.lz");
|
||||
const u8 gMonIcon_UnownF[] = INCBIN_U8("graphics/pokemon/unown/f/icon.4bpp");
|
||||
|
||||
const u32 gMonFrontPic_UnownG[] = INCBIN_U32("graphics/pokemon/unown/g/anim_front.4bpp.lz");
|
||||
const u32 gMonFrontPic_UnownG[] = INCBIN_U32("graphics/pokemon/unown/g/front.4bpp.lz");
|
||||
const u32 gMonBackPic_UnownG[] = INCBIN_U32("graphics/pokemon/unown/g/back.4bpp.lz");
|
||||
const u8 gMonIcon_UnownG[] = INCBIN_U8("graphics/pokemon/unown/g/icon.4bpp");
|
||||
|
||||
const u32 gMonFrontPic_UnownH[] = INCBIN_U32("graphics/pokemon/unown/h/anim_front.4bpp.lz");
|
||||
const u32 gMonFrontPic_UnownH[] = INCBIN_U32("graphics/pokemon/unown/h/front.4bpp.lz");
|
||||
const u32 gMonBackPic_UnownH[] = INCBIN_U32("graphics/pokemon/unown/h/back.4bpp.lz");
|
||||
const u8 gMonIcon_UnownH[] = INCBIN_U8("graphics/pokemon/unown/h/icon.4bpp");
|
||||
|
||||
const u32 gMonFrontPic_UnownI[] = INCBIN_U32("graphics/pokemon/unown/i/anim_front.4bpp.lz");
|
||||
const u32 gMonFrontPic_UnownI[] = INCBIN_U32("graphics/pokemon/unown/i/front.4bpp.lz");
|
||||
const u32 gMonBackPic_UnownI[] = INCBIN_U32("graphics/pokemon/unown/i/back.4bpp.lz");
|
||||
const u8 gMonIcon_UnownI[] = INCBIN_U8("graphics/pokemon/unown/i/icon.4bpp");
|
||||
|
||||
const u32 gMonFrontPic_UnownJ[] = INCBIN_U32("graphics/pokemon/unown/j/anim_front.4bpp.lz");
|
||||
const u32 gMonFrontPic_UnownJ[] = INCBIN_U32("graphics/pokemon/unown/j/front.4bpp.lz");
|
||||
const u32 gMonBackPic_UnownJ[] = INCBIN_U32("graphics/pokemon/unown/j/back.4bpp.lz");
|
||||
const u8 gMonIcon_UnownJ[] = INCBIN_U8("graphics/pokemon/unown/j/icon.4bpp");
|
||||
|
||||
const u32 gMonFrontPic_UnownK[] = INCBIN_U32("graphics/pokemon/unown/k/anim_front.4bpp.lz");
|
||||
const u32 gMonFrontPic_UnownK[] = INCBIN_U32("graphics/pokemon/unown/k/front.4bpp.lz");
|
||||
const u32 gMonBackPic_UnownK[] = INCBIN_U32("graphics/pokemon/unown/k/back.4bpp.lz");
|
||||
const u8 gMonIcon_UnownK[] = INCBIN_U8("graphics/pokemon/unown/k/icon.4bpp");
|
||||
|
||||
const u32 gMonFrontPic_UnownL[] = INCBIN_U32("graphics/pokemon/unown/l/anim_front.4bpp.lz");
|
||||
const u32 gMonFrontPic_UnownL[] = INCBIN_U32("graphics/pokemon/unown/l/front.4bpp.lz");
|
||||
const u32 gMonBackPic_UnownL[] = INCBIN_U32("graphics/pokemon/unown/l/back.4bpp.lz");
|
||||
const u8 gMonIcon_UnownL[] = INCBIN_U8("graphics/pokemon/unown/l/icon.4bpp");
|
||||
|
||||
const u32 gMonFrontPic_UnownM[] = INCBIN_U32("graphics/pokemon/unown/m/anim_front.4bpp.lz");
|
||||
const u32 gMonFrontPic_UnownM[] = INCBIN_U32("graphics/pokemon/unown/m/front.4bpp.lz");
|
||||
const u32 gMonBackPic_UnownM[] = INCBIN_U32("graphics/pokemon/unown/m/back.4bpp.lz");
|
||||
const u8 gMonIcon_UnownM[] = INCBIN_U8("graphics/pokemon/unown/m/icon.4bpp");
|
||||
|
||||
const u32 gMonFrontPic_UnownN[] = INCBIN_U32("graphics/pokemon/unown/n/anim_front.4bpp.lz");
|
||||
const u32 gMonFrontPic_UnownN[] = INCBIN_U32("graphics/pokemon/unown/n/front.4bpp.lz");
|
||||
const u32 gMonBackPic_UnownN[] = INCBIN_U32("graphics/pokemon/unown/n/back.4bpp.lz");
|
||||
const u8 gMonIcon_UnownN[] = INCBIN_U8("graphics/pokemon/unown/n/icon.4bpp");
|
||||
|
||||
const u32 gMonFrontPic_UnownO[] = INCBIN_U32("graphics/pokemon/unown/o/anim_front.4bpp.lz");
|
||||
const u32 gMonFrontPic_UnownO[] = INCBIN_U32("graphics/pokemon/unown/o/front.4bpp.lz");
|
||||
const u32 gMonBackPic_UnownO[] = INCBIN_U32("graphics/pokemon/unown/o/back.4bpp.lz");
|
||||
const u8 gMonIcon_UnownO[] = INCBIN_U8("graphics/pokemon/unown/o/icon.4bpp");
|
||||
|
||||
const u32 gMonFrontPic_UnownP[] = INCBIN_U32("graphics/pokemon/unown/p/anim_front.4bpp.lz");
|
||||
const u32 gMonFrontPic_UnownP[] = INCBIN_U32("graphics/pokemon/unown/p/front.4bpp.lz");
|
||||
const u32 gMonBackPic_UnownP[] = INCBIN_U32("graphics/pokemon/unown/p/back.4bpp.lz");
|
||||
const u8 gMonIcon_UnownP[] = INCBIN_U8("graphics/pokemon/unown/p/icon.4bpp");
|
||||
|
||||
const u32 gMonFrontPic_UnownQ[] = INCBIN_U32("graphics/pokemon/unown/q/anim_front.4bpp.lz");
|
||||
const u32 gMonFrontPic_UnownQ[] = INCBIN_U32("graphics/pokemon/unown/q/front.4bpp.lz");
|
||||
const u32 gMonBackPic_UnownQ[] = INCBIN_U32("graphics/pokemon/unown/q/back.4bpp.lz");
|
||||
const u8 gMonIcon_UnownQ[] = INCBIN_U8("graphics/pokemon/unown/q/icon.4bpp");
|
||||
|
||||
const u32 gMonFrontPic_UnownR[] = INCBIN_U32("graphics/pokemon/unown/r/anim_front.4bpp.lz");
|
||||
const u32 gMonFrontPic_UnownR[] = INCBIN_U32("graphics/pokemon/unown/r/front.4bpp.lz");
|
||||
const u32 gMonBackPic_UnownR[] = INCBIN_U32("graphics/pokemon/unown/r/back.4bpp.lz");
|
||||
const u8 gMonIcon_UnownR[] = INCBIN_U8("graphics/pokemon/unown/r/icon.4bpp");
|
||||
|
||||
const u32 gMonFrontPic_UnownS[] = INCBIN_U32("graphics/pokemon/unown/s/anim_front.4bpp.lz");
|
||||
const u32 gMonFrontPic_UnownS[] = INCBIN_U32("graphics/pokemon/unown/s/front.4bpp.lz");
|
||||
const u32 gMonBackPic_UnownS[] = INCBIN_U32("graphics/pokemon/unown/s/back.4bpp.lz");
|
||||
const u8 gMonIcon_UnownS[] = INCBIN_U8("graphics/pokemon/unown/s/icon.4bpp");
|
||||
|
||||
const u32 gMonFrontPic_UnownT[] = INCBIN_U32("graphics/pokemon/unown/t/anim_front.4bpp.lz");
|
||||
const u32 gMonFrontPic_UnownT[] = INCBIN_U32("graphics/pokemon/unown/t/front.4bpp.lz");
|
||||
const u32 gMonBackPic_UnownT[] = INCBIN_U32("graphics/pokemon/unown/t/back.4bpp.lz");
|
||||
const u8 gMonIcon_UnownT[] = INCBIN_U8("graphics/pokemon/unown/t/icon.4bpp");
|
||||
|
||||
const u32 gMonFrontPic_UnownU[] = INCBIN_U32("graphics/pokemon/unown/u/anim_front.4bpp.lz");
|
||||
const u32 gMonFrontPic_UnownU[] = INCBIN_U32("graphics/pokemon/unown/u/front.4bpp.lz");
|
||||
const u32 gMonBackPic_UnownU[] = INCBIN_U32("graphics/pokemon/unown/u/back.4bpp.lz");
|
||||
const u8 gMonIcon_UnownU[] = INCBIN_U8("graphics/pokemon/unown/u/icon.4bpp");
|
||||
|
||||
const u32 gMonFrontPic_UnownV[] = INCBIN_U32("graphics/pokemon/unown/v/anim_front.4bpp.lz");
|
||||
const u32 gMonFrontPic_UnownV[] = INCBIN_U32("graphics/pokemon/unown/v/front.4bpp.lz");
|
||||
const u32 gMonBackPic_UnownV[] = INCBIN_U32("graphics/pokemon/unown/v/back.4bpp.lz");
|
||||
const u8 gMonIcon_UnownV[] = INCBIN_U8("graphics/pokemon/unown/v/icon.4bpp");
|
||||
|
||||
const u32 gMonFrontPic_UnownW[] = INCBIN_U32("graphics/pokemon/unown/w/anim_front.4bpp.lz");
|
||||
const u32 gMonFrontPic_UnownW[] = INCBIN_U32("graphics/pokemon/unown/w/front.4bpp.lz");
|
||||
const u32 gMonBackPic_UnownW[] = INCBIN_U32("graphics/pokemon/unown/w/back.4bpp.lz");
|
||||
const u8 gMonIcon_UnownW[] = INCBIN_U8("graphics/pokemon/unown/w/icon.4bpp");
|
||||
|
||||
const u32 gMonFrontPic_UnownX[] = INCBIN_U32("graphics/pokemon/unown/x/anim_front.4bpp.lz");
|
||||
const u32 gMonFrontPic_UnownX[] = INCBIN_U32("graphics/pokemon/unown/x/front.4bpp.lz");
|
||||
const u32 gMonBackPic_UnownX[] = INCBIN_U32("graphics/pokemon/unown/x/back.4bpp.lz");
|
||||
const u8 gMonIcon_UnownX[] = INCBIN_U8("graphics/pokemon/unown/x/icon.4bpp");
|
||||
|
||||
const u32 gMonFrontPic_UnownY[] = INCBIN_U32("graphics/pokemon/unown/y/anim_front.4bpp.lz");
|
||||
const u32 gMonFrontPic_UnownY[] = INCBIN_U32("graphics/pokemon/unown/y/front.4bpp.lz");
|
||||
const u32 gMonBackPic_UnownY[] = INCBIN_U32("graphics/pokemon/unown/y/back.4bpp.lz");
|
||||
const u8 gMonIcon_UnownY[] = INCBIN_U8("graphics/pokemon/unown/y/icon.4bpp");
|
||||
|
||||
const u32 gMonFrontPic_UnownZ[] = INCBIN_U32("graphics/pokemon/unown/z/anim_front.4bpp.lz");
|
||||
const u32 gMonFrontPic_UnownZ[] = INCBIN_U32("graphics/pokemon/unown/z/front.4bpp.lz");
|
||||
const u32 gMonBackPic_UnownZ[] = INCBIN_U32("graphics/pokemon/unown/z/back.4bpp.lz");
|
||||
const u8 gMonIcon_UnownZ[] = INCBIN_U8("graphics/pokemon/unown/z/icon.4bpp");
|
||||
|
||||
const u32 gMonFrontPic_UnownExclamationMark[] = INCBIN_U32("graphics/pokemon/unown/exclamation_mark/anim_front.4bpp.lz");
|
||||
const u32 gMonFrontPic_UnownExclamationMark[] = INCBIN_U32("graphics/pokemon/unown/exclamation_mark/front.4bpp.lz");
|
||||
const u32 gMonBackPic_UnownExclamationMark[] = INCBIN_U32("graphics/pokemon/unown/exclamation_mark/back.4bpp.lz");
|
||||
const u8 gMonIcon_UnownExclamationMark[] = INCBIN_U8("graphics/pokemon/unown/exclamation_mark/icon.4bpp");
|
||||
|
||||
const u32 gMonFrontPic_UnownQuestionMark[] = INCBIN_U32("graphics/pokemon/unown/question_mark/anim_front.4bpp.lz");
|
||||
const u32 gMonFrontPic_UnownQuestionMark[] = INCBIN_U32("graphics/pokemon/unown/question_mark/front.4bpp.lz");
|
||||
const u32 gMonBackPic_UnownQuestionMark[] = INCBIN_U32("graphics/pokemon/unown/question_mark/back.4bpp.lz");
|
||||
const u8 gMonIcon_UnownQuestionMark[] = INCBIN_U8("graphics/pokemon/unown/question_mark/icon.4bpp");
|
||||
#endif //P_FAMILY_UNOWN
|
||||
|
||||
@ -3688,7 +3688,7 @@ const struct Item gItemsInfo[] =
|
||||
.name = _("Dubious Disc"),
|
||||
.price = (I_PRICE >= GEN_7) ? 2000 * TREASURE_FACTOR : 2100,
|
||||
.description = COMPOUND_STRING(
|
||||
"A transparent device\n"
|
||||
"A clear device\n"
|
||||
"overflowing with\n"
|
||||
"dubious data."),
|
||||
.pocket = POCKET_ITEMS,
|
||||
@ -9419,7 +9419,7 @@ const struct Item gItemsInfo[] =
|
||||
"Fires an icy cold\n"
|
||||
"beam that may\n"
|
||||
#if B_USE_FROSTBITE == TRUE
|
||||
"give the foe frostbite."),
|
||||
"inflict frostbite."),
|
||||
#else
|
||||
"freeze the foe."),
|
||||
#endif
|
||||
@ -9435,11 +9435,13 @@ const struct Item gItemsInfo[] =
|
||||
.name = _("TM14"),
|
||||
.price = 5500,
|
||||
.description = COMPOUND_STRING(
|
||||
#if B_USE_FROSTBITE == TRUE
|
||||
"A snow-and-wind\n"
|
||||
"attack that may\n"
|
||||
"inflict frostbite."),
|
||||
#else
|
||||
"A brutal snow-and-\n"
|
||||
"wind attack that\n"
|
||||
#if B_USE_FROSTBITE == TRUE
|
||||
"may give the foe frostbite."),
|
||||
#else
|
||||
"may freeze the foe."),
|
||||
#endif
|
||||
.importance = I_REUSABLE_TMS,
|
||||
|
||||
@ -1098,6 +1098,7 @@ static const struct FormChange sSandacondaFormChangeTable[] =
|
||||
static const struct FormChange sCramorantFormChangeTable[] = {
|
||||
{FORM_CHANGE_BATTLE_HP_PERCENT, SPECIES_CRAMORANT_GULPING, ABILITY_GULP_MISSILE, HP_HIGHER_THAN, 50},
|
||||
{FORM_CHANGE_BATTLE_HP_PERCENT, SPECIES_CRAMORANT_GORGING, ABILITY_GULP_MISSILE, HP_LOWER_EQ_THAN, 50},
|
||||
{FORM_CHANGE_HIT_BY_MOVE, SPECIES_CRAMORANT, ABILITY_GULP_MISSILE},
|
||||
{FORM_CHANGE_BATTLE_SWITCH, SPECIES_CRAMORANT},
|
||||
{FORM_CHANGE_FAINT, SPECIES_CRAMORANT},
|
||||
{FORM_CHANGE_END_BATTLE, SPECIES_CRAMORANT},
|
||||
|
||||
@ -12043,7 +12043,11 @@ const struct SpeciesInfo gSpeciesInfoGen1[] =
|
||||
.baseSpeed = 90,
|
||||
.baseSpAttack = 100,
|
||||
.baseSpDefense = 120,
|
||||
#if P_UPDATED_TYPES >= GEN_6
|
||||
.types = MON_TYPES(TYPE_PSYCHIC, TYPE_FAIRY),
|
||||
#else
|
||||
.types = MON_TYPES(TYPE_PSYCHIC),
|
||||
#endif
|
||||
.catchRate = 45,
|
||||
.expYield = (P_UPDATED_EXP_YIELDS >= GEN_5) ? 161 : 136,
|
||||
.evYield_SpDefense = 2,
|
||||
|
||||
@ -2894,13 +2894,7 @@ static const union AnimCmd sAnim_Mismagius_1[] =
|
||||
#endif //P_FAMILY_MISDREAVUS
|
||||
|
||||
#if P_FAMILY_UNOWN
|
||||
static const union AnimCmd sAnim_Unown_1[] =
|
||||
{
|
||||
ANIMCMD_FRAME(0, 30),
|
||||
ANIMCMD_FRAME(1, 30),
|
||||
ANIMCMD_FRAME(0, 1),
|
||||
ANIMCMD_END,
|
||||
};
|
||||
PLACEHOLDER_ANIM_SINGLE_FRAME(Unown);
|
||||
#endif //P_FAMILY_UNOWN
|
||||
|
||||
#if P_FAMILY_WOBBUFFET
|
||||
|
||||
@ -49,15 +49,26 @@ u32 GetSoftLevelCapExpValue(u32 level, u32 expValue)
|
||||
if (B_EXP_CAP_TYPE == EXP_CAP_NONE)
|
||||
return expValue;
|
||||
|
||||
if (B_LEVEL_CAP_EXP_UP && level < currentLevelCap)
|
||||
if (level < currentLevelCap)
|
||||
{
|
||||
levelDifference = currentLevelCap - level;
|
||||
if (levelDifference > ARRAY_COUNT(sExpScalingDown))
|
||||
return expValue + (expValue / sExpScalingUp[ARRAY_COUNT(sExpScalingDown) - 1]);
|
||||
if (B_LEVEL_CAP_EXP_UP)
|
||||
{
|
||||
levelDifference = currentLevelCap - level;
|
||||
if (levelDifference > ARRAY_COUNT(sExpScalingUp))
|
||||
return expValue + (expValue / sExpScalingUp[ARRAY_COUNT(sExpScalingUp) - 1]);
|
||||
else
|
||||
return expValue + (expValue / sExpScalingUp[levelDifference]);
|
||||
}
|
||||
else
|
||||
return expValue + (expValue / sExpScalingUp[levelDifference]);
|
||||
{
|
||||
return expValue;
|
||||
}
|
||||
}
|
||||
else if (B_EXP_CAP_TYPE == EXP_CAP_SOFT && level >= currentLevelCap)
|
||||
else if (B_EXP_CAP_TYPE == EXP_CAP_HARD)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (B_EXP_CAP_TYPE == EXP_CAP_SOFT)
|
||||
{
|
||||
levelDifference = level - currentLevelCap;
|
||||
if (levelDifference > ARRAY_COUNT(sExpScalingDown))
|
||||
@ -65,13 +76,8 @@ u32 GetSoftLevelCapExpValue(u32 level, u32 expValue)
|
||||
else
|
||||
return expValue / sExpScalingDown[levelDifference];
|
||||
}
|
||||
else if (level < currentLevelCap)
|
||||
else
|
||||
{
|
||||
return expValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -2532,6 +2532,7 @@ u32 GetBoxMonData3(struct BoxPokemon *boxMon, s32 field, u8 *data)
|
||||
case MON_DATA_EVOLUTION_TRACKER:
|
||||
evoTracker.asField.a = substruct1->evolutionTracker1;
|
||||
evoTracker.asField.b = substruct1->evolutionTracker2;
|
||||
evoTracker.asField.unused = 0;
|
||||
retVal = evoTracker.value;
|
||||
break;
|
||||
default:
|
||||
@ -3535,7 +3536,7 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 mov
|
||||
u16 species = GetMonData(mon, MON_DATA_SPECIES, NULL);
|
||||
dataUnsigned = sExpCandyExperienceTable[param - 1] + GetMonData(mon, MON_DATA_EXP, NULL);
|
||||
|
||||
if (B_RARE_CANDY_CAP && EXP_CAP_HARD)
|
||||
if (B_RARE_CANDY_CAP && B_EXP_CAP_TYPE == EXP_CAP_HARD)
|
||||
{
|
||||
u32 currentLevelCap = GetCurrentLevelCap();
|
||||
if (dataUnsigned > gExperienceTables[gSpeciesInfo[species].growthRate][currentLevelCap])
|
||||
|
||||
@ -329,7 +329,8 @@ void MultichoiceDynamic_DestroyStack(void)
|
||||
static void MultichoiceDynamic_MoveCursor(s32 itemIndex, bool8 onInit, struct ListMenu *list)
|
||||
{
|
||||
u8 taskId;
|
||||
PlaySE(SE_SELECT);
|
||||
if (!onInit)
|
||||
PlaySE(SE_SELECT);
|
||||
taskId = FindTaskIdByFunc(Task_HandleScrollingMultichoiceInput);
|
||||
if (taskId != TASK_NONE)
|
||||
{
|
||||
|
||||
@ -116,9 +116,7 @@ SINGLE_BATTLE_TEST("(Gulp Missile) Cramorant in Gorging paralyzes the target if
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("(Gulp Missile) triggers even if the user is fainted by opposing mon")
|
||||
{
|
||||
// See: https://github.com/rh-hideout/pokeemerald-expansion/issues/4143
|
||||
KNOWN_FAILING;
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_CRAMORANT) { HP(1); MaxHP(250); Ability(ABILITY_GULP_MISSILE); }
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
|
||||
@ -830,3 +830,55 @@ AI_SINGLE_BATTLE_TEST("AI will choose Surf over Thunderbolt and Ice Beam if the
|
||||
TURN { EXPECT_MOVE(opponent, MOVE_SURF); }
|
||||
}
|
||||
}
|
||||
|
||||
AI_SINGLE_BATTLE_TEST("AI will choose Scratch over Power-up Punch with Contrary")
|
||||
{
|
||||
u32 ability;
|
||||
|
||||
PARAMETRIZE {ability = ABILITY_SUCTION_CUPS; }
|
||||
PARAMETRIZE {ability = ABILITY_CONTRARY; }
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_SCRATCH].power == 40);
|
||||
ASSUME(gMovesInfo[MOVE_SCRATCH].type == TYPE_NORMAL);
|
||||
ASSUME(gMovesInfo[MOVE_POWER_UP_PUNCH].power == 40);
|
||||
ASSUME(gMovesInfo[MOVE_POWER_UP_PUNCH].type == TYPE_FIGHTING);
|
||||
ASSUME(gSpeciesInfo[SPECIES_SQUIRTLE].types[0] == TYPE_WATER);
|
||||
ASSUME(gSpeciesInfo[SPECIES_SQUIRTLE].types[1] == TYPE_WATER);
|
||||
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
|
||||
PLAYER(SPECIES_SQUIRTLE) { };
|
||||
OPPONENT(SPECIES_MALAMAR) { Ability(ability); Moves(MOVE_SCRATCH, MOVE_POWER_UP_PUNCH); }
|
||||
} WHEN {
|
||||
TURN {
|
||||
if (ability != ABILITY_CONTRARY)
|
||||
EXPECT_MOVE(opponent, MOVE_POWER_UP_PUNCH);
|
||||
else
|
||||
EXPECT_MOVE(opponent, MOVE_SCRATCH);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AI_SINGLE_BATTLE_TEST("AI will choose Superpower over Outrage with Contrary")
|
||||
{
|
||||
u32 ability;
|
||||
|
||||
PARAMETRIZE {ability = ABILITY_SUCTION_CUPS; }
|
||||
PARAMETRIZE {ability = ABILITY_CONTRARY; }
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_SUPERPOWER].power == 120);
|
||||
ASSUME(gMovesInfo[MOVE_SUPERPOWER].type == TYPE_FIGHTING);
|
||||
ASSUME(gMovesInfo[MOVE_OUTRAGE].power == 120);
|
||||
ASSUME(gMovesInfo[MOVE_OUTRAGE].type == TYPE_DRAGON);
|
||||
ASSUME(gSpeciesInfo[SPECIES_SQUIRTLE].types[0] == TYPE_WATER);
|
||||
ASSUME(gSpeciesInfo[SPECIES_SQUIRTLE].types[1] == TYPE_WATER);
|
||||
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
|
||||
PLAYER(SPECIES_SQUIRTLE) { };
|
||||
OPPONENT(SPECIES_MALAMAR) { Ability(ability); Moves(MOVE_OUTRAGE, MOVE_SUPERPOWER); }
|
||||
} WHEN {
|
||||
TURN {
|
||||
if (ability != ABILITY_CONTRARY)
|
||||
EXPECT_MOVE(opponent, MOVE_OUTRAGE);
|
||||
else
|
||||
EXPECT_MOVE(opponent, MOVE_SUPERPOWER);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -90,3 +90,17 @@ SINGLE_BATTLE_TEST("Belly Drum fails if the user's Attack is already at +6")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Belly Drum's HP cost doesn't trigger effects that trigger on damage taken")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_AIR_BALLOON); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_BELLY_DRUM); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_BELLY_DRUM, player);
|
||||
MESSAGE("Wobbuffet cut its own HP and maximized ATTACK!");
|
||||
NOT MESSAGE("Wobbuffet's Air Balloon popped!");
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,3 +56,19 @@ SINGLE_BATTLE_TEST("Fillet Away fails if user's current HP is half or less than
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Fillet Away's HP cost doesn't trigger effects that trigger on damage taken")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_AIR_BALLOON); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_FILLET_AWAY); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_FILLET_AWAY, player);
|
||||
MESSAGE("Wobbuffet's Attack sharply rose!");
|
||||
MESSAGE("Wobbuffet's Sp. Atk sharply rose!");
|
||||
MESSAGE("Wobbuffet's Speed sharply rose!");
|
||||
NOT MESSAGE("Wobbuffet's Air Balloon popped!");
|
||||
}
|
||||
}
|
||||
|
||||
@ -132,3 +132,24 @@ SINGLE_BATTLE_TEST("Future Sight will miss timing if target faints before it is
|
||||
NOT MESSAGE("Foe Wynaut took the Future Sight attack!");
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Future Sight will miss timing if target faints by residual damage")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET) { HP(10); }
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_FUTURE_SIGHT); }
|
||||
TURN { MOVE(player, MOVE_CELEBRATE); }
|
||||
TURN { MOVE(player, MOVE_WRAP); SEND_OUT(opponent, 1); }
|
||||
TURN { }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_FUTURE_SIGHT, player);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_WRAP, player);
|
||||
MESSAGE("Foe Wobbuffet fainted!");
|
||||
MESSAGE("2 sent out Wynaut!");
|
||||
NOT MESSAGE("Foe Wynaut took the Future Sight attack!");
|
||||
}
|
||||
}
|
||||
|
||||
@ -70,3 +70,18 @@ SINGLE_BATTLE_TEST("Shed Tail fails if there are no usable pokemon left")
|
||||
MESSAGE("But it failed!");
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Shed Tail's HP cost doesn't trigger effects that trigger on damage taken")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_AIR_BALLOON); }
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_SHED_TAIL); SEND_OUT(player, 1); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_SHED_TAIL, player);
|
||||
MESSAGE("Wobbuffet shed its tail to create a decoy!");
|
||||
NOT MESSAGE("Wobbuffet's Air Balloon popped!");
|
||||
}
|
||||
}
|
||||
|
||||
@ -54,3 +54,17 @@ SINGLE_BATTLE_TEST("Substitute's HP cost can trigger a berry")
|
||||
MESSAGE("Wobbuffet's Sitrus Berry restored health!");
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Substitute's HP cost doesn't trigger effects that trigger on damage taken")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_AIR_BALLOON); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_SUBSTITUTE); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_SUBSTITUTE, player);
|
||||
MESSAGE("Wobbuffet made a SUBSTITUTE!");
|
||||
NOT MESSAGE("Wobbuffet's Air Balloon popped!");
|
||||
}
|
||||
}
|
||||
|
||||