Set TYPE_NONE as type 0 + other type data tweaks (#4462)

* Set TYPE_MYSTERY as type 0

* Remove redundant TYPE_NONE

* Moved Gen 1-3 type damage categories to gTypesInfo

* Set TYPE_NONE as 0 instead

* Grouped type info to a single file

* Fixed sTypeEffectivenessTable static name

* Adjusted MON_DATA_TERA_TYPE to account for shift in type IDs

* oops, missed the extern

* Moved Tera Type RGB values to gTypesInfo

* Fixed Tera Type test

* Added option test feature to set IVs

* Hidden Power type test

* Tera Type safeguard in givemon

* Removed isHiddenPowerType for a future PR that refactors Hidden Power

* Review changes
This commit is contained in:
Eduardo Quezada 2024-06-01 01:38:22 -04:00 committed by GitHub
parent cb1b4bc9a0
commit 0be643a517
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
22 changed files with 729 additions and 458 deletions

BIN
graphics/types/none.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 215 B

View file

@ -22,7 +22,7 @@ STARTERGFXDIR := graphics/starter_choose
NAMINGGFXDIR := graphics/naming_screen NAMINGGFXDIR := graphics/naming_screen
SPINDAGFXDIR := graphics/pokemon/spinda/spots SPINDAGFXDIR := graphics/pokemon/spinda/spots
types := normal fight flying poison ground rock bug ghost steel mystery fire water grass electric psychic ice dragon dark fairy stellar types := none normal fight flying poison ground rock bug ghost steel mystery fire water grass electric psychic ice dragon dark fairy stellar
contest_types := cool beauty cute smart tough contest_types := cool beauty cute smart tough
### Tilesets ### ### Tilesets ###

View file

@ -77,6 +77,7 @@ extern const struct SpriteTemplate gUnusedBattleInitSprite;
extern const struct OamData gOamData_BattleSpriteOpponentSide; extern const struct OamData gOamData_BattleSpriteOpponentSide;
extern const struct OamData gOamData_BattleSpritePlayerSide; extern const struct OamData gOamData_BattleSpritePlayerSide;
extern const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES]; extern const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES];
extern const uq4_12_t gTypeEffectivenessTable[NUMBER_OF_MON_TYPES][NUMBER_OF_MON_TYPES];
extern const u8 gStatusConditionString_PoisonJpn[8]; extern const u8 gStatusConditionString_PoisonJpn[8];
extern const u8 gStatusConditionString_SleepJpn[8]; extern const u8 gStatusConditionString_SleepJpn[8];

View file

@ -43,7 +43,7 @@
#define B_GHOSTS_ESCAPE GEN_LATEST // In Gen6+, abilities like Shadow Tag or moves like Mean Look fail on Ghost-type Pokémon. They can also escape any Wild Battle. #define B_GHOSTS_ESCAPE GEN_LATEST // In Gen6+, abilities like Shadow Tag or moves like Mean Look fail on Ghost-type Pokémon. They can also escape any Wild Battle.
#define B_PARALYZE_ELECTRIC GEN_LATEST // In Gen6+, Electric-type Pokémon can't be paralyzed. #define B_PARALYZE_ELECTRIC GEN_LATEST // In Gen6+, Electric-type Pokémon can't be paralyzed.
#define B_POWDER_GRASS GEN_LATEST // In Gen6+, Grass-type Pokémon are immune to powder and spore moves. #define B_POWDER_GRASS GEN_LATEST // In Gen6+, Grass-type Pokémon are immune to powder and spore moves.
#define B_UPDATED_TYPE_MATCHUPS GEN_LATEST // Updates Type matchups. Refer to sTypeEffectivenessTable for details. #define B_UPDATED_TYPE_MATCHUPS GEN_LATEST // Updates Type matchups. src/data/types_info.h for details.
#define B_PRANKSTER_DARK_TYPES GEN_LATEST // In Gen7+, Prankster-elevated status moves do not affect Dark type Pokémon. #define B_PRANKSTER_DARK_TYPES GEN_LATEST // In Gen7+, Prankster-elevated status moves do not affect Dark type Pokémon.
#define B_SHEER_COLD_IMMUNITY GEN_LATEST // In Gen7+, Ice-types are immune to Sheer Cold #define B_SHEER_COLD_IMMUNITY GEN_LATEST // In Gen7+, Ice-types are immune to Sheer Cold
#define B_ROOST_PURE_FLYING GEN_LATEST // In Gen5+, Roost makes pure Flying-types into Normal-type. #define B_ROOST_PURE_FLYING GEN_LATEST // In Gen5+, Roost makes pure Flying-types into Normal-type.

View file

@ -2,28 +2,28 @@
#define GUARD_CONSTANTS_POKEMON_H #define GUARD_CONSTANTS_POKEMON_H
// Pokémon types // Pokémon types
#define TYPE_NONE 255 #define TYPE_NONE 0
#define TYPE_NORMAL 0 #define TYPE_NORMAL 1
#define TYPE_FIGHTING 1 #define TYPE_FIGHTING 2
#define TYPE_FLYING 2 #define TYPE_FLYING 3
#define TYPE_POISON 3 #define TYPE_POISON 4
#define TYPE_GROUND 4 #define TYPE_GROUND 5
#define TYPE_ROCK 5 #define TYPE_ROCK 6
#define TYPE_BUG 6 #define TYPE_BUG 7
#define TYPE_GHOST 7 #define TYPE_GHOST 8
#define TYPE_STEEL 8 #define TYPE_STEEL 9
#define TYPE_MYSTERY 9 #define TYPE_MYSTERY 10
#define TYPE_FIRE 10 #define TYPE_FIRE 11
#define TYPE_WATER 11 #define TYPE_WATER 12
#define TYPE_GRASS 12 #define TYPE_GRASS 13
#define TYPE_ELECTRIC 13 #define TYPE_ELECTRIC 14
#define TYPE_PSYCHIC 14 #define TYPE_PSYCHIC 15
#define TYPE_ICE 15 #define TYPE_ICE 16
#define TYPE_DRAGON 16 #define TYPE_DRAGON 17
#define TYPE_DARK 17 #define TYPE_DARK 18
#define TYPE_FAIRY 18 #define TYPE_FAIRY 19
#define TYPE_STELLAR 19 #define TYPE_STELLAR 20
#define NUMBER_OF_MON_TYPES 20 #define NUMBER_OF_MON_TYPES 21
// Pokémon egg groups // Pokémon egg groups
#define EGG_GROUP_NONE 0 #define EGG_GROUP_NONE 0

View file

@ -109,6 +109,9 @@ struct TypeInfo
u8 palette; u8 palette;
u16 zMove; u16 zMove;
u16 maxMove; u16 maxMove;
u16 teraTypeRGBValue; // Most values pulled from the Tera type icon palette.
u16 damageCategory:2; // Used for B_PHYSICAL_SPECIAL_SPLIT <= GEN_3
u16 padding:14;
const u32 *const paletteTMHM; const u32 *const paletteTMHM;
//u16 enhanceItem; //u16 enhanceItem;
//u16 berry; //u16 berry;

View file

