mirror of
https://github.com/Ninjdai1/pokeemerald.git
synced 2024-11-16 19:47:35 +01:00
Important battle util functions
This commit is contained in:
parent
b24427f3bf
commit
939127bfff
@ -473,8 +473,10 @@
|
||||
.word \jumpptr
|
||||
.endm
|
||||
|
||||
.macro nullsub_53
|
||||
.macro if_field_status flag jumpptr
|
||||
.byte 0x53
|
||||
.word \flag
|
||||
.word \jumpptr
|
||||
.endm
|
||||
|
||||
.macro nullsub_54
|
||||
|
@ -570,7 +570,7 @@ AI_CBM_Refresh: @ 82DC713
|
||||
end
|
||||
|
||||
AI_CBM_MudSport: @ 82DC71E
|
||||
if_status3 AI_USER, STATUS3_MUDSPORT, Score_Minus10
|
||||
if_field_status STATUS_FIELD_MUDSPORT, Score_Minus10
|
||||
end
|
||||
|
||||
AI_CBM_Tickle: @ 82DC729
|
||||
@ -589,7 +589,7 @@ AI_CBM_BulkUp: @ 82DC74B
|
||||
end
|
||||
|
||||
AI_CBM_WaterSport: @ 82DC75C
|
||||
if_status3 AI_USER, STATUS3_WATERSPORT, Score_Minus10
|
||||
if_field_status STATUS_FIELD_WATERSPORT, Score_Minus10
|
||||
end
|
||||
|
||||
AI_CBM_CalmMind: @ 82DC767
|
||||
|
@ -171,7 +171,8 @@ struct DisableStruct
|
||||
/*0x18*/ u8 unk18_a_2:2;
|
||||
/*0x18*/ u8 unk18_b:4;
|
||||
/*0x19*/ u8 rechargeCounter;
|
||||
/*0x1A*/ u8 unk1A[2];
|
||||
/*0x1A*/ u8 autonomizeCount;
|
||||
/*0x1B*/ u8 slowStartTimer;
|
||||
};
|
||||
|
||||
struct ProtectStruct
|
||||
@ -259,6 +260,7 @@ struct FieldTimer
|
||||
u8 mistyTerrainTimer;
|
||||
u8 electricTerrainTimer;
|
||||
u8 psychicTerrainTimer;
|
||||
u8 echoVoiceCounter;
|
||||
};
|
||||
|
||||
struct WishFutureKnock
|
||||
|
@ -72,5 +72,12 @@ void ClearFuryCutterDestinyBondGrudge(u8 battlerId);
|
||||
void HandleAction_RunBattleScript(void);
|
||||
u8 GetMoveTarget(u16 move, u8 setTarget);
|
||||
u8 IsMonDisobedient(void);
|
||||
u32 GetBattlerAbility(u8 battlerId);
|
||||
u32 GetBattlerHoldEffect(u8 battlerId, bool32 checkNegating);
|
||||
u32 GetBattlerHoldEffectParam(u8 battlerId);
|
||||
bool32 IsMoveMakingContact(u16 move, u8 battlerAtk);
|
||||
bool32 IsBattlerGrounded(u8 battlerId);
|
||||
u8 GetBattleMonMoveSlot(struct BattlePokemon *battleMon, u16 move);
|
||||
u32 GetBattlerWeight(u8 battlerId);
|
||||
|
||||
#endif // GUARD_BATTLE_UTIL_H
|
||||
|
@ -143,11 +143,14 @@
|
||||
#define STATUS3_IMPRISONED_OTHERS 0x2000
|
||||
#define STATUS3_GRUDGE 0x4000
|
||||
#define STATUS3_CANT_SCORE_A_CRIT 0x8000
|
||||
// #define STATUS3_MUDSPORT 0x10000
|
||||
// #define STATUS3_WATERSPORT 0x20000
|
||||
#define STATUS3_GASTRO_ACID 0x10000
|
||||
#define STATUS3_EMBARGO 0x20000
|
||||
#define STATUS3_UNDERWATER 0x40000
|
||||
#define STATUS3_INTIMIDATE_POKES 0x80000
|
||||
#define STATUS3_TRACE 0x100000
|
||||
#define STATUS3_SMACKED_DOWN 0x200000
|
||||
#define STATUS3_ME_FIRST 0x400000
|
||||
#define STATUS3_TELEKINESIS 0x800000
|
||||
#define STATUS3_SEMI_INVULNERABLE (STATUS3_UNDERGROUND | STATUS3_ON_AIR | STATUS3_UNDERWATER)
|
||||
|
||||
// Not really sure what a "hitmarker" is.
|
||||
|
@ -216,4 +216,29 @@
|
||||
#define EFFECT_DRAGON_DANCE 212
|
||||
#define EFFECT_CAMOUFLAGE 213
|
||||
|
||||
// New move effects
|
||||
#define EFFECT_PLEDGE 214
|
||||
#define EFFECT_FLING 215
|
||||
#define EFFECT_NATURAL_GIFT 216
|
||||
#define EFFECT_WAKE_UP_SLAP 217
|
||||
#define EFFECT_WRING_OUT 218
|
||||
#define EFFECT_HEX 219
|
||||
#define EFFECT_ASSURANCE 220
|
||||
#define EFFECT_TRUMP_CARD 221
|
||||
#define EFFECT_ACROBATICS 222
|
||||
#define EFFECT_HEAT_CRASH 223
|
||||
#define EFFECT_PUNISHMENT 224
|
||||
#define EFFECT_STORED_POWER 225
|
||||
#define EFFECT_ELECTRO_BALL 226
|
||||
#define EFFECT_GYRO_BALL 227
|
||||
#define EFFECT_ECHOED_VOICE 228
|
||||
#define EFFECT_PAYBACK 229
|
||||
#define EFFECT_ROUND 230
|
||||
#define EFFECT_BRINE 231
|
||||
#define EFFECT_VENOSHOCK 232
|
||||
#define EFFECT_RETALITATE 233
|
||||
#define EFFECT_BULLDOZE 234
|
||||
#define EFFECT_FOUL_PLAY 235
|
||||
#define EFFECT_PSYSHOCK 236
|
||||
|
||||
#endif // GUARD_CONSTANTS_BATTLE_MOVE_EFFECTS_H
|
||||
|
@ -97,5 +97,13 @@
|
||||
#define HOLD_EFFECT_DESTINY_KNOT 91
|
||||
#define HOLD_EFFECT_SHED_SHELL 92
|
||||
|
||||
// Gen5 hold effects
|
||||
#define HOLD_EFFECT_FLOAT_STONE 115
|
||||
|
||||
// Gen6 hold effects
|
||||
#define HOLD_EFFECT_FAIRY_POWER 130
|
||||
|
||||
// Gen7 hold effects
|
||||
#define HOLD_EFFECT_PROTECTIVE_PADS 150
|
||||
|
||||
#endif // GUARD_HOLD_EFFECTS_H
|
||||
|
@ -136,7 +136,7 @@ static void BattleAICmd_get_move_power_from_result(void);
|
||||
static void BattleAICmd_get_move_effect_from_result(void);
|
||||
static void BattleAICmd_get_protect_count(void);
|
||||
static void BattleAICmd_if_move_flag(void);
|
||||
static void BattleAICmd_nullsub_53(void);
|
||||
static void BattleAICmd_if_field_status(void);
|
||||
static void BattleAICmd_nullsub_54(void);
|
||||
static void BattleAICmd_nullsub_55(void);
|
||||
static void BattleAICmd_nullsub_56(void);
|
||||
@ -245,7 +245,7 @@ static const BattleAICmdFunc sBattleAICmdTable[] =
|
||||
BattleAICmd_get_move_effect_from_result, // 0x50
|
||||
BattleAICmd_get_protect_count, // 0x51
|
||||
BattleAICmd_if_move_flag, // 0x52
|
||||
BattleAICmd_nullsub_53, // 0x53
|
||||
BattleAICmd_if_field_status, // 0x53
|
||||
BattleAICmd_nullsub_54, // 0x54
|
||||
BattleAICmd_nullsub_55, // 0x55
|
||||
BattleAICmd_nullsub_56, // 0x56
|
||||
@ -2133,8 +2133,14 @@ static void BattleAICmd_if_move_flag(void)
|
||||
gAIScriptPtr += 7;
|
||||
}
|
||||
|
||||
static void BattleAICmd_nullsub_53(void)
|
||||
static void BattleAICmd_if_field_status(void)
|
||||
{
|
||||
u32 fieldFlags = T1_READ_32(gAIScriptPtr + 1);
|
||||
|
||||
if (gFieldStatuses & fieldFlags)
|
||||
gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 5);
|
||||
else
|
||||
gAIScriptPtr += 9;
|
||||
}
|
||||
|
||||
static void BattleAICmd_nullsub_54(void)
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "event_data.h"
|
||||
#include "link.h"
|
||||
#include "berry.h"
|
||||
#include "pokedex.h"
|
||||
|
||||
extern u8 weather_get_current(void);
|
||||
|
||||
@ -3369,3 +3370,237 @@ u8 IsMonDisobedient(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const u8 sAbilitiesAffectedByMoldBreaker[] =
|
||||
{
|
||||
[ABILITY_BATTLE_ARMOR] = 1,
|
||||
[ABILITY_CLEAR_BODY] = 1,
|
||||
[ABILITY_DAMP] = 1,
|
||||
[ABILITY_DRY_SKIN] = 1,
|
||||
[ABILITY_FILTER] = 1,
|
||||
[ABILITY_FLASH_FIRE] = 1,
|
||||
[ABILITY_FLOWER_GIFT] = 1,
|
||||
[ABILITY_HEATPROOF] = 1,
|
||||
[ABILITY_HYPER_CUTTER] = 1,
|
||||
[ABILITY_IMMUNITY] = 1,
|
||||
[ABILITY_INNER_FOCUS] = 1,
|
||||
[ABILITY_INSOMNIA] = 1,
|
||||
[ABILITY_KEEN_EYE] = 1,
|
||||
[ABILITY_LEAF_GUARD] = 1,
|
||||
[ABILITY_LEVITATE] = 1,
|
||||
[ABILITY_LIGHTNING_ROD] = 1,
|
||||
[ABILITY_LIMBER] = 1,
|
||||
[ABILITY_MAGMA_ARMOR] = 1,
|
||||
[ABILITY_MARVEL_SCALE] = 1,
|
||||
[ABILITY_MOTOR_DRIVE] = 1,
|
||||
[ABILITY_OBLIVIOUS] = 1,
|
||||
[ABILITY_OWN_TEMPO] = 1,
|
||||
[ABILITY_SAND_VEIL] = 1,
|
||||
[ABILITY_SHELL_ARMOR] = 1,
|
||||
[ABILITY_SHIELD_DUST] = 1,
|
||||
[ABILITY_SIMPLE] = 1,
|
||||
[ABILITY_SNOW_CLOAK] = 1,
|
||||
[ABILITY_SOLID_ROCK] = 1,
|
||||
[ABILITY_SOUNDPROOF] = 1,
|
||||
[ABILITY_STICKY_HOLD] = 1,
|
||||
[ABILITY_STORM_DRAIN] = 1,
|
||||
[ABILITY_STURDY] = 1,
|
||||
[ABILITY_SUCTION_CUPS] = 1,
|
||||
[ABILITY_TANGLED_FEET] = 1,
|
||||
[ABILITY_THICK_FAT] = 1,
|
||||
[ABILITY_UNAWARE] = 1,
|
||||
[ABILITY_VITAL_SPIRIT] = 1,
|
||||
[ABILITY_VOLT_ABSORB] = 1,
|
||||
[ABILITY_WATER_ABSORB] = 1,
|
||||
[ABILITY_WATER_VEIL] = 1,
|
||||
[ABILITY_WHITE_SMOKE] = 1,
|
||||
[ABILITY_WONDER_GUARD] = 1,
|
||||
[ABILITY_BIG_PECKS] = 1,
|
||||
[ABILITY_CONTRARY] = 1,
|
||||
[ABILITY_FRIEND_GUARD] = 1,
|
||||
[ABILITY_HEAVY_METAL] = 1,
|
||||
[ABILITY_LIGHT_METAL] = 1,
|
||||
[ABILITY_MAGIC_BOUNCE] = 1,
|
||||
[ABILITY_MULTISCALE] = 1,
|
||||
[ABILITY_SAP_SIPPER] = 1,
|
||||
[ABILITY_TELEPATHY] = 1,
|
||||
[ABILITY_WONDER_SKIN] = 1,
|
||||
[ABILITY_AROMA_VEIL] = 1,
|
||||
[ABILITY_BULLETPROOF] = 1,
|
||||
[ABILITY_FLOWER_VEIL] = 1,
|
||||
[ABILITY_FUR_COAT] = 1,
|
||||
[ABILITY_OVERCOAT] = 1,
|
||||
[ABILITY_SWEET_VEIL] = 1,
|
||||
[ABILITY_DAZZLING] = 1,
|
||||
[ABILITY_DISGUISE] = 1,
|
||||
[ABILITY_FLUFFY] = 1,
|
||||
[ABILITY_QUEENLY_MAJESTY] = 1,
|
||||
[ABILITY_WATER_BUBBLE] = 1,
|
||||
};
|
||||
|
||||
u32 GetBattlerAbility(u8 battlerId)
|
||||
{
|
||||
if (gStatuses3[battlerId] & STATUS3_GASTRO_ACID)
|
||||
return ABILITY_NONE;
|
||||
else if ((gBattleMons[gBattlerAttacker].ability == ABILITY_MOLD_BREAKER
|
||||
|| gBattleMons[gBattlerAttacker].ability == ABILITY_TERAVOLT
|
||||
|| gBattleMons[gBattlerAttacker].ability == ABILITY_TURBOBLAZE)
|
||||
&& sAbilitiesAffectedByMoldBreaker[gBattleMons[battlerId].ability]
|
||||
&& gBattlerByTurnOrder[gCurrentTurnActionNumber] == gBattlerAttacker
|
||||
&& gActionsByTurnOrder[gBattlerByTurnOrder[gBattlerAttacker]] == B_ACTION_USE_MOVE
|
||||
&& gCurrentTurnActionNumber < gBattlersCount
|
||||
&& !(gStatuses3[gBattlerAttacker] & STATUS3_GASTRO_ACID))
|
||||
return ABILITY_NONE;
|
||||
else
|
||||
return gBattleMons[battlerId].ability;
|
||||
}
|
||||
|
||||
u32 GetBattlerHoldEffect(u8 battlerId, bool32 checkNegating)
|
||||
{
|
||||
if (checkNegating)
|
||||
{
|
||||
if (gStatuses3[battlerId] & STATUS3_EMBARGO)
|
||||
return HOLD_EFFECT_NONE;
|
||||
if (gFieldStatuses & STATUS_FIELD_MAGIC_ROOM)
|
||||
return HOLD_EFFECT_NONE;
|
||||
if (gBattleMons[battlerId].ability == ABILITY_KLUTZ && !(gStatuses3[battlerId] & STATUS3_GASTRO_ACID))
|
||||
return HOLD_EFFECT_NONE;
|
||||
}
|
||||
|
||||
gPotentialItemEffectBattler = battlerId;
|
||||
|
||||
if (gBattleMons[battlerId].item == ITEM_ENIGMA_BERRY)
|
||||
return gEnigmaBerries[battlerId].holdEffect;
|
||||
else
|
||||
return ItemId_GetHoldEffect(gBattleMons[battlerId].item);
|
||||
}
|
||||
|
||||
u32 GetBattlerHoldEffectParam(u8 battlerId)
|
||||
{
|
||||
if (gBattleMons[battlerId].item == ITEM_ENIGMA_BERRY)
|
||||
return gEnigmaBerries[battlerId].holdEffectParam;
|
||||
else
|
||||
return ItemId_GetHoldEffectParam(gBattleMons[battlerId].item);
|
||||
}
|
||||
|
||||
bool32 IsMoveMakingContact(u16 move, u8 battlerAtk)
|
||||
{
|
||||
if (!(gBattleMoves[move].flags & FLAG_MAKES_CONTACT))
|
||||
return FALSE;
|
||||
else if (GetBattlerAbility(battlerAtk) == ABILITY_LONG_REACH)
|
||||
return FALSE;
|
||||
else if (GetBattlerHoldEffect(battlerAtk, TRUE) == HOLD_EFFECT_PROTECTIVE_PADS)
|
||||
return FALSE;
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool32 IsBattlerGrounded(u8 battlerId)
|
||||
{
|
||||
if (GetBattlerHoldEffect(battlerId, TRUE) == HOLD_EFFECT_IRON_BALL)
|
||||
return TRUE;
|
||||
else if (gFieldStatuses & STATUS_FIELD_GRAVITY)
|
||||
return TRUE;
|
||||
else if (gStatuses3[battlerId] & STATUS3_ROOTED)
|
||||
return TRUE;
|
||||
else if (gStatuses3[battlerId] & STATUS3_SMACKED_DOWN)
|
||||
return TRUE;
|
||||
|
||||
else if (gStatuses3[battlerId] & STATUS3_TELEKINESIS)
|
||||
return FALSE;
|
||||
else if (GetBattlerAbility(battlerId) == ABILITY_LEVITATE)
|
||||
return FALSE;
|
||||
else if (IS_BATTLER_OF_TYPE(battlerId, TYPE_FLYING))
|
||||
return FALSE;
|
||||
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool32 IsBattlerAlive(u8 battlerId)
|
||||
{
|
||||
if (gBattleMons[battlerId].hp == 0)
|
||||
return FALSE;
|
||||
else if (battlerId >= gBattlersCount)
|
||||
return FALSE;
|
||||
else if (gAbsentBattlerFlags & gBitTable[battlerId])
|
||||
return FALSE;
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
u8 GetBattleMonMoveSlot(struct BattlePokemon *battleMon, u16 move)
|
||||
{
|
||||
u8 i;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
if (battleMon->moves[i] == move)
|
||||
break;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
u32 GetBattlerWeight(u8 battlerId)
|
||||
{
|
||||
u32 weight = GetPokedexHeightWeight(SpeciesToNationalPokedexNum(gBattleMons[battlerId].species), 1);
|
||||
u32 ability = GetBattlerAbility(battlerId);
|
||||
u32 holdEffect = GetBattlerHoldEffect(battlerId, TRUE);
|
||||
|
||||
if (ability == ABILITY_HEAVY_METAL)
|
||||
weight *= 2;
|
||||
else if (ability == ABILITY_LIGHT_METAL)
|
||||
weight /= 2;
|
||||
|
||||
if (holdEffect == HOLD_EFFECT_FLOAT_STONE)
|
||||
weight /= 2;
|
||||
|
||||
if (gDisableStructs[battlerId].autonomizeCount)
|
||||
weight -= 1000 * gDisableStructs[battlerId].autonomizeCount;
|
||||
|
||||
if (weight == 0)
|
||||
weight = 1;
|
||||
|
||||
return weight;
|
||||
}
|
||||
|
||||
u32 CountBattlerStatIncreases(u8 battlerId, bool32 countEvasionAcc)
|
||||
{
|
||||
u32 i;
|
||||
u32 count = 0;
|
||||
|
||||
for (i = 0; i < BATTLE_STATS_NO; i++)
|
||||
{
|
||||
if ((i == STAT_ACC || i == STAT_EVASION) && !countEvasionAcc)
|
||||
continue;
|
||||
if (gBattleMons[battlerId].statStages[i] > 6) // Stat is increased.
|
||||
count += gBattleMons[battlerId].statStages[i] - 6;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
u32 GetMoveTargetCount(u16 move, u8 battlerAtk, u8 battlerDef)
|
||||
{
|
||||
switch (gBattleMoves[move].target)
|
||||
{
|
||||
case MOVE_TARGET_BOTH:
|
||||
return IsBattlerAlive(battlerDef)
|
||||
+ IsBattlerAlive(BATTLE_PARTNER(battlerDef));
|
||||
case MOVE_TARGET_FOES_AND_ALLY:
|
||||
return IsBattlerAlive(battlerDef)
|
||||
+ IsBattlerAlive(BATTLE_PARTNER(battlerDef))
|
||||
+ IsBattlerAlive(BATTLE_PARTNER(battlerAtk));
|
||||
case MOVE_TARGET_OPPONENTS_FIELD:
|
||||
return 1;
|
||||
case MOVE_TARGET_DEPENDS:
|
||||
case MOVE_TARGET_SELECTED:
|
||||
case MOVE_TARGET_RANDOM:
|
||||
case MOVE_TARGET_USER_OR_SELECTED:
|
||||
return IsBattlerAlive(battlerDef);
|
||||
case MOVE_TARGET_USER:
|
||||
return IsBattlerAlive(battlerAtk);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user