diff --git a/include/data.h b/include/data.h index ad3cf4ec1e..1d2a1291f9 100644 --- a/include/data.h +++ b/include/data.h @@ -114,7 +114,8 @@ struct TypeInfo u16 damageCategory:2; // Used for B_PHYSICAL_SPECIAL_SPLIT <= GEN_3 u16 useSecondTypeIconPalette:1; u16 isSpecialCaseType:1; - u16 padding:12; + u16 isHiddenPowerType:1; // Changing this for any type will change the distribution of all Hidden Power types from vanilla. + u16 padding:11; const u32 *const paletteTMHM; //u16 enhanceItem; //u16 berry; diff --git a/src/battle_main.c b/src/battle_main.c index 1a0da73142..1938cef20c 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -5966,12 +5966,15 @@ u32 GetDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler, u8 *ateBoost) | ((GetMonData(mon, MON_DATA_SPDEF_IV) & 1) << 5); } - // Subtract 6 instead of 1 below because 5 types are excluded (TYPE_NONE, TYPE_NORMAL, TYPE_MYSTERY, TYPE_FAIRY and TYPE_STELLAR) - // The final + 2 skips past TYPE_NONE and Normal. - moveType = ((NUMBER_OF_MON_TYPES - 6) * typeBits) / 63 + 2; - if (moveType >= TYPE_MYSTERY) - moveType++; - return ((moveType | F_DYNAMIC_TYPE_IGNORE_PHYSICALITY) & 0x3F); + u32 hpTypes[NUMBER_OF_MON_TYPES] = {0}; + u32 i, hpTypeCount = 0; + for (i = 0; i < NUMBER_OF_MON_TYPES; i++) + { + if (gTypesInfo[i].isHiddenPowerType) + hpTypes[hpTypeCount++] = i; + } + moveType = ((hpTypeCount - 1) * typeBits) / 63; + return ((hpTypes[moveType] | F_DYNAMIC_TYPE_IGNORE_PHYSICALITY) & 0x3F); } break; case EFFECT_CHANGE_TYPE_ON_ITEM: diff --git a/src/data/types_info.h b/src/data/types_info.h index d14012ed5c..ea962b4a44 100644 --- a/src/data/types_info.h +++ b/src/data/types_info.h @@ -40,10 +40,12 @@ const uq4_12_t gTypeEffectivenessTable[NUMBER_OF_MON_TYPES][NUMBER_OF_MON_TYPES] #undef ______ #undef X -// .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. +// Notes regarding custom data: +// - The "generic" field 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. +// - Changing "isHiddenPowerType" for any type will change the distribution of all Hidden Power types from vanilla. const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = { [TYPE_NONE] = @@ -56,6 +58,7 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = .paletteTMHM = gItemIconPalette_NormalTMHM, .useSecondTypeIconPalette = FALSE, .isSpecialCaseType = TRUE, + .isHiddenPowerType = FALSE, }, [TYPE_NORMAL] = { @@ -69,6 +72,7 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = .paletteTMHM = gItemIconPalette_NormalTMHM, .useSecondTypeIconPalette = FALSE, .isSpecialCaseType = FALSE, + .isHiddenPowerType = FALSE, //.enhanceItem = ITEM_SILK_SCARF, //.berry = ITEM_CHILAN_BERRY, //.gem = ITEM_NORMAL_GEM, @@ -88,6 +92,7 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = .paletteTMHM = gItemIconPalette_FightingTMHM, .useSecondTypeIconPalette = FALSE, .isSpecialCaseType = FALSE, + .isHiddenPowerType = TRUE, //.enhanceItem = ITEM_BLACK_BELT, //.berry = ITEM_CHOPLE_BERRY, //.gem = ITEM_FIGHTING_GEM, @@ -109,6 +114,7 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = .paletteTMHM = gItemIconPalette_FlyingTMHM, .useSecondTypeIconPalette = FALSE, .isSpecialCaseType = FALSE, + .isHiddenPowerType = TRUE, //.enhanceItem = ITEM_SHARP_BEAK, //.berry = ITEM_COBA_BERRY, //.gem = ITEM_FLYING_GEM, @@ -130,6 +136,7 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = .paletteTMHM = gItemIconPalette_PoisonTMHM, .useSecondTypeIconPalette = FALSE, .isSpecialCaseType = FALSE, + .isHiddenPowerType = TRUE, //.enhanceItem = ITEM_POISON_BARB, //.berry = ITEM_KEBIA_BERRY, //.gem = ITEM_POISON_GEM, @@ -151,6 +158,7 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = .paletteTMHM = gItemIconPalette_GroundTMHM, .useSecondTypeIconPalette = FALSE, .isSpecialCaseType = FALSE, + .isHiddenPowerType = TRUE, //.enhanceItem = ITEM_SOFT_SAND, //.berry = ITEM_SHUCA_BERRY, //.gem = ITEM_GROUND_GEM, @@ -172,6 +180,7 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = .paletteTMHM = gItemIconPalette_RockTMHM, .useSecondTypeIconPalette = FALSE, .isSpecialCaseType = FALSE, + .isHiddenPowerType = TRUE, //.enhanceItem = ITEM_HARD_STONE, //.berry = ITEM_CHARTI_BERRY, //.gem = ITEM_ROCK_GEM, @@ -193,6 +202,7 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = .paletteTMHM = gItemIconPalette_BugTMHM, .useSecondTypeIconPalette = FALSE, .isSpecialCaseType = FALSE, + .isHiddenPowerType = TRUE, //.enhanceItem = ITEM_SILVER_POWDER, //.berry = ITEM_TANGA_BERRY, //.gem = ITEM_BUG_GEM, @@ -214,6 +224,7 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = .paletteTMHM = gItemIconPalette_GhostTMHM, .useSecondTypeIconPalette = FALSE, .isSpecialCaseType = FALSE, + .isHiddenPowerType = TRUE, //.enhanceItem = ITEM_SPELL_TAG, //.berry = ITEM_KASIB_BERRY, //.gem = ITEM_GHOST_GEM, @@ -235,6 +246,7 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = .paletteTMHM = gItemIconPalette_SteelTMHM, .useSecondTypeIconPalette = FALSE, .isSpecialCaseType = FALSE, + .isHiddenPowerType = TRUE, //.enhanceItem = ITEM_METAL_COAT, //.berry = ITEM_BABIRI_BERRY, //.gem = ITEM_STEEL_GEM, @@ -253,6 +265,7 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = .damageCategory = DAMAGE_CATEGORY_SPECIAL, .useSecondTypeIconPalette = FALSE, .isSpecialCaseType = TRUE, + .isHiddenPowerType = FALSE, }, [TYPE_FIRE] = { @@ -266,6 +279,7 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = .paletteTMHM = gItemIconPalette_FireTMHM, .useSecondTypeIconPalette = TRUE, .isSpecialCaseType = FALSE, + .isHiddenPowerType = TRUE, //.enhanceItem = ITEM_CHARCOAL, //.berry = ITEM_OCCA_BERRY, //.gem = ITEM_FIRE_GEM, @@ -287,6 +301,7 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = .paletteTMHM = gItemIconPalette_WaterTMHM, .useSecondTypeIconPalette = TRUE, .isSpecialCaseType = FALSE, + .isHiddenPowerType = TRUE, //.enhanceItem = ITEM_MYSTIC_WATER, //.berry = ITEM_PASSHO_BERRY, //.gem = ITEM_WATER_GEM, @@ -308,6 +323,7 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = .paletteTMHM = gItemIconPalette_GrassTMHM, .useSecondTypeIconPalette = TRUE, .isSpecialCaseType = FALSE, + .isHiddenPowerType = TRUE, //.enhanceItem = ITEM_MIRACLE_SEED, //.berry = ITEM_RINDO_BERRY, //.gem = ITEM_GRASS_GEM, @@ -329,6 +345,7 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = .paletteTMHM = gItemIconPalette_ElectricTMHM, .useSecondTypeIconPalette = TRUE, .isSpecialCaseType = FALSE, + .isHiddenPowerType = TRUE, //.enhanceItem = ITEM_MAGNET, //.berry = ITEM_WACAN_BERRY, //.gem = ITEM_ELECTRIC_GEM, @@ -350,6 +367,7 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = .paletteTMHM = gItemIconPalette_PsychicTMHM, .useSecondTypeIconPalette = TRUE, .isSpecialCaseType = FALSE, + .isHiddenPowerType = TRUE, //.enhanceItem = ITEM_TWISTED_SPOON, //.berry = ITEM_PAYAPA_BERRY, //.gem = ITEM_PSYCHIC_GEM, @@ -371,6 +389,7 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = .paletteTMHM = gItemIconPalette_IceTMHM, .useSecondTypeIconPalette = TRUE, .isSpecialCaseType = FALSE, + .isHiddenPowerType = TRUE, //.enhanceItem = ITEM_NEVER_MELT_ICE, //.berry = ITEM_YACHE_BERRY, //.gem = ITEM_ICE_GEM, @@ -392,6 +411,7 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = .paletteTMHM = gItemIconPalette_DragonTMHM, .useSecondTypeIconPalette = TRUE, .isSpecialCaseType = FALSE, + .isHiddenPowerType = TRUE, //.enhanceItem = ITEM_DRAGON_FANG, //.berry = ITEM_HABAN_BERRY, //.gem = ITEM_DRAGON_GEM, @@ -413,6 +433,7 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = .paletteTMHM = gItemIconPalette_DarkTMHM, .useSecondTypeIconPalette = TRUE, .isSpecialCaseType = FALSE, + .isHiddenPowerType = TRUE, //.enhanceItem = ITEM_BLACK_GLASSES, //.berry = ITEM_COLBUR_BERRY, //.gem = ITEM_DARK_GEM, @@ -434,6 +455,7 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = .paletteTMHM = gItemIconPalette_FairyTMHM, .useSecondTypeIconPalette = TRUE, .isSpecialCaseType = FALSE, + .isHiddenPowerType = FALSE, //.enhanceItem = ITEM_FAIRY_FEATHER, //.berry = ITEM_ROSELI_BERRY, //.gem = ITEM_FAIRY_GEM, @@ -454,6 +476,7 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = .paletteTMHM = gItemIconPalette_NormalTMHM, // failsafe .useSecondTypeIconPalette = FALSE, .isSpecialCaseType = TRUE, + .isHiddenPowerType = FALSE, // .teraShard = ITEM_STELLAR_TERA_SHARD, }, }; diff --git a/test/battle/move_effect/hidden_power.c b/test/battle/move_effect/hidden_power.c index 8ec63c21a7..3b2af8d99a 100644 --- a/test/battle/move_effect/hidden_power.c +++ b/test/battle/move_effect/hidden_power.c @@ -1,6 +1,33 @@ #include "global.h" #include "test/battle.h" +ASSUMPTIONS +{ + ASSUME(gTypesInfo[TYPE_NONE].isHiddenPowerType == FALSE); + ASSUME(gTypesInfo[TYPE_NORMAL].isHiddenPowerType == FALSE); + ASSUME(gTypesInfo[TYPE_FIGHTING].isHiddenPowerType == TRUE); + ASSUME(gTypesInfo[TYPE_FLYING].isHiddenPowerType == TRUE); + ASSUME(gTypesInfo[TYPE_POISON].isHiddenPowerType == TRUE); + ASSUME(gTypesInfo[TYPE_GROUND].isHiddenPowerType == TRUE); + ASSUME(gTypesInfo[TYPE_ROCK].isHiddenPowerType == TRUE); + ASSUME(gTypesInfo[TYPE_BUG].isHiddenPowerType == TRUE); + ASSUME(gTypesInfo[TYPE_GHOST].isHiddenPowerType == TRUE); + ASSUME(gTypesInfo[TYPE_STEEL].isHiddenPowerType == TRUE); + ASSUME(gTypesInfo[TYPE_MYSTERY].isHiddenPowerType == FALSE); + ASSUME(gTypesInfo[TYPE_FIRE].isHiddenPowerType == TRUE); + ASSUME(gTypesInfo[TYPE_WATER].isHiddenPowerType == TRUE); + ASSUME(gTypesInfo[TYPE_GRASS].isHiddenPowerType == TRUE); + ASSUME(gTypesInfo[TYPE_ELECTRIC].isHiddenPowerType == TRUE); + ASSUME(gTypesInfo[TYPE_PSYCHIC].isHiddenPowerType == TRUE); + ASSUME(gTypesInfo[TYPE_ICE].isHiddenPowerType == TRUE); + ASSUME(gTypesInfo[TYPE_DRAGON].isHiddenPowerType == TRUE); + ASSUME(gTypesInfo[TYPE_DARK].isHiddenPowerType == TRUE); + // Any type after Dark shouldn't be part of Hidden Power officially. + for (u32 j = TYPE_DARK + 1; j < NUMBER_OF_MON_TYPES; j++) { + ASSUME(gTypesInfo[j].isHiddenPowerType == FALSE); + } +} + // 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") {