@ -824,6 +824,12 @@ struct moveWithPP {
#define SpAttack(spAttack) SpAttack_(__LINE__, spAttack) #define SpAttack(spAttack) SpAttack_(__LINE__, spAttack)
#define SpDefense(spDefense) SpDefense_(__LINE__, spDefense) #define SpDefense(spDefense) SpDefense_(__LINE__, spDefense)
#define Speed(speed) Speed_(__LINE__, speed) #define Speed(speed) Speed_(__LINE__, speed)
#define HPIV(hpIV) HPIV_(__LINE__, hpIV)
#define AttackIV(attackIV) AttackIV_(__LINE__, attackIV)
#define DefenseIV(defenseIV) DefenseIV_(__LINE__, defenseIV)
#define SpAttackIV(spAttackIV) SpAttackIV_(__LINE__, spAttackIV)
#define SpDefenseIV(spDefenseIV) SpDefenseIV_(__LINE__, spDefenseIV)
#define SpeedIV(speedIV) SpeedIV_(__LINE__, speedIV)
#define Item(item) Item_(__LINE__, item) #define Item(item) Item_(__LINE__, item)
#define Moves(move1, ...) do { u16 moves_[MAX_MON_MOVES] = {move1, __VA_ARGS__}; Moves_(__LINE__, moves_); } while(0) #define Moves(move1, ...) do { u16 moves_[MAX_MON_MOVES] = {move1, __VA_ARGS__}; Moves_(__LINE__, moves_); } while(0)
#define MovesWithPP(movewithpp1, ...) MovesWithPP_(__LINE__, (struct moveWithPP[MAX_MON_MOVES]) {movewithpp1, __VA_ARGS__}) #define MovesWithPP(movewithpp1, ...) MovesWithPP_(__LINE__, (struct moveWithPP[MAX_MON_MOVES]) {movewithpp1, __VA_ARGS__})
@ -854,6 +860,12 @@ void Defense_(u32 sourceLine, u32 defense);
void SpAttack_(u32 sourceLine, u32 spAttack); void SpAttack_(u32 sourceLine, u32 spAttack);
void SpDefense_(u32 sourceLine, u32 spDefense); void SpDefense_(u32 sourceLine, u32 spDefense);
void Speed_(u32 sourceLine, u32 speed); void Speed_(u32 sourceLine, u32 speed);
void HPIV_(u32 sourceLine, u32 hpIV);
void AttackIV_(u32 sourceLine, u32 attackIV);
void DefenseIV_(u32 sourceLine, u32 defenseIV);
void SpAttackIV_(u32 sourceLine, u32 spAttackIV);
void SpDefenseIV_(u32 sourceLine, u32 spDefenseIV);
void SpeedIV_(u32 sourceLine, u32 speedIV);
void Item_(u32 sourceLine, u32 item); void Item_(u32 sourceLine, u32 item);
void Moves_(u32 sourceLine, u16 moves[MAX_MON_MOVES]); void Moves_(u32 sourceLine, u16 moves[MAX_MON_MOVES]);
void MovesWithPP_(u32 sourceLine, struct moveWithPP moveWithPP[MAX_MON_MOVES]); void MovesWithPP_(u32 sourceLine, struct moveWithPP moveWithPP[MAX_MON_MOVES]);

View file

@ -296,336 +296,7 @@ const struct OamData gOamData_BattleSpritePlayerSide =
static const s8 sCenterToCornerVecXs[8] ={-32, -16, -16, -32, -32}; static const s8 sCenterToCornerVecXs[8] ={-32, -16, -16, -32, -32};
#if B_EXPANDED_TYPE_NAMES == TRUE #include "data/types_info.h"
#define HANDLE_EXPANDED_TYPE_NAME(_name, ...) _(DEFAULT(_name, __VA_ARGS__))
#else
#define HANDLE_EXPANDED_TYPE_NAME(_name, ...) _(_name)
#endif
// .generic is large enough that the text for TYPE_ELECTRIC will exceed TEXT_BUFF_ARRAY_COUNT.
const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] =
{
[TYPE_NORMAL] =
{
.name = _("Normal"),
.generic = _("a NORMAL move"),
.palette = 13,
.zMove = MOVE_BREAKNECK_BLITZ,
.maxMove = MOVE_MAX_STRIKE,
.paletteTMHM = gItemIconPalette_NormalTMHM,
//.enhanceItem = ITEM_SILK_SCARF,
//.berry = ITEM_CHILAN_BERRY,
//.gem = ITEM_NORMAL_GEM,
//.zCrystal = ITEM_NORMALIUM_Z,
//.teraShard = ITEM_NORMAL_TERA_SHARD,
//.arceusForm = SPECIES_ARCEUS_NORMAL,
},
[TYPE_FIGHTING] =
{
.name = HANDLE_EXPANDED_TYPE_NAME("Fight", "Fighting"),
.generic = _("a FIGHTING move"),
.palette = 13,
.zMove = MOVE_ALL_OUT_PUMMELING,
.maxMove = MOVE_MAX_KNUCKLE,
.paletteTMHM = gItemIconPalette_FightingTMHM,
//.enhanceItem = ITEM_BLACK_BELT,
//.berry = ITEM_CHOPLE_BERRY,
//.gem = ITEM_FIGHTING_GEM,
//.zCrystal = ITEM_FIGHTINIUM_Z,
//.plate = ITEM_FIST_PLATE,
//.memory = ITEM_FIGHTING_MEMORY,
//.teraShard = ITEM_FIGHTING_TERA_SHARD,
//.arceusForm = SPECIES_ARCEUS_FIGHTING,
},
[TYPE_FLYING] =
{
.name = _("Flying"),
.generic = _("a FLYING move"),
.palette = 14,
.zMove = MOVE_SUPERSONIC_SKYSTRIKE,
.maxMove = MOVE_MAX_AIRSTREAM,
.paletteTMHM = gItemIconPalette_FlyingTMHM,
//.enhanceItem = ITEM_SHARP_BEAK,
//.berry = ITEM_COBA_BERRY,
//.gem = ITEM_FLYING_GEM,
//.zCrystal = ITEM_FLYINIUM_Z,
//.plate = ITEM_SKY_PLATE,
//.memory = ITEM_FLYING_MEMORY,
//.teraShard = ITEM_FLYING_TERA_SHARD,
//.arceusForm = SPECIES_ARCEUS_FLYING,
},
[TYPE_POISON] =
{
.name = _("Poison"),
.generic = _("a POISON move"),
.palette = 14,
.zMove = MOVE_ACID_DOWNPOUR,
.maxMove = MOVE_MAX_OOZE,
.paletteTMHM = gItemIconPalette_PoisonTMHM,
//.enhanceItem = ITEM_POISON_BARB,
//.berry = ITEM_KEBIA_BERRY,
//.gem = ITEM_POISON_GEM,
//.zCrystal = ITEM_POISONIUM_Z,
//.plate = ITEM_TOXIC_PLATE,
//.memory = ITEM_POISON_MEMORY,
//.teraShard = ITEM_POISON_TERA_SHARD,
//.arceusForm = SPECIES_ARCEUS_POISON,
},
[TYPE_GROUND] =
{
.name = _("Ground"),
.generic = _("a GROUND move"),
.palette = 13,
.zMove = MOVE_TECTONIC_RAGE,
.maxMove = MOVE_MAX_QUAKE,
.paletteTMHM = gItemIconPalette_GroundTMHM,
//.enhanceItem = ITEM_SOFT_SAND,
//.berry = ITEM_SHUCA_BERRY,
//.gem = ITEM_GROUND_GEM,
//.zCrystal = ITEM_GROUNDIUM_Z,
//.plate = ITEM_EARTH_PLATE,
//.memory = ITEM_GROUND_MEMORY,
//.teraShard = ITEM_GROUND_TERA_SHARD,
//.arceusForm = SPECIES_ARCEUS_GROUND,
},
[TYPE_ROCK] =
{
.name = _("Rock"),
.generic = _("a ROCK move"),
.palette = 13,
.zMove = MOVE_CONTINENTAL_CRUSH,
.maxMove = MOVE_MAX_ROCKFALL,
.paletteTMHM = gItemIconPalette_RockTMHM,
//.enhanceItem = ITEM_HARD_STONE,
//.berry = ITEM_CHARTI_BERRY,
//.gem = ITEM_ROCK_GEM,
//.zCrystal = ITEM_ROCKIUM_Z,
//.plate = ITEM_STONE_PLATE,
//.memory = ITEM_ROCK_MEMORY,
//.teraShard = ITEM_ROCK_TERA_SHARD,
//.arceusForm = SPECIES_ARCEUS_ROCK,
},
[TYPE_BUG] =
{
.name = _("Bug"),
.generic = _("a BUG move"),
.palette = 15,
.zMove = MOVE_SAVAGE_SPIN_OUT,
.maxMove = MOVE_MAX_FLUTTERBY,
.paletteTMHM = gItemIconPalette_BugTMHM,
//.enhanceItem = ITEM_SILVER_POWDER,
//.berry = ITEM_TANGA_BERRY,
//.gem = ITEM_BUG_GEM,
//.zCrystal = ITEM_BUGINIUM_Z,
//.plate = ITEM_INSECT_PLATE,
//.memory = ITEM_BUG_MEMORY,
//.teraShard = ITEM_BUG_TERA_SHARD,
//.arceusForm = SPECIES_ARCEUS_BUG,
},
[TYPE_GHOST] =
{
.name = _("Ghost"),
.generic = _("a GHOST move"),
.palette = 14,
.zMove = MOVE_NEVER_ENDING_NIGHTMARE,
.maxMove = MOVE_MAX_PHANTASM,
.paletteTMHM = gItemIconPalette_GhostTMHM,
//.enhanceItem = ITEM_SPELL_TAG,
//.berry = ITEM_KASIB_BERRY,
//.gem = ITEM_GHOST_GEM,
//.zCrystal = ITEM_GHOSTIUM_Z,
//.plate = ITEM_SPOOKY_PLATE,
//.memory = ITEM_GHOST_MEMORY,
//.teraShard = ITEM_GHOST_TERA_SHARD,
//.arceusForm = SPECIES_ARCEUS_GHOST,
},
[TYPE_STEEL] =
{
.name = _("Steel"),
.generic = _("a STEEL move"),
.palette = 13,
.zMove = MOVE_CORKSCREW_CRASH,
.maxMove = MOVE_MAX_STEELSPIKE,
.paletteTMHM = gItemIconPalette_SteelTMHM,
//.enhanceItem = ITEM_METAL_COAT,
//.berry = ITEM_BABIRI_BERRY,
//.gem = ITEM_STEEL_GEM,
//.zCrystal = ITEM_STEELIUM_Z,
//.plate = ITEM_IRON_PLATE,
//.memory = ITEM_STEEL_MEMORY,
//.teraShard = ITEM_STEEL_TERA_SHARD,
//.arceusForm = SPECIES_ARCEUS_STEEL,
},
[TYPE_MYSTERY] =
{
.name = _("???"),
.generic = _("a ??? move"),
.palette = 15,
},
[TYPE_FIRE] =
{
.name = _("Fire"),
.generic = _("a FIRE move"),
.palette = 13,
.zMove = MOVE_INFERNO_OVERDRIVE,
.maxMove = MOVE_MAX_FLARE,
.paletteTMHM = gItemIconPalette_FireTMHM,
//.enhanceItem = ITEM_CHARCOAL,
//.berry = ITEM_OCCA_BERRY,
//.gem = ITEM_FIRE_GEM,
//.zCrystal = ITEM_FIRIUM_Z,
//.plate = ITEM_FLAME_PLATE,
//.memory = ITEM_FIRE_MEMORY,
//.teraShard = ITEM_FIRE_TERA_SHARD,
//.arceusForm = SPECIES_ARCEUS_FIRE,
},
[TYPE_WATER] =
{
.name = _("Water"),
.generic = _("a WATER move"),
.palette = 14,
.zMove = MOVE_HYDRO_VORTEX,
.maxMove = MOVE_MAX_GEYSER,
.paletteTMHM = gItemIconPalette_WaterTMHM,
//.enhanceItem = ITEM_MYSTIC_WATER,
//.berry = ITEM_PASSHO_BERRY,
//.gem = ITEM_WATER_GEM,
//.zCrystal = ITEM_WATERIUM_Z,
//.plate = ITEM_SPLASH_PLATE,
//.memory = ITEM_WATER_MEMORY,
//.teraShard = ITEM_WATER_TERA_SHARD,
//.arceusForm = SPECIES_ARCEUS_WATER,
},
[TYPE_GRASS] =
{
.name = _("Grass"),
.generic = _("a GRASS move"),
.palette = 15,
.zMove = MOVE_BLOOM_DOOM,
.maxMove = MOVE_MAX_OVERGROWTH,
.paletteTMHM = gItemIconPalette_GrassTMHM,
//.enhanceItem = ITEM_MIRACLE_SEED,
//.berry = ITEM_RINDO_BERRY,
//.gem = ITEM_GRASS_GEM,
//.zCrystal = ITEM_GRASSIUM_Z,
//.plate = ITEM_MEADOW_PLATE,
//.memory = ITEM_GRASS_MEMORY,
//.teraShard = ITEM_GRASS_TERA_SHARD,
//.arceusForm = SPECIES_ARCEUS_GRASS,
},
[TYPE_ELECTRIC] =
{
.name = HANDLE_EXPANDED_TYPE_NAME("Electr", "Electric"),
.generic = _("an ELECTRIC move"),
.palette = 13,
.zMove = MOVE_GIGAVOLT_HAVOC,
.maxMove = MOVE_MAX_LIGHTNING,
.paletteTMHM = gItemIconPalette_ElectricTMHM,
//.enhanceItem = ITEM_MAGNET,
//.berry = ITEM_WACAN_BERRY,
//.gem = ITEM_ELECTRIC_GEM,
//.zCrystal = ITEM_ELECTRIUM_Z,
//.plate = ITEM_ZAP_PLATE,
//.memory = ITEM_ELECTRIC_MEMORY,
//.teraShard = ITEM_ELECTRIC_TERA_SHARD,
//.arceusForm = SPECIES_ARCEUS_ELECTRIC,
},
[TYPE_PSYCHIC] =
{
.name = HANDLE_EXPANDED_TYPE_NAME("Psychc", "Psychic"),
.generic = _("a PSYCHIC move"),
.palette = 14,
.zMove = MOVE_SHATTERED_PSYCHE,
.maxMove = MOVE_MAX_MINDSTORM,
.paletteTMHM = gItemIconPalette_PsychicTMHM,
//.enhanceItem = ITEM_TWISTED_SPOON,
//.berry = ITEM_PAYAPA_BERRY,
//.gem = ITEM_PSYCHIC_GEM,
//.zCrystal = ITEM_PSYCHIUM_Z,
//.plate = ITEM_MIND_PLATE,
//.memory = ITEM_PSYCHIC_MEMORY,
//.teraShard = ITEM_PSYCHIC_TERA_SHARD,
//.arceusForm = SPECIES_ARCEUS_PSYCHIC,
},
[TYPE_ICE] =
{
.name = _("Ice"),
.generic = _("an ICE move"),
.palette = 14,
.zMove = MOVE_SUBZERO_SLAMMER,
.maxMove = MOVE_MAX_HAILSTORM,
.paletteTMHM = gItemIconPalette_IceTMHM,
//.enhanceItem = ITEM_NEVER_MELT_ICE,
//.berry = ITEM_YACHE_BERRY,
//.gem = ITEM_ICE_GEM,
//.zCrystal = ITEM_ICIUM_Z,
//.plate = ITEM_ICICLE_PLATE,
//.memory = ITEM_ICE_MEMORY,
//.teraShard = ITEM_ICE_TERA_SHARD,
//.arceusForm = SPECIES_ARCEUS_ICE,
},
[TYPE_DRAGON] =
{
.name = _("Dragon"),
.generic = _("a DRAGON move"),
.palette = 15,
.zMove = MOVE_DEVASTATING_DRAKE,
.maxMove = MOVE_MAX_WYRMWIND,
.paletteTMHM = gItemIconPalette_DragonTMHM,
//.enhanceItem = ITEM_DRAGON_FANG,
//.berry = ITEM_HABAN_BERRY,
//.gem = ITEM_DRAGON_GEM,
//.zCrystal = ITEM_DRAGONIUM_Z,
//.plate = ITEM_DRACO_PLATE,
//.memory = ITEM_DRAGON_MEMORY,
//.teraShard = ITEM_DRAGON_TERA_SHARD,
//.arceusForm = SPECIES_ARCEUS_DRAGON,
},
[TYPE_DARK] =
{
.name = _("Dark"),
.generic = _("a DARK move"),
.palette = 13,
.zMove = MOVE_BLACK_HOLE_ECLIPSE,
.maxMove = MOVE_MAX_DARKNESS,
.paletteTMHM = gItemIconPalette_DarkTMHM,
//.enhanceItem = ITEM_BLACK_GLASSES,
//.berry = ITEM_COLBUR_BERRY,
//.gem = ITEM_DARK_GEM,
//.zCrystal = ITEM_DARKINIUM_Z,
//.plate = ITEM_DREAD_PLATE,
//.memory = ITEM_DARK_MEMORY,
//.teraShard = ITEM_DARK_TERA_SHARD,
//.arceusForm = SPECIES_ARCEUS_DARK,
},
[TYPE_FAIRY] =
{
.name = _("Fairy"),
.generic = _("a FAIRY move"),
.palette = 14,
.zMove = MOVE_TWINKLE_TACKLE,
.maxMove = MOVE_MAX_STARFALL,
.paletteTMHM = gItemIconPalette_FairyTMHM,
//.enhanceItem = ITEM_FAIRY_FEATHER,
//.berry = ITEM_ROSELI_BERRY,
//.gem = ITEM_FAIRY_GEM,
//.zCrystal = ITEM_FAIRIUM_Z,
//.plate = ITEM_PIXIE_PLATE,
//.memory = ITEM_FAIRY_MEMORY,
//.teraShard = ITEM_FAIRY_TERA_SHARD,
//.arceusForm = SPECIES_ARCEUS_FAIRY,
},
[TYPE_STELLAR] =
{
.name = HANDLE_EXPANDED_TYPE_NAME("Stellr", "Stellar"),
.generic = _("a STELLAR move"),
.palette = 15,
.zMove = MOVE_BREAKNECK_BLITZ,
.maxMove = MOVE_MAX_STRIKE,
.paletteTMHM = gItemIconPalette_NormalTMHM, // failsafe
// .teraShard = ITEM_STELLAR_TERA_SHARD,
},
};
// extra args are money and ball // extra args are money and ball
#define TRAINER_CLASS(trainerClass, trainerName, ...) \ #define TRAINER_CLASS(trainerClass, trainerName, ...) \
@ -6066,9 +5737,9 @@ void SetTypeBeforeUsingMove(u32 move, u32 battlerAtk)
| ((gBattleMons[battlerAtk].spAttackIV & 1) << 4) | ((gBattleMons[battlerAtk].spAttackIV & 1) << 4)
| ((gBattleMons[battlerAtk].spDefenseIV & 1) << 5); | ((gBattleMons[battlerAtk].spDefenseIV & 1) << 5);
// Subtract 4 instead of 1 below because 3 types are excluded (TYPE_NORMAL and TYPE_MYSTERY and TYPE_FAIRY) // Subtract 6 instead of 1 below because 5 types are excluded (TYPE_NONE, TYPE_NORMAL, TYPE_MYSTERY, TYPE_FAIRY and TYPE_STELLAR)
// The final + 1 skips past Normal, and the following conditional skips TYPE_MYSTERY // The final + 2 skips past TYPE_NONE and Normal.
gBattleStruct->dynamicMoveType = ((NUMBER_OF_MON_TYPES - 4) * typeBits) / 63 + 1; gBattleStruct->dynamicMoveType = ((NUMBER_OF_MON_TYPES - 6) * typeBits) / 63 + 2;
if (gBattleStruct->dynamicMoveType >= TYPE_MYSTERY) if (gBattleStruct->dynamicMoveType >= TYPE_MYSTERY)
gBattleStruct->dynamicMoveType++; gBattleStruct->dynamicMoveType++;
gBattleStruct->dynamicMoveType |= F_DYNAMIC_TYPE_IGNORE_PHYSICALITY | F_DYNAMIC_TYPE_SET; gBattleStruct->dynamicMoveType |= F_DYNAMIC_TYPE_IGNORE_PHYSICALITY | F_DYNAMIC_TYPE_SET;

View file

@ -169,33 +169,9 @@ uq4_12_t GetTeraMultiplier(u32 battler, u32 type)
} }
} }
// Most values pulled from the Tera type icon palette.
const u16 sTeraTypeRGBValues[NUMBER_OF_MON_TYPES] = {
[TYPE_NORMAL] = RGB_WHITE, // custom
[TYPE_FIGHTING] = RGB(26, 8, 14),
[TYPE_FLYING] = RGB(31, 26, 7),
[TYPE_POISON] = RGB(26, 10, 25), // custom
[TYPE_GROUND] = RGB(25, 23, 18),
[TYPE_ROCK] = RGB(18, 16, 8), // custom
[TYPE_BUG] = RGB(18, 24, 6),
[TYPE_GHOST] = RGB(12, 10, 16),
[TYPE_STEEL] = RGB(19, 19, 20),
[TYPE_MYSTERY] = RGB_WHITE,
[TYPE_FIRE] = RGB(31, 20, 11),
[TYPE_WATER] = RGB(10, 18, 27),
[TYPE_GRASS] = RGB(12, 24, 11),
[TYPE_ELECTRIC] = RGB(30, 26, 7),
[TYPE_PSYCHIC] = RGB(31, 14, 15),
[TYPE_ICE] = RGB(14, 26, 25),
[TYPE_DRAGON] = RGB(10, 18, 27),
[TYPE_DARK] = RGB(6, 5, 8),
[TYPE_FAIRY] = RGB(31, 15, 21),
[TYPE_STELLAR] = RGB(10, 18, 27),
};
u16 GetTeraTypeRGB(u32 type) u16 GetTeraTypeRGB(u32 type)
{ {
return sTeraTypeRGBValues[type]; return gTypesInfo[type].teraTypeRGBValue;
} }
// TERASTAL TRIGGER: // TERASTAL TRIGGER:
@ -636,6 +612,7 @@ static const struct SpriteTemplate sSpriteTemplate_StellarIndicator =
static const struct SpriteSheet sTeraIndicatorSpriteSheets[NUMBER_OF_MON_TYPES + 1] = static const struct SpriteSheet sTeraIndicatorSpriteSheets[NUMBER_OF_MON_TYPES + 1] =
{ {
{sNormalIndicatorGfx, sizeof(sNormalIndicatorGfx), TAG_NORMAL_INDICATOR_TILE}, // TYPE_NONE
{sNormalIndicatorGfx, sizeof(sNormalIndicatorGfx), TAG_NORMAL_INDICATOR_TILE}, {sNormalIndicatorGfx, sizeof(sNormalIndicatorGfx), TAG_NORMAL_INDICATOR_TILE},
{sFightingIndicatorGfx, sizeof(sFightingIndicatorGfx), TAG_FIGHTING_INDICATOR_TILE}, {sFightingIndicatorGfx, sizeof(sFightingIndicatorGfx), TAG_FIGHTING_INDICATOR_TILE},
{sFlyingIndicatorGfx, sizeof(sFlyingIndicatorGfx), TAG_FLYING_INDICATOR_TILE}, {sFlyingIndicatorGfx, sizeof(sFlyingIndicatorGfx), TAG_FLYING_INDICATOR_TILE},
@ -661,6 +638,7 @@ static const struct SpriteSheet sTeraIndicatorSpriteSheets[NUMBER_OF_MON_TYPES +
static const struct SpriteTemplate * const sTeraIndicatorSpriteTemplates[NUMBER_OF_MON_TYPES] = static const struct SpriteTemplate * const sTeraIndicatorSpriteTemplates[NUMBER_OF_MON_TYPES] =
{ {
[TYPE_NONE] = &sSpriteTemplate_NormalIndicator, // just in case
[TYPE_NORMAL] = &sSpriteTemplate_NormalIndicator, [TYPE_NORMAL] = &sSpriteTemplate_NormalIndicator,
[TYPE_FIGHTING] = &sSpriteTemplate_FightingIndicator, [TYPE_FIGHTING] = &sSpriteTemplate_FightingIndicator,
[TYPE_FLYING] = &sSpriteTemplate_FlyingIndicator, [TYPE_FLYING] = &sSpriteTemplate_FlyingIndicator,

View file

@ -903,44 +903,6 @@ static const uq4_12_t sPercentToModifier[] =
UQ_4_12(1.00), // 100 UQ_4_12(1.00), // 100
}; };
#define X UQ_4_12
#define ______ X(1.0) // Regular effectiveness.
// Type matchup updates. Attacker Defender
#define STL_RS (B_UPDATED_TYPE_MATCHUPS >= GEN_6 ? X(1.0) : X(0.5)) // Ghost/Dark -> Steel
#define PSN_RS (B_UPDATED_TYPE_MATCHUPS >= GEN_2 ? X(0.5) : X(2.0)) // Bug -> Poison
#define BUG_RS (B_UPDATED_TYPE_MATCHUPS >= GEN_2 ? X(1.0) : X(2.0)) // Poison -> Bug
#define PSY_RS (B_UPDATED_TYPE_MATCHUPS >= GEN_2 ? X(2.0) : X(0.0)) // Ghost -> Psychic
#define FIR_RS (B_UPDATED_TYPE_MATCHUPS >= GEN_2 ? X(0.5) : X(1.0)) // Ice -> Fire
static const uq4_12_t sTypeEffectivenessTable[NUMBER_OF_MON_TYPES][NUMBER_OF_MON_TYPES] =
{// Defender -->
// Attacker Normal Fighting Flying Poison Ground Rock Bug Ghost Steel Mystery Fire Water Grass Electric Psychic Ice Dragon Dark Fairy Stellar
[TYPE_NORMAL] = {______, ______, ______, ______, ______, X(0.5), ______, X(0.0), X(0.5), ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______},
[TYPE_FIGHTING] = {X(2.0), ______, X(0.5), X(0.5), ______, X(2.0), X(0.5), X(0.0), X(2.0), ______, ______, ______, ______, ______, X(0.5), X(2.0), ______, X(2.0), X(0.5), ______},
[TYPE_FLYING] = {______, X(2.0), ______, ______, ______, X(0.5), X(2.0), ______, X(0.5), ______, ______, ______, X(2.0), X(0.5), ______, ______, ______, ______, ______, ______},
[TYPE_POISON] = {______, ______, ______, X(0.5), X(0.5), X(0.5), BUG_RS, X(0.5), X(0.0), ______, ______, ______, X(2.0), ______, ______, ______, ______, ______, X(2.0), ______},
[TYPE_GROUND] = {______, ______, X(0.0), X(2.0), ______, X(2.0), X(0.5), ______, X(2.0), ______, X(2.0), ______, X(0.5), X(2.0), ______, ______, ______, ______, ______, ______},
[TYPE_ROCK] = {______, X(0.5), X(2.0), ______, X(0.5), ______, X(2.0), ______, X(0.5), ______, X(2.0), ______, ______, ______, ______, X(2.0), ______, ______, ______, ______},
[TYPE_BUG] = {______, X(0.5), X(0.5), PSN_RS, ______, ______, ______, X(0.5), X(0.5), ______, X(0.5), ______, X(2.0), ______, X(2.0), ______, ______, X(2.0), X(0.5), ______},
[TYPE_GHOST] = {X(0.0), ______, ______, ______, ______, ______, ______, X(2.0), STL_RS, ______, ______, ______, ______, ______, PSY_RS, ______, ______, X(0.5), ______, ______},
[TYPE_STEEL] = {______, ______, ______, ______, ______, X(2.0), ______, ______, X(0.5), ______, X(0.5), X(0.5), ______, X(0.5), ______, X(2.0), ______, ______, X(2.0), ______},
[TYPE_MYSTERY] = {______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______},
[TYPE_FIRE] = {______, ______, ______, ______, ______, X(0.5), X(2.0), ______, X(2.0), ______, X(0.5), X(0.5), X(2.0), ______, ______, X(2.0), X(0.5), ______, ______, ______},
[TYPE_WATER] = {______, ______, ______, ______, X(2.0), X(2.0), ______, ______, ______, ______, X(2.0), X(0.5), X(0.5), ______, ______, ______, X(0.5), ______, ______, ______},
[TYPE_GRASS] = {______, ______, X(0.5), X(0.5), X(2.0), X(2.0), X(0.5), ______, X(0.5), ______, X(0.5), X(2.0), X(0.5), ______, ______, ______, X(0.5), ______, ______, ______},
[TYPE_ELECTRIC] = {______, ______, X(2.0), ______, X(0.0), ______, ______, ______, ______, ______, ______, X(2.0), X(0.5), X(0.5), ______, ______, X(0.5), ______, ______, ______},
[TYPE_PSYCHIC] = {______, X(2.0), ______, X(2.0), ______, ______, ______, ______, X(0.5), ______, ______, ______, ______, ______, X(0.5), ______, ______, X(0.0), ______, ______},
[TYPE_ICE] = {______, ______, X(2.0), ______, X(2.0), ______, ______, ______, X(0.5), ______, FIR_RS, X(0.5), X(2.0), ______, ______, X(0.5), X(2.0), ______, ______, ______},
[TYPE_DRAGON] = {______, ______, ______, ______, ______, ______, ______, ______, X(0.5), ______, ______, ______, ______, ______, ______, ______, X(2.0), ______, X(0.0), ______},
[TYPE_DARK] = {______, X(0.5), ______, ______, ______, ______, ______, X(2.0), STL_RS, ______, ______, ______, ______, ______, X(2.0), ______, ______, X(0.5), X(0.5), ______},
[TYPE_FAIRY] = {______, X(2.0), ______, X(0.5), ______, ______, ______, ______, X(0.5), ______, X(0.5), ______, ______, ______, ______, ______, X(2.0), X(2.0), ______, ______},
[TYPE_STELLAR] = {______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______},
};
#undef ______
#undef X
// code // code
u8 GetBattlerForBattleScript(u8 caseId) u8 GetBattlerForBattleScript(u8 caseId)
{ {
@ -10367,8 +10329,8 @@ static uq4_12_t GetInverseTypeMultiplier(uq4_12_t multiplier)
uq4_12_t GetTypeModifier(u32 atkType, u32 defType) uq4_12_t GetTypeModifier(u32 atkType, u32 defType)
{ {
if (B_FLAG_INVERSE_BATTLE != 0 && FlagGet(B_FLAG_INVERSE_BATTLE)) if (B_FLAG_INVERSE_BATTLE != 0 && FlagGet(B_FLAG_INVERSE_BATTLE))
return GetInverseTypeMultiplier(sTypeEffectivenessTable[atkType][defType]); return GetInverseTypeMultiplier(gTypeEffectivenessTable[atkType][defType]);
return sTypeEffectivenessTable[atkType][defType]; return gTypeEffectivenessTable[atkType][defType];
} }
s32 GetStealthHazardDamageByTypesAndHP(u8 hazardType, u8 type1, u8 type2, u32 maxHp) s32 GetStealthHazardDamageByTypesAndHP(u8 hazardType, u8 type1, u8 type2, u32 maxHp)
@ -10912,10 +10874,8 @@ u8 GetBattleMoveCategory(u32 moveId)
if (IS_MOVE_STATUS(moveId)) if (IS_MOVE_STATUS(moveId))
return DAMAGE_CATEGORY_STATUS; return DAMAGE_CATEGORY_STATUS;
else if (gMovesInfo[moveId].type < TYPE_MYSTERY)
return DAMAGE_CATEGORY_PHYSICAL;
else else
return DAMAGE_CATEGORY_SPECIAL; return gTypesInfo[gMovesInfo[moveId].type].damageCategory;
} }
static bool32 TryRemoveScreens(u32 battler) static bool32 TryRemoveScreens(u32 battler)

423
src/data/types_info.h Normal file
View file

@ -0,0 +1,423 @@
#include "constants/battle.h"
#include "constants/pokemon.h"
#define X UQ_4_12
#define ______ X(1.0) // Regular effectiveness.
// Type matchup updates. Attacker Defender
#define STL_RS (B_UPDATED_TYPE_MATCHUPS >= GEN_6 ? X(1.0) : X(0.5)) // Ghost/Dark -> Steel
#define PSN_RS (B_UPDATED_TYPE_MATCHUPS >= GEN_2 ? X(0.5) : X(2.0)) // Bug -> Poison
#define BUG_RS (B_UPDATED_TYPE_MATCHUPS >= GEN_2 ? X(1.0) : X(2.0)) // Poison -> Bug
#define PSY_RS (B_UPDATED_TYPE_MATCHUPS >= GEN_2 ? X(2.0) : X(0.0)) // Ghost -> Psychic
#define FIR_RS (B_UPDATED_TYPE_MATCHUPS >= GEN_2 ? X(0.5) : X(1.0)) // Ice -> Fire
const uq4_12_t gTypeEffectivenessTable[NUMBER_OF_MON_TYPES][NUMBER_OF_MON_TYPES] =
{// Defender -->
// Attacker None Normal Fighting Flying Poison Ground Rock Bug Ghost Steel Mystery Fire Water Grass Electric Psychic Ice Dragon Dark Fairy Stellar
[TYPE_NONE] = {______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______},
[TYPE_NORMAL] = {______, ______, ______, ______, ______, ______, X(0.5), ______, X(0.0), X(0.5), ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______},
[TYPE_FIGHTING] = {______, X(2.0), ______, X(0.5), X(0.5), ______, X(2.0), X(0.5), X(0.0), X(2.0), ______, ______, ______, ______, ______, X(0.5), X(2.0), ______, X(2.0), X(0.5), ______},
[TYPE_FLYING] = {______, ______, X(2.0), ______, ______, ______, X(0.5), X(2.0), ______, X(0.5), ______, ______, ______, X(2.0), X(0.5), ______, ______, ______, ______, ______, ______},
[TYPE_POISON] = {______, ______, ______, ______, X(0.5), X(0.5), X(0.5), BUG_RS, X(0.5), X(0.0), ______, ______, ______, X(2.0), ______, ______, ______, ______, ______, X(2.0), ______},
[TYPE_GROUND] = {______, ______, ______, X(0.0), X(2.0), ______, X(2.0), X(0.5), ______, X(2.0), ______, X(2.0), ______, X(0.5), X(2.0), ______, ______, ______, ______, ______, ______},
[TYPE_ROCK] = {______, ______, X(0.5), X(2.0), ______, X(0.5), ______, X(2.0), ______, X(0.5), ______, X(2.0), ______, ______, ______, ______, X(2.0), ______, ______, ______, ______},
[TYPE_BUG] = {______, ______, X(0.5), X(0.5), PSN_RS, ______, ______, ______, X(0.5), X(0.5), ______, X(0.5), ______, X(2.0), ______, X(2.0), ______, ______, X(2.0), X(0.5), ______},
[TYPE_GHOST] = {______, X(0.0), ______, ______, ______, ______, ______, ______, X(2.0), STL_RS, ______, ______, ______, ______, ______, PSY_RS, ______, ______, X(0.5), ______, ______},
[TYPE_STEEL] = {______, ______, ______, ______, ______, ______, X(2.0), ______, ______, X(0.5), ______, X(0.5), X(0.5), ______, X(0.5), ______, X(2.0), ______, ______, X(2.0), ______},
[TYPE_MYSTERY] = {______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______},
[TYPE_FIRE] = {______, ______, ______, ______, ______, ______, X(0.5), X(2.0), ______, X(2.0), ______, X(0.5), X(0.5), X(2.0), ______, ______, X(2.0), X(0.5), ______, ______, ______},
[TYPE_WATER] = {______, ______, ______, ______, ______, X(2.0), X(2.0), ______, ______, ______, ______, X(2.0), X(0.5), X(0.5), ______, ______, ______, X(0.5), ______, ______, ______},
[TYPE_GRASS] = {______, ______, ______, X(0.5), X(0.5), X(2.0), X(2.0), X(0.5), ______, X(0.5), ______, X(0.5), X(2.0), X(0.5), ______, ______, ______, X(0.5), ______, ______, ______},
[TYPE_ELECTRIC] = {______, ______, ______, X(2.0), ______, X(0.0), ______, ______, ______, ______, ______, ______, X(2.0), X(0.5), X(0.5), ______, ______, X(0.5), ______, ______, ______},
[TYPE_PSYCHIC] = {______, ______, X(2.0), ______, X(2.0), ______, ______, ______, ______, X(0.5), ______, ______, ______, ______, ______, X(0.5), ______, ______, X(0.0), ______, ______},
[TYPE_ICE] = {______, ______, ______, X(2.0), ______, X(2.0), ______, ______, ______, X(0.5), ______, FIR_RS, X(0.5), X(2.0), ______, ______, X(0.5), X(2.0), ______, ______, ______},
[TYPE_DRAGON] = {______, ______, ______, ______, ______, ______, ______, ______, ______, X(0.5), ______, ______, ______, ______, ______, ______, ______, X(2.0), ______, X(0.0), ______},
[TYPE_DARK] = {______, ______, X(0.5), ______, ______, ______, ______, ______, X(2.0), STL_RS, ______, ______, ______, ______, ______, X(2.0), ______, ______, X(0.5), X(0.5), ______},
[TYPE_FAIRY] = {______, ______, X(2.0), ______, X(0.5), ______, ______, ______, ______, X(0.5), ______, X(0.5), ______, ______, ______, ______, ______, X(2.0), X(2.0), ______, ______},
[TYPE_STELLAR] = {______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______},
};
#undef ______
#undef X
#if B_EXPANDED_TYPE_NAMES == TRUE
#define HANDLE_EXPANDED_TYPE_NAME(_name, ...) _(DEFAULT(_name, __VA_ARGS__))
#else
#define HANDLE_EXPANDED_TYPE_NAME(_name, ...) _(_name)
#endif
// .generic is large enough that the text for TYPE_ELECTRIC will exceed TEXT_BUFF_ARRAY_COUNT.
// In this array there's commented-out data such as references to type-resist berries that would otherwise would go unused.
// However, we figured this information would be useful for users that want to add their own types as a reminder of
// what data would they need to add in order to have their new types be fully fledged like official types.
const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] =
{
[TYPE_NONE] =
{
.name = _("None"),
.generic = _("a move"),
.palette = 15, // Uses TYPE_MYSTERY's icon
.teraTypeRGBValue = RGB_WHITE,
.damageCategory = DAMAGE_CATEGORY_PHYSICAL,
.paletteTMHM = gItemIconPalette_NormalTMHM,
},
[TYPE_NORMAL] =
{
.name = _("Normal"),
.generic = _("a NORMAL move"),
.palette = 13,
.zMove = MOVE_BREAKNECK_BLITZ,
.maxMove = MOVE_MAX_STRIKE,
.teraTypeRGBValue = RGB_WHITE, // custom
.damageCategory = DAMAGE_CATEGORY_PHYSICAL,
.paletteTMHM = gItemIconPalette_NormalTMHM,
//.enhanceItem = ITEM_SILK_SCARF,
//.berry = ITEM_CHILAN_BERRY,
//.gem = ITEM_NORMAL_GEM,
//.zCrystal = ITEM_NORMALIUM_Z,
//.teraShard = ITEM_NORMAL_TERA_SHARD,
//.arceusForm = SPECIES_ARCEUS_NORMAL,
},
[TYPE_FIGHTING] =
{
.name = HANDLE_EXPANDED_TYPE_NAME("Fight", "Fighting"),
.generic = _("a FIGHTING move"),
.palette = 13,
.zMove = MOVE_ALL_OUT_PUMMELING,
.maxMove = MOVE_MAX_KNUCKLE,
.teraTypeRGBValue = RGB(26, 8, 14),
.damageCategory = DAMAGE_CATEGORY_PHYSICAL,
.paletteTMHM = gItemIconPalette_FightingTMHM,
//.enhanceItem = ITEM_BLACK_BELT,
//.berry = ITEM_CHOPLE_BERRY,
//.gem = ITEM_FIGHTING_GEM,
//.zCrystal = ITEM_FIGHTINIUM_Z,
//.plate = ITEM_FIST_PLATE,
//.memory = ITEM_FIGHTING_MEMORY,
//.teraShard = ITEM_FIGHTING_TERA_SHARD,
//.arceusForm = SPECIES_ARCEUS_FIGHTING,
},
[TYPE_FLYING] =
{
.name = _("Flying"),
.generic = _("a FLYING move"),
.palette = 14,
.zMove = MOVE_SUPERSONIC_SKYSTRIKE,
.maxMove = MOVE_MAX_AIRSTREAM,
.teraTypeRGBValue = RGB(31, 26, 7),
.damageCategory = DAMAGE_CATEGORY_PHYSICAL,
.paletteTMHM = gItemIconPalette_FlyingTMHM,
//.enhanceItem = ITEM_SHARP_BEAK,
//.berry = ITEM_COBA_BERRY,
//.gem = ITEM_FLYING_GEM,
//.zCrystal = ITEM_FLYINIUM_Z,
//.plate = ITEM_SKY_PLATE,
//.memory = ITEM_FLYING_MEMORY,
//.teraShard = ITEM_FLYING_TERA_SHARD,
//.arceusForm = SPECIES_ARCEUS_FLYING,
},
[TYPE_POISON] =
{
.name = _("Poison"),
.generic = _("a POISON move"),
.palette = 14,
.zMove = MOVE_ACID_DOWNPOUR,
.maxMove = MOVE_MAX_OOZE,
.teraTypeRGBValue = RGB(26, 10, 25), // custom
.damageCategory = DAMAGE_CATEGORY_PHYSICAL,
.paletteTMHM = gItemIconPalette_PoisonTMHM,
//.enhanceItem = ITEM_POISON_BARB,
//.berry = ITEM_KEBIA_BERRY,
//.gem = ITEM_POISON_GEM,
//.zCrystal = ITEM_POISONIUM_Z,
//.plate = ITEM_TOXIC_PLATE,
//.memory = ITEM_POISON_MEMORY,
//.teraShard = ITEM_POISON_TERA_SHARD,
//.arceusForm = SPECIES_ARCEUS_POISON,
},
[TYPE_GROUND] =
{
.name = _("Ground"),
.generic = _("a GROUND move"),
.palette = 13,
.zMove = MOVE_TECTONIC_RAGE,
.maxMove = MOVE_MAX_QUAKE,
.teraTypeRGBValue = RGB(25, 23, 18),
.damageCategory = DAMAGE_CATEGORY_PHYSICAL,
.paletteTMHM = gItemIconPalette_GroundTMHM,
//.enhanceItem = ITEM_SOFT_SAND,
//.berry = ITEM_SHUCA_BERRY,
//.gem = ITEM_GROUND_GEM,
//.zCrystal = ITEM_GROUNDIUM_Z,
//.plate = ITEM_EARTH_PLATE,
//.memory = ITEM_GROUND_MEMORY,
//.teraShard = ITEM_GROUND_TERA_SHARD,
//.arceusForm = SPECIES_ARCEUS_GROUND,
},
[TYPE_ROCK] =
{
.name = _("Rock"),
.generic = _("a ROCK move"),
.palette = 13,
.zMove = MOVE_CONTINENTAL_CRUSH,
.maxMove = MOVE_MAX_ROCKFALL,
.teraTypeRGBValue = RGB(18, 16, 8), // custom
.damageCategory = DAMAGE_CATEGORY_PHYSICAL,
.paletteTMHM = gItemIconPalette_RockTMHM,
//.enhanceItem = ITEM_HARD_STONE,
//.berry = ITEM_CHARTI_BERRY,
//.gem = ITEM_ROCK_GEM,
//.zCrystal = ITEM_ROCKIUM_Z,
//.plate = ITEM_STONE_PLATE,
//.memory = ITEM_ROCK_MEMORY,
//.teraShard = ITEM_ROCK_TERA_SHARD,
//.arceusForm = SPECIES_ARCEUS_ROCK,
},
[TYPE_BUG] =
{
.name = _("Bug"),
.generic = _("a BUG move"),
.palette = 15,
.zMove = MOVE_SAVAGE_SPIN_OUT,
.maxMove = MOVE_MAX_FLUTTERBY,
.teraTypeRGBValue = RGB(18, 24, 6),
.damageCategory = DAMAGE_CATEGORY_PHYSICAL,
.paletteTMHM = gItemIconPalette_BugTMHM,
//.enhanceItem = ITEM_SILVER_POWDER,
//.berry = ITEM_TANGA_BERRY,
//.gem = ITEM_BUG_GEM,
//.zCrystal = ITEM_BUGINIUM_Z,
//.plate = ITEM_INSECT_PLATE,
//.memory = ITEM_BUG_MEMORY,
//.teraShard = ITEM_BUG_TERA_SHARD,
//.arceusForm = SPECIES_ARCEUS_BUG,
},
[TYPE_GHOST] =
{
.name = _("Ghost"),
.generic = _("a GHOST move"),
.palette = 14,
.zMove = MOVE_NEVER_ENDING_NIGHTMARE,
.maxMove = MOVE_MAX_PHANTASM,
.teraTypeRGBValue = RGB(12, 10, 16),
.damageCategory = DAMAGE_CATEGORY_PHYSICAL,
.paletteTMHM = gItemIconPalette_GhostTMHM,
//.enhanceItem = ITEM_SPELL_TAG,
//.berry = ITEM_KASIB_BERRY,
//.gem = ITEM_GHOST_GEM,
//.zCrystal = ITEM_GHOSTIUM_Z,
//.plate = ITEM_SPOOKY_PLATE,
//.memory = ITEM_GHOST_MEMORY,
//.teraShard = ITEM_GHOST_TERA_SHARD,
//.arceusForm = SPECIES_ARCEUS_GHOST,
},
[TYPE_STEEL] =
{
.name = _("Steel"),
.generic = _("a STEEL move"),
.palette = 13,
.zMove = MOVE_CORKSCREW_CRASH,
.maxMove = MOVE_MAX_STEELSPIKE,
.teraTypeRGBValue = RGB(19, 19, 20),
.damageCategory = DAMAGE_CATEGORY_PHYSICAL,
.paletteTMHM = gItemIconPalette_SteelTMHM,
//.enhanceItem = ITEM_METAL_COAT,
//.berry = ITEM_BABIRI_BERRY,
//.gem = ITEM_STEEL_GEM,
//.zCrystal = ITEM_STEELIUM_Z,
//.plate = ITEM_IRON_PLATE,
//.memory = ITEM_STEEL_MEMORY,
//.teraShard = ITEM_STEEL_TERA_SHARD,
//.arceusForm = SPECIES_ARCEUS_STEEL,
},
[TYPE_MYSTERY] =
{
.name = _("???"),
.generic = _("a ??? move"),
.palette = 15,
.teraTypeRGBValue = RGB_WHITE,
.damageCategory = DAMAGE_CATEGORY_SPECIAL,
},
[TYPE_FIRE] =
{
.name = _("Fire"),
.generic = _("a FIRE move"),
.palette = 13,
.zMove = MOVE_INFERNO_OVERDRIVE,
.maxMove = MOVE_MAX_FLARE,
.teraTypeRGBValue = RGB(31, 20, 11),
.damageCategory = DAMAGE_CATEGORY_SPECIAL,
.paletteTMHM = gItemIconPalette_FireTMHM,
//.enhanceItem = ITEM_CHARCOAL,
//.berry = ITEM_OCCA_BERRY,
//.gem = ITEM_FIRE_GEM,
//.zCrystal = ITEM_FIRIUM_Z,
//.plate = ITEM_FLAME_PLATE,
//.memory = ITEM_FIRE_MEMORY,
//.teraShard = ITEM_FIRE_TERA_SHARD,
//.arceusForm = SPECIES_ARCEUS_FIRE,
},
[TYPE_WATER] =
{
.name = _("Water"),
.generic = _("a WATER move"),
.palette = 14,
.zMove = MOVE_HYDRO_VORTEX,
.maxMove = MOVE_MAX_GEYSER,
.teraTypeRGBValue = RGB(10, 18, 27),
.damageCategory = DAMAGE_CATEGORY_SPECIAL,
.paletteTMHM = gItemIconPalette_WaterTMHM,
//.enhanceItem = ITEM_MYSTIC_WATER,
//.berry = ITEM_PASSHO_BERRY,
//.gem = ITEM_WATER_GEM,
//.zCrystal = ITEM_WATERIUM_Z,
//.plate = ITEM_SPLASH_PLATE,
//.memory = ITEM_WATER_MEMORY,
//.teraShard = ITEM_WATER_TERA_SHARD,
//.arceusForm = SPECIES_ARCEUS_WATER,
},
[TYPE_GRASS] =
{
.name = _("Grass"),
.generic = _("a GRASS move"),
.palette = 15,
.zMove = MOVE_BLOOM_DOOM,
.maxMove = MOVE_MAX_OVERGROWTH,
.teraTypeRGBValue = RGB(12, 24, 11),
.damageCategory = DAMAGE_CATEGORY_SPECIAL,
.paletteTMHM = gItemIconPalette_GrassTMHM,
//.enhanceItem = ITEM_MIRACLE_SEED,
//.berry = ITEM_RINDO_BERRY,
//.gem = ITEM_GRASS_GEM,
//.zCrystal = ITEM_GRASSIUM_Z,
//.plate = ITEM_MEADOW_PLATE,
//.memory = ITEM_GRASS_MEMORY,
//.teraShard = ITEM_GRASS_TERA_SHARD,
//.arceusForm = SPECIES_ARCEUS_GRASS,
},
[TYPE_ELECTRIC] =
{
.name = HANDLE_EXPANDED_TYPE_NAME("Electr", "Electric"),
.generic = _("an ELECTRIC move"),
.palette = 13,
.zMove = MOVE_GIGAVOLT_HAVOC,
.maxMove = MOVE_MAX_LIGHTNING,
.teraTypeRGBValue = RGB(30, 26, 7),
.damageCategory = DAMAGE_CATEGORY_SPECIAL,
.paletteTMHM = gItemIconPalette_ElectricTMHM,
//.enhanceItem = ITEM_MAGNET,
//.berry = ITEM_WACAN_BERRY,
//.gem = ITEM_ELECTRIC_GEM,
//.zCrystal = ITEM_ELECTRIUM_Z,
//.plate = ITEM_ZAP_PLATE,
//.memory = ITEM_ELECTRIC_MEMORY,
//.teraShard = ITEM_ELECTRIC_TERA_SHARD,
//.arceusForm = SPECIES_ARCEUS_ELECTRIC,
},
[TYPE_PSYCHIC] =
{
.name = HANDLE_EXPANDED_TYPE_NAME("Psychc", "Psychic"),
.generic = _("a PSYCHIC move"),
.palette = 14,
.zMove = MOVE_SHATTERED_PSYCHE,
.maxMove = MOVE_MAX_MINDSTORM,
.teraTypeRGBValue = RGB(31, 14, 15),
.damageCategory = DAMAGE_CATEGORY_SPECIAL,
.paletteTMHM = gItemIconPalette_PsychicTMHM,
//.enhanceItem = ITEM_TWISTED_SPOON,
//.berry = ITEM_PAYAPA_BERRY,
//.gem = ITEM_PSYCHIC_GEM,
//.zCrystal = ITEM_PSYCHIUM_Z,
//.plate = ITEM_MIND_PLATE,
//.memory = ITEM_PSYCHIC_MEMORY,
//.teraShard = ITEM_PSYCHIC_TERA_SHARD,
//.arceusForm = SPECIES_ARCEUS_PSYCHIC,
},
[TYPE_ICE] =
{
.name = _("Ice"),
.generic = _("an ICE move"),
.palette = 14,
.zMove = MOVE_SUBZERO_SLAMMER,
.maxMove = MOVE_MAX_HAILSTORM,
.teraTypeRGBValue = RGB(14, 26, 25),
.damageCategory = DAMAGE_CATEGORY_SPECIAL,
.paletteTMHM = gItemIconPalette_IceTMHM,
//.enhanceItem = ITEM_NEVER_MELT_ICE,
//.berry = ITEM_YACHE_BERRY,
//.gem = ITEM_ICE_GEM,
//.zCrystal = ITEM_ICIUM_Z,
//.plate = ITEM_ICICLE_PLATE,
//.memory = ITEM_ICE_MEMORY,
//.teraShard = ITEM_ICE_TERA_SHARD,
//.arceusForm = SPECIES_ARCEUS_ICE,
},
[TYPE_DRAGON] =
{
.name = _("Dragon"),
.generic = _("a DRAGON move"),
.palette = 15,
.zMove = MOVE_DEVASTATING_DRAKE,
.maxMove = MOVE_MAX_WYRMWIND,
.teraTypeRGBValue = RGB(10, 18, 27),
.damageCategory = DAMAGE_CATEGORY_SPECIAL,
.paletteTMHM = gItemIconPalette_DragonTMHM,
//.enhanceItem = ITEM_DRAGON_FANG,
//.berry = ITEM_HABAN_BERRY,
//.gem = ITEM_DRAGON_GEM,
//.zCrystal = ITEM_DRAGONIUM_Z,
//.plate = ITEM_DRACO_PLATE,
//.memory = ITEM_DRAGON_MEMORY,
//.teraShard = ITEM_DRAGON_TERA_SHARD,
//.arceusForm = SPECIES_ARCEUS_DRAGON,
},
[TYPE_DARK] =
{
.name = _("Dark"),
.generic = _("a DARK move"),
.palette = 13,
.zMove = MOVE_BLACK_HOLE_ECLIPSE,
.maxMove = MOVE_MAX_DARKNESS,
.teraTypeRGBValue = RGB(6, 5, 8),
.damageCategory = DAMAGE_CATEGORY_SPECIAL,
.paletteTMHM = gItemIconPalette_DarkTMHM,
//.enhanceItem = ITEM_BLACK_GLASSES,
//.berry = ITEM_COLBUR_BERRY,
//.gem = ITEM_DARK_GEM,
//.zCrystal = ITEM_DARKINIUM_Z,
//.plate = ITEM_DREAD_PLATE,
//.memory = ITEM_DARK_MEMORY,
//.teraShard = ITEM_DARK_TERA_SHARD,
//.arceusForm = SPECIES_ARCEUS_DARK,
},
[TYPE_FAIRY] =
{
.name = _("Fairy"),
.generic = _("a FAIRY move"),
.palette = 14,
.zMove = MOVE_TWINKLE_TACKLE,
.maxMove = MOVE_MAX_STARFALL,
.teraTypeRGBValue = RGB(31, 15, 21),
.damageCategory = DAMAGE_CATEGORY_SPECIAL,
.paletteTMHM = gItemIconPalette_FairyTMHM,
//.enhanceItem = ITEM_FAIRY_FEATHER,
//.berry = ITEM_ROSELI_BERRY,
//.gem = ITEM_FAIRY_GEM,
//.zCrystal = ITEM_FAIRIUM_Z,
//.plate = ITEM_PIXIE_PLATE,
//.memory = ITEM_FAIRY_MEMORY,
//.teraShard = ITEM_FAIRY_TERA_SHARD,
//.arceusForm = SPECIES_ARCEUS_FAIRY,
},
[TYPE_STELLAR] =
{
.name = HANDLE_EXPANDED_TYPE_NAME("Stellr", "Stellar"),
.generic = _("a STELLAR move"),
.palette = 15,
.zMove = MOVE_BREAKNECK_BLITZ,
.maxMove = MOVE_MAX_STRIKE,
.teraTypeRGBValue = RGB(10, 18, 27),
.paletteTMHM = gItemIconPalette_NormalTMHM, // failsafe
// .teraShard = ITEM_STELLAR_TERA_SHARD,
},
};

View file

@ -112,6 +112,7 @@ static const u8 sTextColors[] = { TEXT_DYNAMIC_COLOR_6, TEXT_COLOR_WHITE, TEXT_C
static const struct MenuInfoIcon sMenuInfoIcons[] = static const struct MenuInfoIcon sMenuInfoIcons[] =
{ // { width, height, offset } { // { width, height, offset }
{ 12, 12, 0x00 }, // Unused { 12, 12, 0x00 }, // Unused
[TYPE_NONE + 1] = { 32, 12, 0xA4 }, // Copy of TYPE_MYSTERY's
[TYPE_NORMAL + 1] = { 32, 12, 0x20 }, [TYPE_NORMAL + 1] = { 32, 12, 0x20 },
[TYPE_FIGHTING + 1] = { 32, 12, 0x64 }, [TYPE_FIGHTING + 1] = { 32, 12, 0x64 },
[TYPE_FLYING + 1] = { 32, 12, 0x60 }, [TYPE_FLYING + 1] = { 32, 12, 0x60 },

View file

@ -1389,7 +1389,7 @@ static const struct SearchOptionText sDexSearchColorOptions[] =
static const struct SearchOptionText sDexSearchTypeOptions[NUMBER_OF_MON_TYPES] = // + 2 for "None" and terminator, - 2 for Mystery and Stellar static const struct SearchOptionText sDexSearchTypeOptions[NUMBER_OF_MON_TYPES] = // + 2 for "None" and terminator, - 2 for Mystery and Stellar
{ {
{gText_DexEmptyString, gText_DexSearchTypeNone}, {gText_DexEmptyString, gTypesInfo[TYPE_NONE].name},
{gText_DexEmptyString, gTypesInfo[TYPE_NORMAL].name}, {gText_DexEmptyString, gTypesInfo[TYPE_NORMAL].name},
{gText_DexEmptyString, gTypesInfo[TYPE_FIGHTING].name}, {gText_DexEmptyString, gTypesInfo[TYPE_FIGHTING].name},
{gText_DexEmptyString, gTypesInfo[TYPE_FLYING].name}, {gText_DexEmptyString, gTypesInfo[TYPE_FLYING].name},

View file

@ -1901,7 +1901,7 @@ static const struct SearchOptionText sDexSearchColorOptions[] =
static const struct SearchOptionText sDexSearchTypeOptions[NUMBER_OF_MON_TYPES] = // + 2 for "None" and terminator, - 2 for Mystery and Stellar static const struct SearchOptionText sDexSearchTypeOptions[NUMBER_OF_MON_TYPES] = // + 2 for "None" and terminator, - 2 for Mystery and Stellar
{ {
{gText_DexEmptyString, gText_DexSearchTypeNone}, {gText_DexEmptyString, gTypesInfo[TYPE_NONE].name},
{gText_DexEmptyString, gTypesInfo[TYPE_NORMAL].name}, {gText_DexEmptyString, gTypesInfo[TYPE_NORMAL].name},
{gText_DexEmptyString, gTypesInfo[TYPE_FIGHTING].name}, {gText_DexEmptyString, gTypesInfo[TYPE_FIGHTING].name},
{gText_DexEmptyString, gTypesInfo[TYPE_FLYING].name}, {gText_DexEmptyString, gTypesInfo[TYPE_FLYING].name},

View file

@ -2771,14 +2771,14 @@ u32 GetBoxMonData3(struct BoxPokemon *boxMon, s32 field, u8 *data)
break; break;
case MON_DATA_TERA_TYPE: case MON_DATA_TERA_TYPE:
{ {
if (substruct0->teraType == 0) if (substruct0->teraType == TYPE_NONE)
{ {
const u8 *types = gSpeciesInfo[substruct0->species].types; const u8 *types = gSpeciesInfo[substruct0->species].types;
retVal = (boxMon->personality & 0x1) == 0 ? types[0] : types[1]; retVal = (boxMon->personality & 0x1) == 0 ? types[0] : types[1];
} }
else else
{ {
retVal = substruct0->teraType - 1; retVal = substruct0->teraType;
} }
break; break;
} }
@ -3207,7 +3207,7 @@ void SetBoxMonData(struct BoxPokemon *boxMon, s32 field, const void *dataArg)
{ {
u32 teraType; u32 teraType;
SET8(teraType); SET8(teraType);
substruct0->teraType = 1 + teraType; substruct0->teraType = teraType;
break; break;
} }
case MON_DATA_EVOLUTION_TRACKER: case MON_DATA_EVOLUTION_TRACKER:

View file

@ -812,6 +812,10 @@ static const struct OamData sOamData_MoveTypes =
.paletteNum = 0, .paletteNum = 0,
.affineParam = 0, .affineParam = 0,
}; };
static const union AnimCmd sSpriteAnim_TypeNone[] = {
ANIMCMD_FRAME(TYPE_NONE * 8, 0, FALSE, FALSE),
ANIMCMD_END
};
static const union AnimCmd sSpriteAnim_TypeNormal[] = { static const union AnimCmd sSpriteAnim_TypeNormal[] = {
ANIMCMD_FRAME(TYPE_NORMAL * 8, 0, FALSE, FALSE), ANIMCMD_FRAME(TYPE_NORMAL * 8, 0, FALSE, FALSE),
ANIMCMD_END ANIMCMD_END
@ -913,31 +917,32 @@ static const union AnimCmd sSpriteAnim_CategoryTough[] = {
ANIMCMD_END ANIMCMD_END
}; };
static const union AnimCmd *const sSpriteAnimTable_MoveTypes[NUMBER_OF_MON_TYPES + CONTEST_CATEGORIES_COUNT] = { static const union AnimCmd *const sSpriteAnimTable_MoveTypes[NUMBER_OF_MON_TYPES + CONTEST_CATEGORIES_COUNT] = {
sSpriteAnim_TypeNormal, [TYPE_NONE] = sSpriteAnim_TypeNone,
sSpriteAnim_TypeFighting, [TYPE_NORMAL] = sSpriteAnim_TypeNormal,
sSpriteAnim_TypeFlying, [TYPE_FIGHTING] = sSpriteAnim_TypeFighting,
sSpriteAnim_TypePoison, [TYPE_FLYING] = sSpriteAnim_TypeFlying,
sSpriteAnim_TypeGround, [TYPE_POISON] = sSpriteAnim_TypePoison,
sSpriteAnim_TypeRock, [TYPE_GROUND] = sSpriteAnim_TypeGround,
sSpriteAnim_TypeBug, [TYPE_ROCK] = sSpriteAnim_TypeRock,
sSpriteAnim_TypeGhost, [TYPE_BUG] = sSpriteAnim_TypeBug,
sSpriteAnim_TypeSteel, [TYPE_GHOST] = sSpriteAnim_TypeGhost,
sSpriteAnim_TypeMystery, [TYPE_STEEL] = sSpriteAnim_TypeSteel,
sSpriteAnim_TypeFire, [TYPE_MYSTERY] = sSpriteAnim_TypeMystery,
sSpriteAnim_TypeWater, [TYPE_FIRE] = sSpriteAnim_TypeFire,
sSpriteAnim_TypeGrass, [TYPE_WATER] = sSpriteAnim_TypeWater,
sSpriteAnim_TypeElectric, [TYPE_GRASS] = sSpriteAnim_TypeGrass,
sSpriteAnim_TypePsychic, [TYPE_ELECTRIC] = sSpriteAnim_TypeElectric,
sSpriteAnim_TypeIce, [TYPE_PSYCHIC] = sSpriteAnim_TypePsychic,
sSpriteAnim_TypeDragon, [TYPE_ICE] = sSpriteAnim_TypeIce,
sSpriteAnim_TypeDark, [TYPE_DRAGON] = sSpriteAnim_TypeDragon,
sSpriteAnim_TypeFairy, [TYPE_DARK] = sSpriteAnim_TypeDark,
sSpriteAnim_TypeStellar, [TYPE_FAIRY] = sSpriteAnim_TypeFairy,
sSpriteAnim_CategoryCool, [TYPE_STELLAR] = sSpriteAnim_TypeStellar,
sSpriteAnim_CategoryBeauty, [NUMBER_OF_MON_TYPES + CONTEST_CATEGORY_COOL] = sSpriteAnim_CategoryCool,
sSpriteAnim_CategoryCute, [NUMBER_OF_MON_TYPES + CONTEST_CATEGORY_BEAUTY] = sSpriteAnim_CategoryBeauty,
sSpriteAnim_CategorySmart, [NUMBER_OF_MON_TYPES + CONTEST_CATEGORY_CUTE] = sSpriteAnim_CategoryCute,
sSpriteAnim_CategoryTough, [NUMBER_OF_MON_TYPES + CONTEST_CATEGORY_SMART] = sSpriteAnim_CategorySmart,
[NUMBER_OF_MON_TYPES + CONTEST_CATEGORY_TOUGH] = sSpriteAnim_CategoryTough,
}; };
const struct CompressedSpriteSheet gSpriteSheet_MoveTypes = const struct CompressedSpriteSheet gSpriteSheet_MoveTypes =

View file

@ -352,7 +352,7 @@ u32 ScriptGiveMonParameterized(u16 species, u8 level, u16 item, u8 ball, u8 natu
// tera type // tera type
if (teraType >= NUMBER_OF_MON_TYPES) if (teraType >= NUMBER_OF_MON_TYPES)
teraType = gSpeciesInfo[species].types[0]; teraType = TYPE_NONE;
SetMonData(&mon, MON_DATA_TERA_TYPE, &teraType); SetMonData(&mon, MON_DATA_TERA_TYPE, &teraType);
// EV and IV // EV and IV

View file

@ -765,6 +765,7 @@ SINGLE_BATTLE_TEST("(TERA) Stellar type's one-time boost factors in dynamically-
SINGLE_BATTLE_TEST("(TERA) All type indicators function correctly") SINGLE_BATTLE_TEST("(TERA) All type indicators function correctly")
{ {
u32 type; u32 type;
PARAMETRIZE { type = TYPE_NONE; }
PARAMETRIZE { type = TYPE_NORMAL; } PARAMETRIZE { type = TYPE_NORMAL; }
PARAMETRIZE { type = TYPE_FIGHTING; } PARAMETRIZE { type = TYPE_FIGHTING; }
PARAMETRIZE { type = TYPE_FLYING; } PARAMETRIZE { type = TYPE_FLYING; }

View file

@ -0,0 +1,106 @@
#include "global.h"
#include "test/battle.h"
// IV combinations sourced from https://www.smogon.com/forums/threads/hidden-power-iv-combinations.78083/
SINGLE_BATTLE_TEST("Hidden Power's type is determined by IVs")
{
u32 type, j, foeType, foeSpecies;
u32 hp, atk, def, spAtk, spDef, speed;
bool32 hidden;
PARAMETRIZE { type = TYPE_NONE; hidden = FALSE; }
PARAMETRIZE { type = TYPE_NORMAL; hidden = FALSE; }
PARAMETRIZE { type = TYPE_FIGHTING; hidden = TRUE; foeType = TYPE_PSYCHIC; foeSpecies = SPECIES_WOBBUFFET; hp = 30; atk = 2; def = 31; spAtk = 30; spDef = 30; speed = 30; }
PARAMETRIZE { type = TYPE_FIGHTING; hidden = TRUE; foeType = TYPE_PSYCHIC; foeSpecies = SPECIES_WOBBUFFET; hp = 31; atk = 15; def = 30; spAtk = 30; spDef = 30; speed = 30; }
PARAMETRIZE { type = TYPE_FIGHTING; hidden = TRUE; foeType = TYPE_PSYCHIC; foeSpecies = SPECIES_WOBBUFFET; hp = 30; atk = 22; def = 31; spAtk = 30; spDef = 30; speed = 30; }
PARAMETRIZE { type = TYPE_FIGHTING; hidden = TRUE; foeType = TYPE_PSYCHIC; foeSpecies = SPECIES_WOBBUFFET; hp = 31; atk = 31; def = 30; spAtk = 30; spDef = 30; speed = 30; }
PARAMETRIZE { type = TYPE_FLYING; hidden = TRUE; foeType = TYPE_STEEL; foeSpecies = SPECIES_REGISTEEL; hp = 31; atk = 2; def = 31; spAtk = 30; spDef = 30; speed = 30; }
PARAMETRIZE { type = TYPE_FLYING; hidden = TRUE; foeType = TYPE_STEEL; foeSpecies = SPECIES_REGISTEEL; hp = 31; atk = 15; def = 31; spAtk = 30; spDef = 30; speed = 30; }
PARAMETRIZE { type = TYPE_FLYING; hidden = TRUE; foeType = TYPE_STEEL; foeSpecies = SPECIES_REGISTEEL; hp = 31; atk = 22; def = 31; spAtk = 30; spDef = 30; speed = 30; }
PARAMETRIZE { type = TYPE_FLYING; hidden = TRUE; foeType = TYPE_STEEL; foeSpecies = SPECIES_REGISTEEL; hp = 31; atk = 31; def = 31; spAtk = 30; spDef = 30; speed = 30; }
PARAMETRIZE { type = TYPE_POISON; hidden = TRUE; foeType = TYPE_POISON; foeSpecies = SPECIES_ARBOK; hp = 30; atk = 2; def = 31; spAtk = 30; spDef = 30; speed = 31; }
PARAMETRIZE { type = TYPE_POISON; hidden = TRUE; foeType = TYPE_POISON; foeSpecies = SPECIES_ARBOK; hp = 31; atk = 15; def = 30; spAtk = 30; spDef = 30; speed = 31; }
PARAMETRIZE { type = TYPE_POISON; hidden = TRUE; foeType = TYPE_POISON; foeSpecies = SPECIES_ARBOK; hp = 30; atk = 22; def = 31; spAtk = 30; spDef = 30; speed = 31; }
PARAMETRIZE { type = TYPE_POISON; hidden = TRUE; foeType = TYPE_POISON; foeSpecies = SPECIES_ARBOK; hp = 31; atk = 31; def = 30; spAtk = 30; spDef = 30; speed = 31; }
PARAMETRIZE { type = TYPE_GROUND; hidden = TRUE; foeType = TYPE_GRASS; foeSpecies = SPECIES_TANGELA; hp = 31; atk = 2; def = 31; spAtk = 30; spDef = 30; speed = 31; }
PARAMETRIZE { type = TYPE_GROUND; hidden = TRUE; foeType = TYPE_GRASS; foeSpecies = SPECIES_TANGELA; hp = 31; atk = 15; def = 31; spAtk = 30; spDef = 30; speed = 31; }
PARAMETRIZE { type = TYPE_GROUND; hidden = TRUE; foeType = TYPE_GRASS; foeSpecies = SPECIES_TANGELA; hp = 31; atk = 22; def = 31; spAtk = 30; spDef = 30; speed = 31; }
PARAMETRIZE { type = TYPE_GROUND; hidden = TRUE; foeType = TYPE_GRASS; foeSpecies = SPECIES_TANGELA; hp = 31; atk = 31; def = 31; spAtk = 30; spDef = 30; speed = 31; }
PARAMETRIZE { type = TYPE_ROCK; hidden = TRUE; foeType = TYPE_STEEL; foeSpecies = SPECIES_KLINK; hp = 31; atk = 2; def = 30; spAtk = 31; spDef = 30; speed = 30; }
PARAMETRIZE { type = TYPE_ROCK; hidden = TRUE; foeType = TYPE_STEEL; foeSpecies = SPECIES_KLINK; hp = 31; atk = 15; def = 30; spAtk = 31; spDef = 30; speed = 30; }
PARAMETRIZE { type = TYPE_ROCK; hidden = TRUE; foeType = TYPE_STEEL; foeSpecies = SPECIES_KLINK; hp = 31; atk = 22; def = 30; spAtk = 31; spDef = 30; speed = 30; }
PARAMETRIZE { type = TYPE_ROCK; hidden = TRUE; foeType = TYPE_STEEL; foeSpecies = SPECIES_KLINK; hp = 31; atk = 31; def = 30; spAtk = 31; spDef = 30; speed = 30; }
PARAMETRIZE { type = TYPE_BUG; hidden = TRUE; foeType = TYPE_STEEL; foeSpecies = SPECIES_KLINK; hp = 31; atk = 2; def = 31; spAtk = 31; spDef = 30; speed = 30; }
PARAMETRIZE { type = TYPE_BUG; hidden = TRUE; foeType = TYPE_STEEL; foeSpecies = SPECIES_KLINK; hp = 31; atk = 15; def = 31; spAtk = 31; spDef = 30; speed = 30; }
PARAMETRIZE { type = TYPE_BUG; hidden = TRUE; foeType = TYPE_STEEL; foeSpecies = SPECIES_KLINK; hp = 31; atk = 22; def = 31; spAtk = 31; spDef = 30; speed = 30; }
PARAMETRIZE { type = TYPE_BUG; hidden = TRUE; foeType = TYPE_STEEL; foeSpecies = SPECIES_KLINK; hp = 31; atk = 31; def = 31; spAtk = 31; spDef = 30; speed = 30; }
PARAMETRIZE { type = TYPE_GHOST; hidden = TRUE; foeType = TYPE_DARK; foeSpecies = SPECIES_UMBREON; hp = 31; atk = 2; def = 31; spAtk = 31; spDef = 30; speed = 31; }
PARAMETRIZE { type = TYPE_GHOST; hidden = TRUE; foeType = TYPE_DARK; foeSpecies = SPECIES_UMBREON; hp = 31; atk = 15; def = 30; spAtk = 31; spDef = 30; speed = 31; }
PARAMETRIZE { type = TYPE_GHOST; hidden = TRUE; foeType = TYPE_DARK; foeSpecies = SPECIES_UMBREON; hp = 31; atk = 22; def = 31; spAtk = 31; spDef = 30; speed = 31; }
PARAMETRIZE { type = TYPE_GHOST; hidden = TRUE; foeType = TYPE_DARK; foeSpecies = SPECIES_UMBREON; hp = 31; atk = 31; def = 30; spAtk = 31; spDef = 30; speed = 31; }
PARAMETRIZE { type = TYPE_STEEL; hidden = TRUE; foeType = TYPE_STEEL; foeSpecies = SPECIES_KLINK; hp = 31; atk = 2; def = 30; spAtk = 30; spDef = 31; speed = 30; }
PARAMETRIZE { type = TYPE_STEEL; hidden = TRUE; foeType = TYPE_STEEL; foeSpecies = SPECIES_KLINK; hp = 31; atk = 15; def = 31; spAtk = 31; spDef = 30; speed = 31; }
PARAMETRIZE { type = TYPE_STEEL; hidden = TRUE; foeType = TYPE_STEEL; foeSpecies = SPECIES_KLINK; hp = 31; atk = 22; def = 30; spAtk = 30; spDef = 31; speed = 30; }
PARAMETRIZE { type = TYPE_STEEL; hidden = TRUE; foeType = TYPE_STEEL; foeSpecies = SPECIES_KLINK; hp = 31; atk = 31; def = 31; spAtk = 31; spDef = 30; speed = 31; }
PARAMETRIZE { type = TYPE_FIRE; hidden = TRUE; foeType = TYPE_WATER; foeSpecies = SPECIES_BLASTOISE; hp = 31; atk = 2; def = 31; spAtk = 30; spDef = 31; speed = 30; }
PARAMETRIZE { type = TYPE_FIRE; hidden = TRUE; foeType = TYPE_WATER; foeSpecies = SPECIES_BLASTOISE; hp = 31; atk = 15; def = 30; spAtk = 30; spDef = 31; speed = 30; }
PARAMETRIZE { type = TYPE_FIRE; hidden = TRUE; foeType = TYPE_WATER; foeSpecies = SPECIES_BLASTOISE; hp = 31; atk = 22; def = 31; spAtk = 30; spDef = 31; speed = 30; }
PARAMETRIZE { type = TYPE_FIRE; hidden = TRUE; foeType = TYPE_WATER; foeSpecies = SPECIES_BLASTOISE; hp = 31; atk = 31; def = 30; spAtk = 30; spDef = 31; speed = 30; }
PARAMETRIZE { type = TYPE_WATER; hidden = TRUE; foeType = TYPE_WATER; foeSpecies = SPECIES_BLASTOISE; hp = 31; atk = 2; def = 30; spAtk = 30; spDef = 31; speed = 31; }
PARAMETRIZE { type = TYPE_WATER; hidden = TRUE; foeType = TYPE_WATER; foeSpecies = SPECIES_BLASTOISE; hp = 31; atk = 15; def = 31; spAtk = 30; spDef = 31; speed = 30; }
PARAMETRIZE { type = TYPE_WATER; hidden = TRUE; foeType = TYPE_WATER; foeSpecies = SPECIES_BLASTOISE; hp = 31; atk = 22; def = 30; spAtk = 30; spDef = 31; speed = 31; }
PARAMETRIZE { type = TYPE_WATER; hidden = TRUE; foeType = TYPE_WATER; foeSpecies = SPECIES_BLASTOISE; hp = 31; atk = 31; def = 31; spAtk = 30; spDef = 31; speed = 30; }
PARAMETRIZE { type = TYPE_GRASS; hidden = TRUE; foeType = TYPE_STEEL; foeSpecies = SPECIES_KLINK; hp = 30; atk = 2; def = 31; spAtk = 30; spDef = 31; speed = 31; }
PARAMETRIZE { type = TYPE_GRASS; hidden = TRUE; foeType = TYPE_STEEL; foeSpecies = SPECIES_KLINK; hp = 30; atk = 15; def = 31; spAtk = 30; spDef = 31; speed = 31; }
PARAMETRIZE { type = TYPE_GRASS; hidden = TRUE; foeType = TYPE_STEEL; foeSpecies = SPECIES_KLINK; hp = 30; atk = 22; def = 31; spAtk = 30; spDef = 31; speed = 31; }
PARAMETRIZE { type = TYPE_GRASS; hidden = TRUE; foeType = TYPE_STEEL; foeSpecies = SPECIES_KLINK; hp = 30; atk = 31; def = 31; spAtk = 30; spDef = 31; speed = 31; }
PARAMETRIZE { type = TYPE_ELECTRIC; hidden = TRUE; foeType = TYPE_GRASS; foeSpecies = SPECIES_TANGELA; hp = 31; atk = 2; def = 30; spAtk = 31; spDef = 31; speed = 30; }
PARAMETRIZE { type = TYPE_ELECTRIC; hidden = TRUE; foeType = TYPE_GRASS; foeSpecies = SPECIES_TANGELA; hp = 30; atk = 15; def = 30; spAtk = 31; spDef = 31; speed = 30; }
PARAMETRIZE { type = TYPE_ELECTRIC; hidden = TRUE; foeType = TYPE_GRASS; foeSpecies = SPECIES_TANGELA; hp = 31; atk = 22; def = 30; spAtk = 31; spDef = 31; speed = 30; }
PARAMETRIZE { type = TYPE_ELECTRIC; hidden = TRUE; foeType = TYPE_GRASS; foeSpecies = SPECIES_TANGELA; hp = 30; atk = 31; def = 30; spAtk = 31; spDef = 31; speed = 30; }
PARAMETRIZE { type = TYPE_PSYCHIC; hidden = TRUE; foeType = TYPE_STEEL; foeSpecies = SPECIES_KLINK; hp = 31; atk = 2; def = 31; spAtk = 31; spDef = 31; speed = 30; }
PARAMETRIZE { type = TYPE_PSYCHIC; hidden = TRUE; foeType = TYPE_STEEL; foeSpecies = SPECIES_KLINK; hp = 30; atk = 15; def = 31; spAtk = 31; spDef = 31; speed = 30; }
PARAMETRIZE { type = TYPE_PSYCHIC; hidden = TRUE; foeType = TYPE_STEEL; foeSpecies = SPECIES_KLINK; hp = 31; atk = 22; def = 31; spAtk = 31; spDef = 31; speed = 30; }
PARAMETRIZE { type = TYPE_PSYCHIC; hidden = TRUE; foeType = TYPE_STEEL; foeSpecies = SPECIES_KLINK; hp = 30; atk = 31; def = 31; spAtk = 31; spDef = 31; speed = 30; }
PARAMETRIZE { type = TYPE_ICE; hidden = TRUE; foeType = TYPE_STEEL; foeSpecies = SPECIES_KLINK; hp = 30; atk = 2; def = 30; spAtk = 31; spDef = 31; speed = 31; }
PARAMETRIZE { type = TYPE_ICE; hidden = TRUE; foeType = TYPE_STEEL; foeSpecies = SPECIES_KLINK; hp = 30; atk = 15; def = 30; spAtk = 31; spDef = 31; speed = 31; }
PARAMETRIZE { type = TYPE_ICE; hidden = TRUE; foeType = TYPE_STEEL; foeSpecies = SPECIES_KLINK; hp = 30; atk = 22; def = 30; spAtk = 31; spDef = 31; speed = 31; }
PARAMETRIZE { type = TYPE_ICE; hidden = TRUE; foeType = TYPE_STEEL; foeSpecies = SPECIES_KLINK; hp = 30; atk = 31; def = 30; spAtk = 31; spDef = 31; speed = 31; }
PARAMETRIZE { type = TYPE_MYSTERY; hidden = FALSE; }
PARAMETRIZE { type = TYPE_DRAGON; hidden = TRUE; foeType = TYPE_STEEL; foeSpecies = SPECIES_KLINK; hp = 30; atk = 2; def = 31; spAtk = 31; spDef = 31; speed = 31; }
PARAMETRIZE { type = TYPE_DRAGON; hidden = TRUE; foeType = TYPE_STEEL; foeSpecies = SPECIES_KLINK; hp = 30; atk = 15; def = 31; spAtk = 31; spDef = 31; speed = 31; }
PARAMETRIZE { type = TYPE_DRAGON; hidden = TRUE; foeType = TYPE_STEEL; foeSpecies = SPECIES_KLINK; hp = 30; atk = 22; def = 31; spAtk = 31; spDef = 31; speed = 31; }
PARAMETRIZE { type = TYPE_DRAGON; hidden = TRUE; foeType = TYPE_STEEL; foeSpecies = SPECIES_KLINK; hp = 30; atk = 31; def = 31; spAtk = 31; spDef = 31; speed = 31; }
PARAMETRIZE { type = TYPE_DARK; hidden = TRUE; foeType = TYPE_DARK; foeSpecies = SPECIES_UMBREON; hp = 31; atk = 3; def = 31; spAtk = 31; spDef = 31; speed = 31; }
PARAMETRIZE { type = TYPE_DARK; hidden = TRUE; foeType = TYPE_DARK; foeSpecies = SPECIES_UMBREON; hp = 31; atk = 15; def = 31; spAtk = 31; spDef = 31; speed = 31; }
PARAMETRIZE { type = TYPE_DARK; hidden = TRUE; foeType = TYPE_DARK; foeSpecies = SPECIES_UMBREON; hp = 31; atk = 23; def = 31; spAtk = 31; spDef = 31; speed = 31; }
PARAMETRIZE { type = TYPE_DARK; hidden = TRUE; foeType = TYPE_DARK; foeSpecies = SPECIES_UMBREON; hp = 31; atk = 31; def = 31; spAtk = 31; spDef = 31; speed = 31; }
// Any type after Dark shouldn't be part of Hidden Power officially.
for (j = TYPE_DARK + 1; j < NUMBER_OF_MON_TYPES; j++) {
PARAMETRIZE { type = j; hidden = FALSE; }
}
GIVEN {
if (hidden) {
ASSUME(gTypeEffectivenessTable[type][foeType] == UQ_4_12(0.5)); // Foe's Type resists
ASSUME(gSpeciesInfo[foeSpecies].types[0] == gSpeciesInfo[foeSpecies].types[1]); // Foe's pure type
ASSUME(gSpeciesInfo[foeSpecies].types[0] == foeType); // Foe is the resisted type
PLAYER(SPECIES_DUNSPARCE) { HPIV(hp); AttackIV(atk); DefenseIV(def); SpAttackIV(spAtk); SpDefenseIV(spDef); SpeedIV(speed); }
} else {
PLAYER(SPECIES_DUNSPARCE);
}
OPPONENT(foeSpecies);
} WHEN {
TURN { MOVE(player, MOVE_HIDDEN_POWER); }
} SCENE {
// Only test valid Hidden Power types
if (hidden) {
ANIMATION(ANIM_TYPE_MOVE, MOVE_HIDDEN_POWER, player);
HP_BAR(opponent);
MESSAGE("It's not very effective…");
}
}
}
TO_DO_BATTLE_TEST("Hidden Power's power is determined by IVs before Gen6");

View file

@ -21,6 +21,57 @@ SINGLE_BATTLE_TEST("Tera Blast changes from Normal-type to the user's Tera Type"
} }
} }
SINGLE_BATTLE_TEST("Tera Blast has correct effectiveness for every Tera Type")
{
u32 species;
u32 type;
PARAMETRIZE { species = SPECIES_CHIKORITA; type = TYPE_FLYING; }
PARAMETRIZE { species = SPECIES_CHIKORITA; type = TYPE_POISON; }
PARAMETRIZE { species = SPECIES_CHIKORITA; type = TYPE_FIRE; }
PARAMETRIZE { species = SPECIES_CHIKORITA; type = TYPE_BUG; }
PARAMETRIZE { species = SPECIES_CHIKORITA; type = TYPE_ICE; }
PARAMETRIZE { species = SPECIES_CYNDAQUIL; type = TYPE_GROUND; }
PARAMETRIZE { species = SPECIES_CYNDAQUIL; type = TYPE_ROCK; }
PARAMETRIZE { species = SPECIES_CYNDAQUIL; type = TYPE_WATER; }
PARAMETRIZE { species = SPECIES_GASTLY; type = TYPE_NORMAL; }
PARAMETRIZE { species = SPECIES_GASTLY; type = TYPE_GHOST; }
PARAMETRIZE { species = SPECIES_GASTLY; type = TYPE_PSYCHIC; }
PARAMETRIZE { species = SPECIES_TOTODILE; type = TYPE_GRASS; }
PARAMETRIZE { species = SPECIES_TOTODILE; type = TYPE_ELECTRIC; }
PARAMETRIZE { species = SPECIES_DRATINI; type = TYPE_DRAGON; }
PARAMETRIZE { species = SPECIES_DRATINI; type = TYPE_FAIRY; }
PARAMETRIZE { species = SPECIES_SNEASEL; type = TYPE_FIGHTING; }
PARAMETRIZE { species = SPECIES_SNEASEL; type = TYPE_STEEL; }
PARAMETRIZE { species = SPECIES_ABRA; type = TYPE_DARK; }
GIVEN {
ASSUME(gSpeciesInfo[SPECIES_CHIKORITA].types[0] == TYPE_GRASS);
ASSUME(gSpeciesInfo[SPECIES_CHIKORITA].types[1] == TYPE_GRASS);
ASSUME(gSpeciesInfo[SPECIES_CYNDAQUIL].types[0] == TYPE_FIRE);
ASSUME(gSpeciesInfo[SPECIES_CYNDAQUIL].types[1] == TYPE_FIRE);
ASSUME(gSpeciesInfo[SPECIES_GASTLY].types[0] == TYPE_GHOST);
ASSUME(gSpeciesInfo[SPECIES_GASTLY].types[1] == TYPE_POISON);
ASSUME(gSpeciesInfo[SPECIES_TOTODILE].types[0] == TYPE_WATER);
ASSUME(gSpeciesInfo[SPECIES_TOTODILE].types[1] == TYPE_WATER);
ASSUME(gSpeciesInfo[SPECIES_DRATINI].types[0] == TYPE_DRAGON);
ASSUME(gSpeciesInfo[SPECIES_DRATINI].types[1] == TYPE_DRAGON);
ASSUME(gSpeciesInfo[SPECIES_SNEASEL].types[0] == TYPE_DARK);
ASSUME(gSpeciesInfo[SPECIES_SNEASEL].types[1] == TYPE_ICE);
ASSUME(gSpeciesInfo[SPECIES_ABRA].types[0] == TYPE_PSYCHIC);
ASSUME(gSpeciesInfo[SPECIES_ABRA].types[1] == TYPE_PSYCHIC);
PLAYER(SPECIES_WOBBUFFET) { TeraType(type); }
OPPONENT(species);
} WHEN {
TURN { MOVE(player, MOVE_TERA_BLAST, tera: TRUE); }
} SCENE {
if (species == SPECIES_GASTLY && type == TYPE_NORMAL)
MESSAGE("It doesn't affect Foe Gastly…");
else
MESSAGE("It's super effective!");
}
}
SINGLE_BATTLE_TEST("Tera Blast becomes a physical move if the user is Terastallized and has a higher Attack stat", s16 damage) SINGLE_BATTLE_TEST("Tera Blast becomes a physical move if the user is Terastallized and has a higher Attack stat", s16 damage)
{ {
bool32 tera; bool32 tera;

View file

@ -33,11 +33,11 @@ TEST("Terastallization type defaults to primary or secondary type")
|| teraType == gSpeciesInfo[SPECIES_PIDGEY].types[1]); || teraType == gSpeciesInfo[SPECIES_PIDGEY].types[1]);
} }
TEST("Terastallization type can be set to any type") TEST("Terastallization type can be set to any type except TYPE_NONE")
{ {
u32 i, teraType; u32 i, teraType;
struct Pokemon mon; struct Pokemon mon;
for (i = 0; i < NUMBER_OF_MON_TYPES; i++) for (i = 1; i < NUMBER_OF_MON_TYPES; i++)
{ {
PARAMETRIZE { teraType = i; } PARAMETRIZE { teraType = i; }
} }
@ -46,6 +46,23 @@ TEST("Terastallization type can be set to any type")
EXPECT_EQ(teraType, GetMonData(&mon, MON_DATA_TERA_TYPE)); EXPECT_EQ(teraType, GetMonData(&mon, MON_DATA_TERA_TYPE));
} }
TEST("Terastallization type is reset to the default types when setting Tera Type back to TYPE_NONE")
{
u32 i, teraType, typeNone;
struct Pokemon mon;
for (i = 1; i < NUMBER_OF_MON_TYPES; i++)
{
PARAMETRIZE { teraType = i; typeNone = TYPE_NONE; }
}
CreateMon(&mon, SPECIES_PIDGEY, 100, 0, FALSE, 0, OT_ID_PRESET, 0);
SetMonData(&mon, MON_DATA_TERA_TYPE, &teraType);
EXPECT_EQ(teraType, GetMonData(&mon, MON_DATA_TERA_TYPE));
SetMonData(&mon, MON_DATA_TERA_TYPE, &typeNone);
typeNone = GetMonData(&mon, MON_DATA_TERA_TYPE);
EXPECT(typeNone == gSpeciesInfo[SPECIES_PIDGEY].types[0]
|| typeNone == gSpeciesInfo[SPECIES_PIDGEY].types[1]);
}
TEST("Shininess independent from PID and OTID") TEST("Shininess independent from PID and OTID")
{ {
u32 pid, otId, data; u32 pid, otId, data;

View file

@ -1717,6 +1717,48 @@ void Speed_(u32 sourceLine, u32 speed)
DATA.explicitSpeeds[DATA.currentSide] |= 1 << DATA.currentPartyIndex; DATA.explicitSpeeds[DATA.currentSide] |= 1 << DATA.currentPartyIndex;
} }
void HPIV_(u32 sourceLine, u32 hpIV)
{
INVALID_IF(!DATA.currentMon, "HP IV outside of PLAYER/OPPONENT");
INVALID_IF(hpIV > MAX_PER_STAT_IVS, "Illegal HP IV: %d", hpIV);
SetMonData(DATA.currentMon, MON_DATA_HP_IV, &hpIV);
}
void AttackIV_(u32 sourceLine, u32 attackIV)
{
INVALID_IF(!DATA.currentMon, "Attack IV outside of PLAYER/OPPONENT");
INVALID_IF(attackIV > MAX_PER_STAT_IVS, "Illegal attack IV: %d", attackIV);
SetMonData(DATA.currentMon, MON_DATA_ATK_IV, &attackIV);
}
void DefenseIV_(u32 sourceLine, u32 defenseIV)
{
INVALID_IF(!DATA.currentMon, "Defense IV outside of PLAYER/OPPONENT");
INVALID_IF(defenseIV > MAX_PER_STAT_IVS, "Illegal defense IV: %d", defenseIV);
SetMonData(DATA.currentMon, MON_DATA_DEF_IV, &defenseIV);
}
void SpAttackIV_(u32 sourceLine, u32 spAttackIV)
{
INVALID_IF(!DATA.currentMon, "SpAttack IV outside of PLAYER/OPPONENT");
INVALID_IF(spAttackIV > MAX_PER_STAT_IVS, "Illegal special attack IV: %d", spAttackIV);
SetMonData(DATA.currentMon, MON_DATA_SPATK_IV, &spAttackIV);
}
void SpDefenseIV_(u32 sourceLine, u32 spDefenseIV)
{
INVALID_IF(!DATA.currentMon, "SpDefense IV outside of PLAYER/OPPONENT");
INVALID_IF(spDefenseIV > MAX_PER_STAT_IVS, "Illegal special defense IV: %d", spDefenseIV);
SetMonData(DATA.currentMon, MON_DATA_SPDEF_IV, &spDefenseIV);
}
void SpeedIV_(u32 sourceLine, u32 speedIV)
{
INVALID_IF(!DATA.currentMon, "Speed IV outside of PLAYER/OPPONENT");
INVALID_IF(speedIV > MAX_PER_STAT_IVS, "Illegal speed IV: %d", speedIV);
SetMonData(DATA.currentMon, MON_DATA_SPEED_IV, &speedIV);
}
void Item_(u32 sourceLine, u32 item) void Item_(u32 sourceLine, u32 item)
{ {
INVALID_IF(!DATA.currentMon, "Item outside of PLAYER/OPPONENT"); INVALID_IF(!DATA.currentMon, "Item outside of PLAYER/OPPONENT");