Merge branch 'upcoming' into berryexpansion
This commit is contained in:
commit
1662dc3478
@ -980,7 +980,7 @@
|
||||
.byte 0xbb
|
||||
.endm
|
||||
|
||||
.macro maxattackhalvehp failInstr:req
|
||||
.macro halvehp failInstr:req
|
||||
.byte 0xbc
|
||||
.4byte \failInstr
|
||||
.endm
|
||||
|
||||
@ -2025,3 +2025,33 @@
|
||||
callnative CreateTrainerPartyForPlayer
|
||||
trainerbattle_no_intro \trainer2, NULL
|
||||
.endm
|
||||
|
||||
@ Sets VAR_RESULT to TRUE if stat can be hyper trained, or to
|
||||
@ FALSE otherwise.
|
||||
.macro canhypertrain stat:req, slot:req
|
||||
callnative CanHyperTrain
|
||||
.byte \stat
|
||||
.2byte \slot
|
||||
.endm
|
||||
|
||||
@ Hyper Trains a stat.
|
||||
.macro hypertrain stat:req, slot:req
|
||||
callnative HyperTrain
|
||||
.byte \stat
|
||||
.2byte \slot
|
||||
.endm
|
||||
|
||||
@ Sets VAR_RESULT to TRUE if the Pokemon has the Gigantamax Factor,
|
||||
@ or to FALSE otherwise.
|
||||
.macro hasgigantamaxfactor slot:req
|
||||
callnative HasGigantamaxFactor
|
||||
.2byte \slot
|
||||
.endm
|
||||
|
||||
@ Toggles the Gigantamax Factor for a Pokemon.
|
||||
@ Fails for Melmetal (vanilla behavior).
|
||||
@ Sets VAR_RESULT to TRUE if it succeeds, and FALSE otherwise.
|
||||
.macro togglegigantamaxfactor slot:req
|
||||
callnative ToggleGigantamaxFactor
|
||||
.2byte \slot
|
||||
.endm
|
||||
|
||||
@ -860,21 +860,21 @@ gBattleAnims_Moves::
|
||||
.4byte Move_MATCHA_GOTCHA
|
||||
.4byte Move_SYRUP_BOMB
|
||||
.4byte Move_IVY_CUDGEL
|
||||
.4byte Move_833
|
||||
.4byte Move_834
|
||||
.4byte Move_835
|
||||
.4byte Move_836
|
||||
.4byte Move_837
|
||||
.4byte Move_838
|
||||
.4byte Move_839
|
||||
.4byte Move_840
|
||||
.4byte Move_841
|
||||
.4byte Move_842
|
||||
.4byte Move_843
|
||||
.4byte Move_844
|
||||
.4byte Move_845
|
||||
.4byte Move_846
|
||||
.4byte Move_847
|
||||
.4byte Move_ELECTRO_SHOT
|
||||
.4byte Move_TERA_STARSTORM
|
||||
.4byte Move_FICKLE_BEAM
|
||||
.4byte Move_BURNING_BULWARK
|
||||
.4byte Move_THUNDERCLAP
|
||||
.4byte Move_MIGHTY_CLEAVE
|
||||
.4byte Move_TACHYON_CUTTER
|
||||
.4byte Move_HARD_PRESS
|
||||
.4byte Move_DRAGON_CHEER
|
||||
.4byte Move_ALLURING_VOICE
|
||||
.4byte Move_TEMPER_FLARE
|
||||
.4byte Move_SUPERCELL_SLAM
|
||||
.4byte Move_PSYCHIC_NOISE
|
||||
.4byte Move_UPPER_HAND
|
||||
.4byte Move_MALIGNANT_CHAIN
|
||||
@@@@ Z MOVES
|
||||
.4byte Move_BREAKNECK_BLITZ
|
||||
.4byte Move_ALL_OUT_PUMMELING
|
||||
@ -16977,6 +16977,21 @@ Move_HYDRO_STEAM::
|
||||
Move_BLOOD_MOON::
|
||||
Move_MATCHA_GOTCHA::
|
||||
Move_IVY_CUDGEL::
|
||||
Move_ELECTRO_SHOT::
|
||||
Move_TERA_STARSTORM::
|
||||
Move_FICKLE_BEAM::
|
||||
Move_BURNING_BULWARK::
|
||||
Move_THUNDERCLAP::
|
||||
Move_MIGHTY_CLEAVE::
|
||||
Move_TACHYON_CUTTER::
|
||||
Move_HARD_PRESS::
|
||||
Move_DRAGON_CHEER::
|
||||
Move_ALLURING_VOICE::
|
||||
Move_TEMPER_FLARE::
|
||||
Move_SUPERCELL_SLAM::
|
||||
Move_PSYCHIC_NOISE::
|
||||
Move_UPPER_HAND::
|
||||
Move_MALIGNANT_CHAIN::
|
||||
end @to do
|
||||
|
||||
@@@@@@@@@@@@@@@@@@@@@@@ GEN 1-3 @@@@@@@@@@@@@@@@@@@@@@@
|
||||
|
||||
@ -440,6 +440,41 @@ gBattleScriptsForMoveEffects::
|
||||
.4byte BattleScript_EffectBrickBreak @ EFFECT_RAGING_BULL
|
||||
.4byte BattleScript_EffectHit @ EFFECT_RAGE_FIST
|
||||
.4byte BattleScript_EffectDoodle @ EFFECT_DOODLE
|
||||
.4byte BattleScript_EffectFilletAway @ EFFECT_FILLET_AWAY
|
||||
|
||||
BattleScript_EffectFilletAway:
|
||||
attackcanceler
|
||||
attackstring
|
||||
ppreduce
|
||||
jumpifstat BS_ATTACKER, CMP_LESS_THAN, STAT_ATK, MAX_STAT_STAGE, BattleScript_FilletAwayTryAttack
|
||||
jumpifstat BS_ATTACKER, CMP_LESS_THAN, STAT_SPATK, MAX_STAT_STAGE, BattleScript_FilletAwayTryAttack
|
||||
jumpifstat BS_ATTACKER, CMP_EQUAL, STAT_SPEED, MAX_STAT_STAGE, BattleScript_ButItFailed
|
||||
BattleScript_FilletAwayTryAttack::
|
||||
halvehp BattleScript_ButItFailed
|
||||
orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE
|
||||
attackanimation
|
||||
waitanimation
|
||||
setbyte sSTAT_ANIM_PLAYED, FALSE
|
||||
playstatchangeanimation BS_ATTACKER, BIT_ATK | BIT_SPATK | BIT_SPEED, STAT_CHANGE_BY_TWO
|
||||
setstatchanger STAT_ATK, 2, FALSE
|
||||
statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_CHANGE_ALLOW_PTR, BattleScript_FilletAwayTrySpAtk
|
||||
printfromtable gStatUpStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
BattleScript_FilletAwayTrySpAtk::
|
||||
setstatchanger STAT_SPATK, 2, FALSE
|
||||
statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_CHANGE_ALLOW_PTR, BattleScript_FilletAwayTrySpeed
|
||||
printfromtable gStatUpStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
BattleScript_FilletAwayTrySpeed::
|
||||
setstatchanger STAT_SPEED, 2, FALSE
|
||||
statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_CHANGE_ALLOW_PTR, BattleScript_FilletAwayEnd
|
||||
printfromtable gStatUpStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
BattleScript_FilletAwayEnd::
|
||||
bichalfword gMoveResultFlags, MOVE_RESULT_NO_EFFECT
|
||||
healthbarupdate BS_ATTACKER
|
||||
datahpupdate BS_ATTACKER
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_EffectDoodle:
|
||||
attackcanceler
|
||||
@ -5343,12 +5378,16 @@ BattleScript_EffectBellyDrum::
|
||||
attackcanceler
|
||||
attackstring
|
||||
ppreduce
|
||||
maxattackhalvehp BattleScript_ButItFailed
|
||||
jumpifstat BS_ATTACKER, CMP_EQUAL, STAT_ATK, MAX_STAT_STAGE, BattleScript_ButItFailed
|
||||
halvehp BattleScript_ButItFailed
|
||||
orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE
|
||||
attackanimation
|
||||
waitanimation
|
||||
healthbarupdate BS_ATTACKER
|
||||
datahpupdate BS_ATTACKER
|
||||
playstatchangeanimation BS_ATTACKER, BIT_ATK, STAT_CHANGE_BY_TWO
|
||||
setstatchanger STAT_ATK, MAX_STAT_STAGE, FALSE
|
||||
statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_CHANGE_ALLOW_PTR, BattleScript_MoveEnd
|
||||
printstring STRINGID_PKMNCUTHPMAXEDATTACK
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
@ -64,3 +64,11 @@ EventScript_AccessHallOfFame::
|
||||
waitstate
|
||||
goto EventScript_AccessPC
|
||||
end
|
||||
|
||||
EventScript_AccessPokemonBoxLink::
|
||||
playse SE_PC_LOGIN
|
||||
msgbox gText_StorageSystemOpened, MSGBOX_DEFAULT
|
||||
special ShowPokemonStorageSystemPC
|
||||
waitstate
|
||||
goto EventScript_TurnOffPC
|
||||
end
|
||||
|
||||
18
graphics/items/icon_palettes/metal_alloy.pal
Normal file
18
graphics/items/icon_palettes/metal_alloy.pal
Normal file
@ -0,0 +1,18 @@
|
||||
JASC-PAL
|
||||
0100
|
||||
15
|
||||
0 0 0
|
||||
249 253 255
|
||||
224 232 243
|
||||
169 163 177
|
||||
136 130 156
|
||||
178 194 220
|
||||
123 146 180
|
||||
162 164 202
|
||||
153 208 247
|
||||
85 96 152
|
||||
136 150 213
|
||||
186 212 247
|
||||
90 118 181
|
||||
154 195 255
|
||||
49 49 49
|
||||
BIN
graphics/items/icons/metal_alloy.png
Normal file
BIN
graphics/items/icons/metal_alloy.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 299 B |
@ -65,7 +65,7 @@ struct ResourceFlags
|
||||
struct DisableStruct
|
||||
{
|
||||
u32 transformedMonPersonality;
|
||||
u32 transformedMonOtId;
|
||||
bool8 transformedMonShininess;
|
||||
u16 disabledMove;
|
||||
u16 encoredMove;
|
||||
u8 protectUses:4;
|
||||
@ -1066,7 +1066,7 @@ extern u8 gBattlerStatusSummaryTaskId[MAX_BATTLERS_COUNT];
|
||||
extern u8 gBattlerInMenuId;
|
||||
extern bool8 gDoingBattleAnim;
|
||||
extern u32 gTransformedPersonalities[MAX_BATTLERS_COUNT];
|
||||
extern u32 gTransformedOtIds[MAX_BATTLERS_COUNT];
|
||||
extern bool8 gTransformedShininess[MAX_BATTLERS_COUNT];
|
||||
extern u8 gPlayerDpadHoldFrames;
|
||||
extern struct BattleSpriteData *gBattleSpritesDataPtr;
|
||||
extern struct MonSpritesGfx *gMonSpritesGfxPtr;
|
||||
|
||||
@ -159,7 +159,7 @@ void PrepareAffineAnimInTaskData(struct Task *task, u8 spriteId, const union Aff
|
||||
bool8 RunAffineAnimFromTaskData(struct Task *task);
|
||||
void AnimThrowProjectile(struct Sprite *sprite);
|
||||
void GetBgDataForTransform(struct BattleAnimBgData *dest, u8 battlerId);
|
||||
u8 CreateAdditionalMonSpriteForMoveAnim(u16 species, bool8 isBackpic, u8 id, s16 x, s16 y, u8 subpriority, u32 personality, u32 trainerId, u32 battlerId);
|
||||
u8 CreateAdditionalMonSpriteForMoveAnim(u16 species, bool8 isBackpic, u8 id, s16 x, s16 y, u8 subpriority, u32 personality, bool8 isShiny, u32 battlerId);
|
||||
void ResetSpriteRotScale_PreserveAffine(struct Sprite *sprite);
|
||||
void Trade_MoveSelectedMonToTarget(struct Sprite *sprite);
|
||||
void DestroyAnimVisualTaskAndDisableBlend(u8 taskId);
|
||||
|
||||
@ -84,8 +84,6 @@ extern const struct OamData gOamData_BattleSpriteOpponentSide;
|
||||
extern const struct OamData gOamData_BattleSpritePlayerSide;
|
||||
extern const u8 gTypeNames[NUMBER_OF_MON_TYPES][TYPE_NAME_LENGTH + 1];
|
||||
extern const struct TrainerMoney gTrainerMoneyTable[];
|
||||
extern const u8 gAbilityNames[][ABILITY_NAME_LENGTH + 1];
|
||||
extern const u8 *const gAbilityDescriptionPointers[];
|
||||
|
||||
extern const u8 gStatusConditionString_PoisonJpn[8];
|
||||
extern const u8 gStatusConditionString_SleepJpn[8];
|
||||
|
||||
@ -113,6 +113,7 @@
|
||||
#define B_QUICK_GUARD GEN_LATEST // In Gen5 only, Wide Guard has a chance to fail if used consecutively.
|
||||
#define B_IMPRISON GEN_LATEST // In Gen5+, Imprison doesn't fail if opposing pokemon don't have any moves the user knows.
|
||||
#define B_ALLY_SWITCH_FAIL_CHANCE GEN_LATEST // In Gen9, using Ally Switch consecutively decreases the chance of success for each consecutive use.
|
||||
#define B_SKETCH_BANS GEN_LATEST // In Gen9+, Sketch is unable to copy more moves than in previous generations.
|
||||
|
||||
// Ability settings
|
||||
#define B_EXPANDED_ABILITY_NAMES TRUE // If TRUE, ability names are increased from 12 characters to 16 characters.
|
||||
|
||||
@ -14,6 +14,8 @@
|
||||
#define I_USE_EVO_HELD_ITEMS_FROM_BAG FALSE // If TRUE, items such as Razor Claw or Electirizer will be usable from the bag to evolve a Pokémon just like in LA.
|
||||
#define I_TYPE_BOOST_POWER GEN_LATEST // In Gen4+, all regular type boosting held items had their power increased from 10% to 20%. eg. Charcoal
|
||||
#define I_SELL_VALUE_FRACTION GEN_LATEST // In Gen9+, items sell for 1/4 of their value instead of 1/2.
|
||||
#define I_PRICE GEN_LATEST // Some items have varied in value across generations.
|
||||
#define I_BERRY_PRICE GEN_7 // Since Berries have become unplantable (Gen8+), their price has gone up.
|
||||
|
||||
// TM config
|
||||
#define I_REUSABLE_TMS FALSE // In Gen5-8, TMs are reusable. Setting this to TRUE will make all vanilla TMs reusable, though they can also be cherry-picked by setting their importance to 1.
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
// PC settings
|
||||
#define OW_PC_PRESS_B GEN_LATEST // In Gen4, pressing B when holding a Pokémon is equivalent to placing it. In Gen3, it gives the "You're holding a Pokémon!" error.
|
||||
#define OW_PC_JAPAN_WALDA_ICONS TRUE // In the US release of Emerald, the Cross, Bolt, and Plusle icons for Walda's wallpapers were left blank from the Japan release. Setting this to TRUE will restore them.
|
||||
#define OW_PC_HEAL GEN_LATEST // In Gen8+, Pokémon are not healed when deposited in the PC.
|
||||
|
||||
// Berry settings
|
||||
// These generational defines only make a distinction for Berries!
|
||||
|
||||
@ -32,6 +32,7 @@
|
||||
#define P_LEGENDARY_PERFECT_IVS GEN_LATEST // Since Gen 6, Legendaries, Mythicals and Ultra Beasts found in the wild or given through gifts have at least 3 perfect IVs.
|
||||
#define P_EV_CAP GEN_LATEST // Since Gen 6, the max EVs per stat is 252 instead of 255.
|
||||
#define P_CATCH_CURVE GEN_LATEST // Since Gen 6, the capture rate curve was changed to make pokeballs more effective on lower level pokemon
|
||||
#define P_SHOW_TERA_TYPE GEN_LATEST // Since Gen 9, the Tera Type is shown on the summary screen.
|
||||
|
||||
// Flag settings
|
||||
// To use the following features in scripting, replace the 0s with the flag ID you're assigning it to.
|
||||
|
||||
@ -332,10 +332,10 @@
|
||||
#define ABILITY_EMBODY_ASPECT_CORNERSTONE 304
|
||||
#define ABILITY_TOXIC_CHAIN 305
|
||||
#define ABILITY_SUPERSWEET_SYRUP 306
|
||||
#define ABILITY_307 307
|
||||
#define ABILITY_308 308
|
||||
#define ABILITY_309 309
|
||||
#define ABILITY_310 310
|
||||
#define ABILITY_TERA_SHIFT 307
|
||||
#define ABILITY_TERA_SHELL 308
|
||||
#define ABILITY_TERAFORM_ZERO 309
|
||||
#define ABILITY_POISON_PUPPETEER 310
|
||||
|
||||
#define ABILITIES_COUNT_GEN9 311
|
||||
|
||||
|
||||
@ -104,7 +104,10 @@
|
||||
#define B_OUTCOME_LINK_BATTLE_RAN (1 << 7) // 128
|
||||
|
||||
// Non-volatile status conditions
|
||||
// These persist remain outside of battle and after switching out
|
||||
// These remain outside of battle and after switching out.
|
||||
// If a new STATUS1 is added here, it should also be added to
|
||||
// sCompressedStatuses in src/pokemon.c or else it will be lost outside
|
||||
// of battle.
|
||||
#define STATUS1_NONE 0
|
||||
#define STATUS1_SLEEP (1 << 0 | 1 << 1 | 1 << 2) // First 3 bits (Number of turns to sleep)
|
||||
#define STATUS1_SLEEP_TURN(num) ((num) << 0) // Just for readability (or if rearranging statuses)
|
||||
|
||||
@ -417,7 +417,8 @@
|
||||
#define EFFECT_RAGING_BULL 411
|
||||
#define EFFECT_RAGE_FIST 412
|
||||
#define EFFECT_DOODLE 413
|
||||
#define EFFECT_FILLET_AWAY 414
|
||||
|
||||
#define NUM_BATTLE_MOVE_EFFECTS 414
|
||||
#define NUM_BATTLE_MOVE_EFFECTS 415
|
||||
|
||||
#endif // GUARD_CONSTANTS_BATTLE_MOVE_EFFECTS_H
|
||||
|
||||
@ -24,6 +24,8 @@
|
||||
#define VERSION_PLATINUM 12
|
||||
#define VERSION_GAMECUBE 15
|
||||
|
||||
#define NUM_VERSIONS 15
|
||||
|
||||
#define LANGUAGE_JAPANESE 1
|
||||
#define LANGUAGE_ENGLISH 2
|
||||
#define LANGUAGE_FRENCH 3
|
||||
|
||||
@ -986,8 +986,8 @@
|
||||
#define ITEM_SWIFT_MOCHI 811
|
||||
#define ITEM_FRESH_START_MOCHI 812
|
||||
#define ITEM_GLIMMERING_CHARM 813
|
||||
#define ITEM_814 814 // TWV0YWwgQWxsb3k=
|
||||
#define ITEM_815 815 // U3RlbGxhciBUZXJhIFNoYXJk
|
||||
#define ITEM_METAL_ALLOY 814
|
||||
#define ITEM_STELLAR_TERA_SHARD 815
|
||||
|
||||
#define ITEMS_COUNT 816
|
||||
#define ITEM_FIELD_ARROW ITEMS_COUNT
|
||||
|
||||
@ -886,25 +886,27 @@
|
||||
#define MOVE_MAGICAL_TORQUE 826
|
||||
#define MOVE_PSYBLADE 827
|
||||
#define MOVE_HYDRO_STEAM 828
|
||||
// The Teal Mask Moves
|
||||
#define MOVE_BLOOD_MOON 829
|
||||
#define MOVE_MATCHA_GOTCHA 830
|
||||
#define MOVE_SYRUP_BOMB 831
|
||||
#define MOVE_IVY_CUDGEL 832
|
||||
#define MOVE_833 833
|
||||
#define MOVE_834 834
|
||||
#define MOVE_835 835
|
||||
#define MOVE_836 836
|
||||
#define MOVE_837 837
|
||||
#define MOVE_838 838
|
||||
#define MOVE_839 839
|
||||
#define MOVE_840 840
|
||||
#define MOVE_841 841
|
||||
#define MOVE_842 842
|
||||
#define MOVE_843 843
|
||||
#define MOVE_844 844
|
||||
#define MOVE_845 845
|
||||
#define MOVE_846 846
|
||||
#define MOVE_847 847
|
||||
// The Indigo Disk Moves
|
||||
#define MOVE_ELECTRO_SHOT 833
|
||||
#define MOVE_TERA_STARSTORM 834
|
||||
#define MOVE_FICKLE_BEAM 835
|
||||
#define MOVE_BURNING_BULWARK 836
|
||||
#define MOVE_THUNDERCLAP 837
|
||||
#define MOVE_MIGHTY_CLEAVE 838
|
||||
#define MOVE_TACHYON_CUTTER 839
|
||||
#define MOVE_HARD_PRESS 840
|
||||
#define MOVE_DRAGON_CHEER 841
|
||||
#define MOVE_ALLURING_VOICE 842
|
||||
#define MOVE_TEMPER_FLARE 843
|
||||
#define MOVE_SUPERCELL_SLAM 844
|
||||
#define MOVE_PSYCHIC_NOISE 845
|
||||
#define MOVE_UPPER_HAND 846
|
||||
#define MOVE_MALIGNANT_CHAIN 847
|
||||
|
||||
#define MOVES_COUNT_GEN9 848
|
||||
|
||||
@ -1014,6 +1016,8 @@
|
||||
|
||||
#define MOVES_COUNT_DYNAMAX (LAST_MAX_MOVE + 1)
|
||||
|
||||
#define MOVES_COUNT_ALL MOVES_COUNT_DYNAMAX
|
||||
|
||||
// Used for checks for moves affected by Disable, Mimic, etc.
|
||||
#define MOVE_UNAVAILABLE 0xFFFF
|
||||
|
||||
|
||||
@ -146,6 +146,8 @@
|
||||
#define MIN_LEVEL 1
|
||||
#define MAX_LEVEL 100
|
||||
|
||||
#define MAX_DYNAMAX_LEVEL 10
|
||||
|
||||
#define OT_ID_PLAYER_ID 0
|
||||
#define OT_ID_PRESET 1
|
||||
#define OT_ID_RANDOM_NO_SHINY 2
|
||||
|
||||
@ -107,7 +107,9 @@ struct ContestPokemon
|
||||
u8 sheen;
|
||||
u8 highestRank;
|
||||
bool8 gameCleared;
|
||||
u8 unused[10];
|
||||
u8 isShiny:1;
|
||||
u8 unused1:7;
|
||||
u8 unused2[9];
|
||||
u32 personality;
|
||||
u32 otId;
|
||||
};
|
||||
@ -125,6 +127,8 @@ struct ContestMoveAnimData
|
||||
u16 species;
|
||||
u16 targetSpecies;
|
||||
bool8 hasTargetAnim:1;
|
||||
u8 isShiny:1;
|
||||
u8 targetIsShiny:1;
|
||||
u8 contestant;
|
||||
u32 personality;
|
||||
u32 otId;
|
||||
|
||||
@ -66,6 +66,8 @@ struct TrainerMon
|
||||
u8 nature : 5;
|
||||
bool8 gender : 2;
|
||||
bool8 isShiny : 1;
|
||||
u8 dynamaxLevel : 4;
|
||||
bool8 gigantamaxFactor : 1;
|
||||
};
|
||||
|
||||
#define TRAINER_PARTY(partyArray) partyArray, .partySize = ARRAY_COUNT(partyArray)
|
||||
|
||||
@ -515,6 +515,7 @@ extern const u8 MauvilleCity_PokemonCenter_1F_Text_HotSpringsStory[];
|
||||
extern const u8 LittlerootTown_BrendansHouse_2F_EventScript_PC[];
|
||||
extern const u8 LittlerootTown_MaysHouse_2F_EventScript_PC[];
|
||||
extern const u8 EventScript_PC[];
|
||||
extern const u8 EventScript_AccessPokemonBoxLink[];
|
||||
extern const u8 EventScript_TestSignpostMsg[];
|
||||
extern const u8 EventScript_HiddenItemScript[];
|
||||
extern const u8 EventScript_TV[];
|
||||
|
||||
@ -129,8 +129,8 @@
|
||||
#define CAT(a, b) CAT_(a, b)
|
||||
#define CAT_(a, b) a ## b
|
||||
|
||||
#define STR(a) STR_(a)
|
||||
#define STR_(a) #a
|
||||
#define STR(...) STR_(__VA_ARGS__)
|
||||
#define STR_(...) #__VA_ARGS__
|
||||
|
||||
// Converts a string to a compound literal, essentially making it a pointer to const u8
|
||||
#define COMPOUND_STRING(str) (const u8[]) _(str)
|
||||
@ -738,7 +738,8 @@ struct ContestWinner
|
||||
u8 contestCategory;
|
||||
u8 monName[POKEMON_NAME_LENGTH + 1];
|
||||
u8 trainerName[PLAYER_NAME_LENGTH + 1];
|
||||
u8 contestRank;
|
||||
u8 contestRank:7;
|
||||
bool8 isShiny:1;
|
||||
//u8 padding;
|
||||
};
|
||||
|
||||
|
||||
@ -785,6 +785,8 @@ extern const u32 gItemIcon_UnremarkableTeacup[];
|
||||
extern const u32 gItemIconPalette_UnremarkableTeacup[];
|
||||
extern const u32 gItemIcon_MasterpieceTeacup[];
|
||||
extern const u32 gItemIconPalette_MasterpieceTeacup[];
|
||||
extern const u32 gItemIcon_MetalAlloy[];
|
||||
extern const u32 gItemIconPalette_MetalAlloy[];
|
||||
// Nectars
|
||||
extern const u32 gItemIcon_RedNectar[];
|
||||
extern const u32 gItemIconPalette_RedNectar[];
|
||||
|
||||
@ -62,7 +62,7 @@ u16 CountTotalItemQuantityInBag(u16 itemId);
|
||||
bool8 AddPyramidBagItem(u16 itemId, u16 count);
|
||||
bool8 RemovePyramidBagItem(u16 itemId, u16 count);
|
||||
const u8 *ItemId_GetName(u16 itemId);
|
||||
u16 ItemId_GetPrice(u16 itemId);
|
||||
u32 ItemId_GetPrice(u16 itemId);
|
||||
u32 ItemId_GetHoldEffect(u32 itemId);
|
||||
u32 ItemId_GetHoldEffectParam(u32 itemId);
|
||||
const u8 *ItemId_GetDescription(u16 itemId);
|
||||
|
||||
@ -7,18 +7,21 @@ void ItemUseOutOfBattle_Rod(u8);
|
||||
void ItemUseOutOfBattle_Itemfinder(u8);
|
||||
void ItemUseOutOfBattle_PokeblockCase(u8);
|
||||
void ItemUseOutOfBattle_CoinCase(u8);
|
||||
void ItemUseOutOfBattle_PokemonBoxLink(u8);
|
||||
void ItemUseOutOfBattle_PowderJar(u8);
|
||||
void ItemUseOutOfBattle_SSTicket(u8);
|
||||
void ItemUseOutOfBattle_WailmerPail(u8);
|
||||
void ItemUseOutOfBattle_Medicine(u8);
|
||||
void ItemUseOutOfBattle_AbilityCapsule(u8);
|
||||
void ItemUseOutOfBattle_AbilityPatch(u8);
|
||||
void ItemUseOutOfBattle_Mint(u8);
|
||||
void ItemUseOutOfBattle_ResetEVs(u8);
|
||||
void ItemUseOutOfBattle_ReduceEV(u8);
|
||||
void ItemUseOutOfBattle_SacredAsh(u8);
|
||||
void ItemUseOutOfBattle_PPRecovery(u8);
|
||||
void ItemUseOutOfBattle_PPUp(u8);
|
||||
void ItemUseOutOfBattle_RareCandy(u8);
|
||||
void ItemUseOutOfBattle_DynamaxCandy(u8);
|
||||
void ItemUseOutOfBattle_TMHM(u8);
|
||||
void ItemUseOutOfBattle_Repel(u8);
|
||||
void ItemUseOutOfBattle_Lure(u8);
|
||||
|
||||
@ -53,6 +53,7 @@ void ItemUseCB_BattleChooseMove(u8 taskId, TaskFunc task);
|
||||
void ItemUseCB_Medicine(u8 taskId, TaskFunc task);
|
||||
void ItemUseCB_AbilityCapsule(u8 taskId, TaskFunc task);
|
||||
void ItemUseCB_AbilityPatch(u8 taskId, TaskFunc task);
|
||||
void ItemUseCB_Mint(u8 taskId, TaskFunc task);
|
||||
void ItemUseCB_ResetEVs(u8 taskId, TaskFunc task);
|
||||
void ItemUseCB_ReduceEV(u8 taskId, TaskFunc task);
|
||||
void ItemUseCB_PPRecovery(u8 taskId, TaskFunc task);
|
||||
@ -62,6 +63,7 @@ bool8 MonKnowsMove(struct Pokemon *mon, u16 move);
|
||||
bool8 BoxMonKnowsMove(struct BoxPokemon *boxMon, u16 move);
|
||||
void ItemUseCB_TMHM(u8 taskId, TaskFunc task);
|
||||
void ItemUseCB_RareCandy(u8 taskId, TaskFunc task);
|
||||
void ItemUseCB_DynamaxCandy(u8 taskId, TaskFunc task);
|
||||
void ItemUseCB_SacredAsh(u8 taskId, TaskFunc task);
|
||||
void ItemUseCB_EvolutionStone(u8 taskId, TaskFunc task);
|
||||
void ItemUseCB_FormChange(u8 taskId, TaskFunc task);
|
||||
|
||||
@ -21,7 +21,7 @@ enum
|
||||
void ResetPokedex(void);
|
||||
u16 GetNationalPokedexCount(u8);
|
||||
u16 GetHoennPokedexCount(u8);
|
||||
u8 DisplayCaughtMonDexPage(u16 species, u32 otId, u32 personality);
|
||||
u8 DisplayCaughtMonDexPage(u16 species, bool32 isShiny, u32 personality);
|
||||
s8 GetSetPokedexFlag(u16 nationalNum, u8 caseId);
|
||||
u16 CreateMonSpriteFromNationalDexNumber(u16, s16, s16, u16);
|
||||
bool16 HasAllHoennMons(void);
|
||||
|
||||
@ -12,8 +12,8 @@
|
||||
// Property labels for Get(Box)MonData / Set(Box)MonData
|
||||
enum {
|
||||
MON_DATA_PERSONALITY,
|
||||
MON_DATA_STATUS,
|
||||
MON_DATA_OT_ID,
|
||||
MON_DATA_NICKNAME,
|
||||
MON_DATA_LANGUAGE,
|
||||
MON_DATA_SANITY_IS_BAD_EGG,
|
||||
MON_DATA_SANITY_HAS_SPECIES,
|
||||
@ -21,7 +21,12 @@ enum {
|
||||
MON_DATA_OT_NAME,
|
||||
MON_DATA_MARKINGS,
|
||||
MON_DATA_CHECKSUM,
|
||||
MON_DATA_HP,
|
||||
MON_DATA_IS_SHINY,
|
||||
MON_DATA_HIDDEN_NATURE,
|
||||
MON_DATA_HP_LOST,
|
||||
MON_DATA_ENCRYPT_SEPARATOR,
|
||||
MON_DATA_NICKNAME,
|
||||
MON_DATA_SPECIES,
|
||||
MON_DATA_HELD_ITEM,
|
||||
MON_DATA_MOVE1,
|
||||
@ -66,9 +71,7 @@ enum {
|
||||
MON_DATA_CUTE_RIBBON,
|
||||
MON_DATA_SMART_RIBBON,
|
||||
MON_DATA_TOUGH_RIBBON,
|
||||
MON_DATA_STATUS,
|
||||
MON_DATA_LEVEL,
|
||||
MON_DATA_HP,
|
||||
MON_DATA_MAX_HP,
|
||||
MON_DATA_ATK,
|
||||
MON_DATA_DEF,
|
||||
@ -90,7 +93,6 @@ enum {
|
||||
MON_DATA_NATIONAL_RIBBON,
|
||||
MON_DATA_EARTH_RIBBON,
|
||||
MON_DATA_WORLD_RIBBON,
|
||||
MON_DATA_UNUSED_RIBBONS,
|
||||
MON_DATA_MODERN_FATEFUL_ENCOUNTER,
|
||||
MON_DATA_KNOWN_MOVES,
|
||||
MON_DATA_RIBBON_COUNT,
|
||||
@ -100,87 +102,116 @@ enum {
|
||||
MON_DATA_SPEED2,
|
||||
MON_DATA_SPATK2,
|
||||
MON_DATA_SPDEF2,
|
||||
MON_DATA_HYPER_TRAINED_HP,
|
||||
MON_DATA_HYPER_TRAINED_ATK,
|
||||
MON_DATA_HYPER_TRAINED_DEF,
|
||||
MON_DATA_HYPER_TRAINED_SPEED,
|
||||
MON_DATA_HYPER_TRAINED_SPATK,
|
||||
MON_DATA_HYPER_TRAINED_SPDEF,
|
||||
MON_DATA_IS_SHADOW,
|
||||
MON_DATA_DYNAMAX_LEVEL,
|
||||
MON_DATA_GIGANTAMAX_FACTOR,
|
||||
MON_DATA_TERA_TYPE,
|
||||
};
|
||||
|
||||
struct PokemonSubstruct0
|
||||
{
|
||||
/*0x00*/ u16 species;
|
||||
/*0x02*/ u16 heldItem;
|
||||
/*0x04*/ u32 experience;
|
||||
/*0x08*/ u8 ppBonuses;
|
||||
/*0x09*/ u8 friendship;
|
||||
/*0x0A*/ u16 pokeball:5; //31 balls
|
||||
u16 filler:11;
|
||||
}; /* size = 12 */
|
||||
u16 species:11; // 2047 species.
|
||||
u16 teraType:5; // 30 types.
|
||||
u16 heldItem:10; // 1023 items.
|
||||
u16 unused_02:6;
|
||||
u32 experience:21;
|
||||
u32 nickname11:8; // 11th character of nickname.
|
||||
u32 unused_04:3;
|
||||
u8 ppBonuses;
|
||||
u8 friendship;
|
||||
u16 pokeball:6; // 63 balls.
|
||||
u16 nickname12:8; // 12th character of nickname.
|
||||
u16 unused_0A:2;
|
||||
};
|
||||
|
||||
struct PokemonSubstruct1
|
||||
{
|
||||
/*0x00*/ u16 moves[MAX_MON_MOVES];
|
||||
/*0x08*/ u8 pp[MAX_MON_MOVES];
|
||||
}; /* size = 12 */
|
||||
u16 move1:11; // 2047 moves.
|
||||
u16 unused_00:5;
|
||||
u16 move2:11; // 2047 moves.
|
||||
u16 unused_02:5;
|
||||
u16 move3:11; // 2047 moves.
|
||||
u16 unused_04:5;
|
||||
u16 move4:11; // 2047 moves.
|
||||
u16 unused_06:3;
|
||||
u16 hyperTrainedHP:1;
|
||||
u16 hyperTrainedAttack:1;
|
||||
u8 pp1:7; // 127 PP.
|
||||
u8 hyperTrainedDefense:1;
|
||||
u8 pp2:7; // 127 PP.
|
||||
u8 hyperTrainedSpeed:1;
|
||||
u8 pp3:7; // 127 PP.
|
||||
u8 hyperTrainedSpAttack:1;
|
||||
u8 pp4:7; // 127 PP.
|
||||
u8 hyperTrainedSpDefense:1;
|
||||
};
|
||||
|
||||
struct PokemonSubstruct2
|
||||
{
|
||||
/*0x00*/ u8 hpEV;
|
||||
/*0x01*/ u8 attackEV;
|
||||
/*0x02*/ u8 defenseEV;
|
||||
/*0x03*/ u8 speedEV;
|
||||
/*0x04*/ u8 spAttackEV;
|
||||
/*0x05*/ u8 spDefenseEV;
|
||||
/*0x06*/ u8 cool;
|
||||
/*0x07*/ u8 beauty;
|
||||
/*0x08*/ u8 cute;
|
||||
/*0x09*/ u8 smart;
|
||||
/*0x0A*/ u8 tough;
|
||||
/*0x0B*/ u8 sheen;
|
||||
}; /* size = 12 */
|
||||
u8 hpEV;
|
||||
u8 attackEV;
|
||||
u8 defenseEV;
|
||||
u8 speedEV;
|
||||
u8 spAttackEV;
|
||||
u8 spDefenseEV;
|
||||
u8 cool;
|
||||
u8 beauty;
|
||||
u8 cute;
|
||||
u8 smart;
|
||||
u8 tough;
|
||||
u8 sheen;
|
||||
};
|
||||
|
||||
struct PokemonSubstruct3
|
||||
{
|
||||
/* 0x00 */ u8 pokerus;
|
||||
/* 0x01 */ u8 metLocation;
|
||||
u8 pokerus;
|
||||
u8 metLocation;
|
||||
u16 metLevel:7;
|
||||
u16 metGame:4;
|
||||
u16 dynamaxLevel:4;
|
||||
u16 otGender:1;
|
||||
u32 hpIV:5;
|
||||
u32 attackIV:5;
|
||||
u32 defenseIV:5;
|
||||
u32 speedIV:5;
|
||||
u32 spAttackIV:5;
|
||||
u32 spDefenseIV:5;
|
||||
u32 isEgg:1;
|
||||
u32 gigantamaxFactor:1;
|
||||
u32 coolRibbon:3; // Stores the highest contest rank achieved in the Cool category.
|
||||
u32 beautyRibbon:3; // Stores the highest contest rank achieved in the Beauty category.
|
||||
u32 cuteRibbon:3; // Stores the highest contest rank achieved in the Cute category.
|
||||
u32 smartRibbon:3; // Stores the highest contest rank achieved in the Smart category.
|
||||
u32 toughRibbon:3; // Stores the highest contest rank achieved in the Tough category.
|
||||
u32 championRibbon:1; // Given when defeating the Champion. Because both RSE and FRLG use it, later generations don't specify from which region it comes from.
|
||||
u32 winningRibbon:1; // Given at the Battle Tower's Level 50 challenge by winning a set of seven battles that extends the current streak to 56 or more.
|
||||
u32 victoryRibbon:1; // Given at the Battle Tower's Level 100 challenge by winning a set of seven battles that extends the current streak to 56 or more.
|
||||
u32 artistRibbon:1; // Given at the Contest Hall by winning a Master Rank contest with at least 800 points, and agreeing to have the Pokémon's portrait placed in the museum after being offered.
|
||||
u32 effortRibbon:1; // Given at Slateport's market to Pokémon with maximum EVs.
|
||||
u32 marineRibbon:1; // Never distributed.
|
||||
u32 landRibbon:1; // Never distributed.
|
||||
u32 skyRibbon:1; // Never distributed.
|
||||
u32 countryRibbon:1; // Distributed during Pokémon Festa '04 and '05 to tournament winners.
|
||||
u32 nationalRibbon:1; // Given to purified Shadow Pokémon in Colosseum/XD.
|
||||
u32 earthRibbon:1; // Given to teams that have beaten Mt. Battle's 100-battle challenge in Colosseum/XD.
|
||||
u32 worldRibbon:1; // Distributed during Pokémon Festa '04 and '05 to tournament winners.
|
||||
u32 isShadow:1;
|
||||
u32 unused_0B:1;
|
||||
u32 abilityNum:2;
|
||||
|
||||
/* 0x02 */ u16 metLevel:7;
|
||||
/* 0x02 */ u16 metGame:4;
|
||||
/* 0x03 */ u16 unused1:4;
|
||||
/* 0x03 */ u16 otGender:1;
|
||||
|
||||
/* 0x04 */ u32 hpIV:5;
|
||||
/* 0x04 */ u32 attackIV:5;
|
||||
/* 0x05 */ u32 defenseIV:5;
|
||||
/* 0x05 */ u32 speedIV:5;
|
||||
/* 0x05 */ u32 spAttackIV:5;
|
||||
/* 0x06 */ u32 spDefenseIV:5;
|
||||
/* 0x07 */ u32 isEgg:1;
|
||||
/* 0x07 */ u32 unused2:1;
|
||||
|
||||
/* 0x08 */ u32 coolRibbon:3; // Stores the highest contest rank achieved in the Cool category.
|
||||
/* 0x08 */ u32 beautyRibbon:3; // Stores the highest contest rank achieved in the Beauty category.
|
||||
/* 0x08 */ u32 cuteRibbon:3; // Stores the highest contest rank achieved in the Cute category.
|
||||
/* 0x09 */ u32 smartRibbon:3; // Stores the highest contest rank achieved in the Smart category.
|
||||
/* 0x09 */ u32 toughRibbon:3; // Stores the highest contest rank achieved in the Tough category.
|
||||
/* 0x09 */ u32 championRibbon:1; // Given when defeating the Champion. Because both RSE and FRLG use it, later generations don't specify from which region it comes from.
|
||||
/* 0x0A */ u32 winningRibbon:1; // Given at the Battle Tower's Level 50 challenge by winning a set of seven battles that extends the current streak to 56 or more.
|
||||
/* 0x0A */ u32 victoryRibbon:1; // Given at the Battle Tower's Level 100 challenge by winning a set of seven battles that extends the current streak to 56 or more.
|
||||
/* 0x0A */ u32 artistRibbon:1; // Given at the Contest Hall by winning a Master Rank contest with at least 800 points, and agreeing to have the Pokémon's portrait placed in the museum after being offered.
|
||||
/* 0x0A */ u32 effortRibbon:1; // Given at Slateport's market to Pokémon with maximum EVs.
|
||||
/* 0x0A */ u32 marineRibbon:1; // Never distributed.
|
||||
/* 0x0A */ u32 landRibbon:1; // Never distributed.
|
||||
/* 0x0A */ u32 skyRibbon:1; // Never distributed.
|
||||
/* 0x0A */ u32 countryRibbon:1; // Distributed during Pokémon Festa '04 and '05 to tournament winners.
|
||||
/* 0x0B */ u32 nationalRibbon:1; // Given to purified Shadow Pokémon in Colosseum/XD.
|
||||
/* 0x0B */ u32 earthRibbon:1; // Given to teams that have beaten Mt. Battle's 100-battle challenge in Colosseum/XD.
|
||||
/* 0x0B */ u32 worldRibbon:1; // Distributed during Pokémon Festa '04 and '05 to tournament winners.
|
||||
/* 0x0B */ u32 unusedRibbons:2; // Discarded in Gen 4.
|
||||
/* 0x0B */ u32 abilityNum:2;
|
||||
|
||||
// The functionality of this bit changed in FRLG:
|
||||
// In RS, this bit does nothing, is never set, & is accidentally unset when hatching Eggs.
|
||||
// In FRLG & Emerald, this controls Mew & Deoxys obedience and whether they can be traded.
|
||||
// If set, a Pokémon is a fateful encounter in FRLG's summary screen if hatched & for all Pokémon in Gen 4+ summary screens.
|
||||
// Set for in-game event island legendaries, events distributed after a certain date, & Pokémon from XD: Gale of Darkness.
|
||||
// Not to be confused with METLOC_FATEFUL_ENCOUNTER.
|
||||
/* 0x0B */ u32 modernFatefulEncounter:1;
|
||||
// The functionality of this bit changed in FRLG:
|
||||
// In RS, this bit does nothing, is never set, & is accidentally unset when hatching Eggs.
|
||||
// In FRLG & Emerald, this controls Mew & Deoxys obedience and whether they can be traded.
|
||||
// If set, a Pokémon is a fateful encounter in FRLG's summary screen if hatched & for all Pokémon in Gen 4+ summary screens.
|
||||
// Set for in-game event island legendaries, events distributed after a certain date, & Pokémon from XD: Gale of Darkness.
|
||||
// Not to be confused with METLOC_FATEFUL_ENCOUNTER.
|
||||
u32 modernFatefulEncounter:1;
|
||||
};
|
||||
|
||||
// Number of bytes in the largest Pokémon substruct.
|
||||
@ -205,17 +236,21 @@ struct BoxPokemon
|
||||
{
|
||||
u32 personality;
|
||||
u32 otId;
|
||||
u8 nickname[POKEMON_NAME_LENGTH];
|
||||
u8 language;
|
||||
u8 nickname[min(10, POKEMON_NAME_LENGTH)];
|
||||
u8 language:3;
|
||||
u8 hiddenNatureModifier:5; // 31 natures.
|
||||
u8 isBadEgg:1;
|
||||
u8 hasSpecies:1;
|
||||
u8 isEgg:1;
|
||||
u8 blockBoxRS:1; // Unused, but Pokémon Box Ruby & Sapphire will refuse to deposit a Pokémon with this flag set
|
||||
u8 unused:4;
|
||||
u8 blockBoxRS:1; // Unused, but Pokémon Box Ruby & Sapphire will refuse to deposit a Pokémon with this flag set.
|
||||
u8 unused_13:4;
|
||||
u8 otName[PLAYER_NAME_LENGTH];
|
||||
u8 markings;
|
||||
u8 markings:4;
|
||||
u8 compressedStatus:4;
|
||||
u16 checksum;
|
||||
u16 unknown;
|
||||
u16 hpLost:14; // 16383 HP.
|
||||
u16 shinyModifier:1;
|
||||
u16 unused_1E:1;
|
||||
|
||||
union
|
||||
{
|
||||
@ -301,6 +336,7 @@ struct BattlePokemon
|
||||
/*0x51*/ u32 status2;
|
||||
/*0x55*/ u32 otId;
|
||||
/*0x59*/ u8 metLevel;
|
||||
/*0x5A*/ bool8 isShiny;
|
||||
};
|
||||
|
||||
struct Evolution
|
||||
@ -468,10 +504,17 @@ struct BattleMove
|
||||
u32 encoreBanned:1;
|
||||
u32 parentalBondBanned:1;
|
||||
u32 skyBattleBanned:1;
|
||||
u32 sketchBanned:1;
|
||||
|
||||
u16 argument;
|
||||
};
|
||||
|
||||
struct Ability
|
||||
{
|
||||
u8 name[ABILITY_NAME_LENGTH + 1];
|
||||
const u8 *description;
|
||||
};
|
||||
|
||||
#define SPINDA_SPOT_WIDTH 16
|
||||
#define SPINDA_SPOT_HEIGHT 16
|
||||
|
||||
@ -540,6 +583,7 @@ extern const u16 gUnionRoomFacilityClasses[];
|
||||
extern const struct SpriteTemplate gBattlerSpriteTemplates[];
|
||||
extern const s8 gNatureStatTable[][5];
|
||||
extern const u32 sExpCandyExperienceTable[];
|
||||
extern const struct Ability gAbilities[];
|
||||
|
||||
void ZeroBoxMonData(struct BoxPokemon *boxMon);
|
||||
void ZeroMonData(struct Pokemon *mon);
|
||||
@ -673,7 +717,7 @@ void PlayBattleBGM(void);
|
||||
void PlayMapChosenOrBattleBGM(u16 songId);
|
||||
void CreateTask_PlayMapChosenOrBattleBGM(u16 songId);
|
||||
const u32 *GetMonFrontSpritePal(struct Pokemon *mon);
|
||||
const u32 *GetMonSpritePalFromSpeciesAndPersonality(u16 species, u32 otId, u32 personality);
|
||||
const u32 *GetMonSpritePalFromSpeciesAndPersonality(u16 species, bool32 isShiny, u32 personality);
|
||||
bool8 IsMoveHM(u16 move);
|
||||
bool8 IsMonSpriteNotFlipped(u16 species);
|
||||
s8 GetMonFlavorRelation(struct Pokemon *mon, u8 flavor);
|
||||
@ -685,7 +729,6 @@ void BoxMonRestorePP(struct BoxPokemon *boxMon);
|
||||
void SetMonPreventsSwitchingString(void);
|
||||
void SetWildMonHeldItem(void);
|
||||
bool8 IsMonShiny(struct Pokemon *mon);
|
||||
bool8 IsShinyOtIdPersonality(u32 otId, u32 personality);
|
||||
const u8 *GetTrainerPartnerName(void);
|
||||
void BattleAnimateFrontSprite(struct Sprite *sprite, u16 species, bool8 noCry, u8 panMode);
|
||||
void DoMonFrontSpriteAnimation(struct Sprite *sprite, u16 species, bool8 noCry, u8 panModeAnimFlag);
|
||||
@ -719,5 +762,7 @@ u16 SanitizeSpeciesId(u16 species);
|
||||
bool32 IsSpeciesEnabled(u16 species);
|
||||
u16 GetCryIdBySpecies(u16 species);
|
||||
u16 GetSpeciesPreEvolution(u16 species);
|
||||
void HealPokemon(struct Pokemon *mon);
|
||||
void HealBoxPokemon(struct BoxPokemon *boxMon);
|
||||
|
||||
#endif // GUARD_POKEMON_H
|
||||
|
||||
@ -849,6 +849,10 @@ struct moveWithPP {
|
||||
#define Friendship(friendship) Friendship_(__LINE__, friendship)
|
||||
#define Status1(status1) Status1_(__LINE__, status1)
|
||||
#define OTName(otName) do {static const u8 otName_[] = _(otName); OTName_(__LINE__, otName_);} while (0)
|
||||
#define DynamaxLevel(dynamaxLevel) DynamaxLevel_(__LINE__, dynamaxLevel)
|
||||
#define GigantamaxFactor(gigantamaxFactor) GigantamaxFactor_(__LINE__, gigantamaxFactor)
|
||||
#define TeraType(teraType) TeraType_(__LINE__, teraType)
|
||||
#define Shadow(isShadow) Shadow_(__LINE__, shadow)
|
||||
|
||||
void SetFlagForTest(u32 sourceLine, u16 flagId);
|
||||
void ClearFlagAfterTest(void);
|
||||
@ -875,6 +879,10 @@ void MovesWithPP_(u32 sourceLine, struct moveWithPP moveWithPP[MAX_MON_MOVES]);
|
||||
void Friendship_(u32 sourceLine, u32 friendship);
|
||||
void Status1_(u32 sourceLine, u32 status1);
|
||||
void OTName_(u32 sourceLine, const u8 *otName);
|
||||
void DynamaxLevel_(u32 sourceLine, u32 dynamaxLevel);
|
||||
void GigantamaxFactor_(u32 sourceLine, bool32 gigantamaxFactor);
|
||||
void TeraType_(u32 sourceLine, u32 teraType);
|
||||
void Shadow_(u32 sourceLine, bool32 isShadow);
|
||||
|
||||
// Created for easy use of EXPECT_MOVES, so the user can provide 1, 2, 3 or 4 moves for AI which can pass the test.
|
||||
struct FourMoves
|
||||
|
||||
48
include/test/overworld_script.h
Normal file
48
include/test/overworld_script.h
Normal file
@ -0,0 +1,48 @@
|
||||
/* Embedded DSL for testing overworld scripts in isolation.
|
||||
* The overworld is not available, so it is only possible to test
|
||||
* commands which don't affect the overworld itself, e.g. givemon can
|
||||
* be tested because it only alters gPlayerParty, but addobject cannot
|
||||
* because it affects object events (which aren't loaded).
|
||||
*
|
||||
* OVERWORLD_SCRIPT(instructions...)
|
||||
* Returns a pointer to a compiled overworld script. Cannot be used to
|
||||
* initialize global const data, although the pointer IS to const data.
|
||||
* Note that each script command must be followed by a ;, e.g.:
|
||||
* const u8 *myScript = OVERWORLD_SCRIPT(
|
||||
* random 2;
|
||||
* addvar VAR_RESULT, 1;
|
||||
* );
|
||||
*
|
||||
* RUN_OVERWORLD_SCRIPT(instructions...)
|
||||
* Runs an overworld script in the immediate script context, which means
|
||||
* that commands like waitstate are not supported.
|
||||
* RUN_OVERWORLD_SCRIPT(
|
||||
* setvar VAR_RESULT, 3;
|
||||
* );
|
||||
* EXPECT_EQ(GetVar(VAR_RESULT), 3); */
|
||||
#ifndef GUARD_TEST_OVERWORLD_SCRIPT
|
||||
#define GUARD_TEST_OVERWORLD_SCRIPT
|
||||
|
||||
#include "script.h"
|
||||
#include "test/test.h"
|
||||
|
||||
#define OVERWORLD_SCRIPT(...) \
|
||||
({ \
|
||||
const u8 *_script; \
|
||||
asm("mov %0, pc\n" \
|
||||
"b .Lend" STR(__LINE__) "\n" \
|
||||
STR(__VA_ARGS__) \
|
||||
"\n" \
|
||||
"end\n" \
|
||||
".balign 2\n" \
|
||||
".Lend" STR(__LINE__) ":\n" \
|
||||
: "=r" (_script)); \
|
||||
_script; \
|
||||
})
|
||||
|
||||
#define RUN_OVERWORLD_SCRIPT(...) RunScriptImmediately(OVERWORLD_SCRIPT(__VA_ARGS__))
|
||||
|
||||
// Make overworld script macros available.
|
||||
asm(".include \"asm/macros/event.inc\"\n");
|
||||
|
||||
#endif
|
||||
@ -59,8 +59,9 @@ extern const struct TestRunner gAssumptionsRunner;
|
||||
|
||||
struct FunctionTestRunnerState
|
||||
{
|
||||
u8 parameters;
|
||||
u8 runParameter;
|
||||
u16 parameters;
|
||||
u16 runParameter;
|
||||
u16 checkProgressParameter;
|
||||
};
|
||||
|
||||
extern const struct TestRunner gFunctionTestRunner;
|
||||
|
||||
@ -8,8 +8,8 @@
|
||||
#define F_MON_PIC_NO_AFFINE (1 << 7)
|
||||
|
||||
bool16 ResetAllPicSprites(void);
|
||||
u16 CreateMonPicSprite_Affine(u16 species, u32 otId, u32 personality, u8 flags, s16 x, s16 y, u8 paletteSlot, u16 paletteTag);
|
||||
u16 CreateMonPicSprite(u16 species, u32 otId, u32 personality, bool8 isFrontPic, s16 x, s16 y, u8 paletteSlot, u16 paletteTag);
|
||||
u16 CreateMonPicSprite_Affine(u16 species, bool8 isShiny, u32 personality, u8 flags, s16 x, s16 y, u8 paletteSlot, u16 paletteTag);
|
||||
u16 CreateMonPicSprite(u16 species, bool8 isShiny, u32 personality, bool8 isFrontPic, s16 x, s16 y, u8 paletteSlot, u16 paletteTag);
|
||||
u16 FreeAndDestroyMonPicSprite(u16 spriteId);
|
||||
u16 CreateTrainerPicSprite(u16 species, bool8 isFrontPic, s16 x, s16 y, u8 paletteSlot, u16 paletteTag);
|
||||
u16 FreeAndDestroyTrainerPicSprite(u16 spriteId);
|
||||
|
||||
@ -207,14 +207,7 @@ static void ShuffleApprenticeSpecies(void)
|
||||
for (i = 0; i < ARRAY_COUNT(species); i++)
|
||||
species[i] = i;
|
||||
|
||||
// Shuffle the possible species an arbitrary 50 times
|
||||
for (i = 0; i < 50; i++)
|
||||
{
|
||||
u8 temp;
|
||||
u8 rand1 = Random() % ARRAY_COUNT(species);
|
||||
u8 rand2 = Random() % ARRAY_COUNT(species);
|
||||
SWAP(species[rand1], species[rand2], temp);
|
||||
}
|
||||
Shuffle(species, APPRENTICE_SPECIES_COUNT, sizeof(species[0]));
|
||||
|
||||
for (i = 0; i < MULTI_PARTY_SIZE; i++)
|
||||
PLAYER_APPRENTICE.speciesIds[i] = ((species[i * 2] & 0xF) << 4) | ((species[i * 2 + 1]) & 0xF);
|
||||
@ -254,33 +247,19 @@ static void SetRandomQuestionData(void)
|
||||
u8 questionOrder[APPRENTICE_MAX_QUESTIONS + 1];
|
||||
u8 partyOrder[MULTI_PARTY_SIZE];
|
||||
u8 partySlot;
|
||||
u8 rand;
|
||||
u8 i, j;
|
||||
u8 rand1, rand2;
|
||||
u8 id;
|
||||
|
||||
for (i = 0; i < ARRAY_COUNT(partyOrder); i++)
|
||||
partyOrder[i] = i;
|
||||
|
||||
// Shuffle the party an arbitrary 10 times
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
u8 temp;
|
||||
rand1 = Random() % ARRAY_COUNT(partyOrder);
|
||||
rand2 = Random() % ARRAY_COUNT(partyOrder);
|
||||
SWAP(partyOrder[rand1], partyOrder[rand2], temp);
|
||||
}
|
||||
Shuffle(partyOrder, MULTI_PARTY_SIZE, sizeof(partyOrder[0]));
|
||||
|
||||
for (i = 0; i < ARRAY_COUNT(questionOrder); i++)
|
||||
questionOrder[i] = sQuestionPossibilities[i];
|
||||
|
||||
// Shuffle the questions an arbitrary 50 times
|
||||
for (i = 0; i < 50; i++)
|
||||
{
|
||||
u8 temp;
|
||||
rand1 = Random() % ARRAY_COUNT(questionOrder);
|
||||
rand2 = Random() % ARRAY_COUNT(questionOrder);
|
||||
SWAP(questionOrder[rand1], questionOrder[rand2], temp);
|
||||
}
|
||||
Shuffle(questionOrder, APPRENTICE_MAX_QUESTIONS + 1, sizeof(questionOrder[0]));
|
||||
|
||||
gApprenticePartyMovesData = AllocZeroed(sizeof(*gApprenticePartyMovesData));
|
||||
gApprenticePartyMovesData->moveCounter = 0;
|
||||
@ -302,16 +281,16 @@ static void SetRandomQuestionData(void)
|
||||
{
|
||||
do
|
||||
{
|
||||
rand1 = Random() % MAX_MON_MOVES;
|
||||
rand = Random() % MAX_MON_MOVES;
|
||||
for (j = 0; j < gApprenticePartyMovesData->moveCounter + 1; j++)
|
||||
{
|
||||
if (gApprenticePartyMovesData->moveSlots[id][j] == rand1)
|
||||
if (gApprenticePartyMovesData->moveSlots[id][j] == rand)
|
||||
break;
|
||||
}
|
||||
} while (j != gApprenticePartyMovesData->moveCounter + 1);
|
||||
|
||||
gApprenticePartyMovesData->moveSlots[id][gApprenticePartyMovesData->moveCounter] = rand1;
|
||||
PLAYER_APPRENTICE.questions[i].moveSlot = rand1;
|
||||
gApprenticePartyMovesData->moveSlots[id][gApprenticePartyMovesData->moveCounter] = rand;
|
||||
PLAYER_APPRENTICE.questions[i].moveSlot = rand;
|
||||
PLAYER_APPRENTICE.questions[i].data = GetRandomAlternateMove(PLAYER_APPRENTICE.questions[i].monId);
|
||||
}
|
||||
}
|
||||
|
||||
@ -143,7 +143,7 @@ static u32 GetWildAiFlags(void)
|
||||
static u32 GetAiFlags(u16 trainerId)
|
||||
{
|
||||
u32 flags = 0;
|
||||
|
||||
|
||||
if (!(gBattleTypeFlags & BATTLE_TYPE_HAS_AI) && !IsWildMonSmart())
|
||||
return 0;
|
||||
if (trainerId == 0xFFFF)
|
||||
@ -167,26 +167,26 @@ static u32 GetAiFlags(u16 trainerId)
|
||||
else
|
||||
flags = gTrainers[trainerId].aiFlags;
|
||||
}
|
||||
|
||||
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
|
||||
flags |= AI_FLAG_DOUBLE_BATTLE;
|
||||
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
void BattleAI_SetupFlags(void)
|
||||
{
|
||||
AI_THINKING_STRUCT->aiFlags[B_POSITION_PLAYER_LEFT] = 0; // player has no AI
|
||||
|
||||
|
||||
#if DEBUG_OVERWORLD_MENU == TRUE
|
||||
if (gIsDebugBattle)
|
||||
{
|
||||
AI_THINKING_STRUCT->aiFlags[B_POSITION_OPPONENT_LEFT] = gDebugAIFlags;
|
||||
AI_THINKING_STRUCT->aiFlags[B_POSITION_OPPONENT_RIGHT] = gDebugAIFlags;
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
if (IsWildMonSmart() && !(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_TRAINER)))
|
||||
{
|
||||
// smart wild AI
|
||||
@ -201,7 +201,7 @@ void BattleAI_SetupFlags(void)
|
||||
else
|
||||
AI_THINKING_STRUCT->aiFlags[B_POSITION_OPPONENT_RIGHT] = AI_THINKING_STRUCT->aiFlags[B_POSITION_OPPONENT_LEFT];
|
||||
}
|
||||
|
||||
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER)
|
||||
{
|
||||
AI_THINKING_STRUCT->aiFlags[B_POSITION_PLAYER_RIGHT] = GetAiFlags(gPartnerTrainerId - TRAINER_PARTNER(PARTNER_NONE));
|
||||
@ -1699,6 +1699,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
||||
ADJUST_SCORE(-6);
|
||||
break;
|
||||
case EFFECT_BELLY_DRUM:
|
||||
case EFFECT_FILLET_AWAY:
|
||||
if (aiData->abilities[battlerAtk] == ABILITY_CONTRARY)
|
||||
ADJUST_SCORE(-10);
|
||||
else if (aiData->hpPercents[battlerAtk] <= 60)
|
||||
@ -5043,6 +5044,7 @@ static s32 AI_Risky(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
||||
case EFFECT_FOCUS_PUNCH:
|
||||
case EFFECT_REVENGE:
|
||||
case EFFECT_TEETER_DANCE:
|
||||
case EFFECT_FILLET_AWAY:
|
||||
if (Random() & 1)
|
||||
ADJUST_SCORE(2);
|
||||
break;
|
||||
@ -5193,6 +5195,7 @@ static s32 AI_HPAware(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
||||
case EFFECT_CONVERSION_2:
|
||||
case EFFECT_SAFEGUARD:
|
||||
case EFFECT_BELLY_DRUM:
|
||||
case EFFECT_FILLET_AWAY:
|
||||
ADJUST_SCORE(-2);
|
||||
break;
|
||||
default:
|
||||
@ -5228,6 +5231,7 @@ static s32 AI_HPAware(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
||||
case EFFECT_HAIL:
|
||||
case EFFECT_SNOWSCAPE:
|
||||
case EFFECT_RAIN_DANCE:
|
||||
case EFFECT_FILLET_AWAY:
|
||||
ADJUST_SCORE(-2);
|
||||
break;
|
||||
default:
|
||||
|
||||
@ -361,6 +361,7 @@ static const u16 sEncouragedEncoreEffects[] =
|
||||
EFFECT_WATER_SPORT,
|
||||
EFFECT_DRAGON_DANCE,
|
||||
EFFECT_CAMOUFLAGE,
|
||||
EFFECT_FILLET_AWAY,
|
||||
};
|
||||
|
||||
// Functions
|
||||
@ -2126,6 +2127,7 @@ bool32 IsAttackBoostMoveEffect(u32 effect)
|
||||
case EFFECT_BELLY_DRUM:
|
||||
case EFFECT_BULK_UP:
|
||||
case EFFECT_GROWTH:
|
||||
case EFFECT_FILLET_AWAY:
|
||||
return TRUE;
|
||||
default:
|
||||
return FALSE;
|
||||
|
||||
@ -6575,12 +6575,14 @@ static void AnimTask_AllySwitchDataSwap(u8 taskId)
|
||||
SwapStructData(&gProtectStructs[battlerAtk], &gProtectStructs[battlerPartner], data, sizeof(struct ProtectStruct));
|
||||
SwapStructData(&gBattleSpritesDataPtr->battlerData[battlerAtk], &gBattleSpritesDataPtr->battlerData[battlerPartner], data, sizeof(struct BattleSpriteInfo));
|
||||
|
||||
SWAP(gBattleSpritesDataPtr->battlerData[battlerAtk].invisible, gBattleSpritesDataPtr->battlerData[battlerPartner].invisible, temp);
|
||||
SWAP(gTransformedPersonalities[battlerAtk], gTransformedPersonalities[battlerPartner], temp);
|
||||
SWAP(gTransformedOtIds[battlerAtk], gTransformedOtIds[battlerPartner], temp);
|
||||
SWAP(gTransformedShininess[battlerAtk], gTransformedShininess[battlerPartner], temp);
|
||||
SWAP(gStatuses3[battlerAtk], gStatuses3[battlerPartner], temp);
|
||||
SWAP(gStatuses4[battlerAtk], gStatuses4[battlerPartner], temp);
|
||||
SWAP(gBattleStruct->chosenMovePositions[battlerAtk], gBattleStruct->chosenMovePositions[battlerPartner], temp);
|
||||
SWAP(gChosenMoveByBattler[battlerAtk], gChosenMoveByBattler[battlerPartner], temp);
|
||||
SWAP(gLockedMoves[battlerAtk], gLockedMoves[battlerPartner], temp);
|
||||
SWAP(gBattleStruct->moveTarget[battlerAtk], gBattleStruct->moveTarget[battlerPartner], temp);
|
||||
SWAP(gMoveSelectionCursor[battlerAtk], gMoveSelectionCursor[battlerPartner], temp);
|
||||
// Swap turn order, so that all the battlers take action
|
||||
@ -6688,6 +6690,12 @@ void AnimTask_AllySwitchAttacker(u8 taskId)
|
||||
PrepareDoubleTeamAnim(taskId, ANIM_ATTACKER, TRUE);
|
||||
gSprites[gBattlerSpriteIds[gBattlerAttacker]].invisible = TRUE;
|
||||
gSprites[gBattlerSpriteIds[BATTLE_PARTNER(gBattlerAttacker)]].invisible = TRUE;
|
||||
// Edge case: Partner's sprite is invisible(i.e. after using Dig).
|
||||
if (gBattleSpritesDataPtr->battlerData[BATTLE_PARTNER(gBattlerAttacker)].invisible)
|
||||
{
|
||||
gBattleSpritesDataPtr->battlerData[BATTLE_PARTNER(gBattlerAttacker)].invisible = FALSE;
|
||||
gBattleSpritesDataPtr->battlerData[gBattlerAttacker].invisible = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
void AnimTask_AllySwitchPartner(u8 taskId)
|
||||
|
||||
@ -3255,9 +3255,8 @@ static void AnimReversalOrb_Step(struct Sprite *sprite)
|
||||
// Copies the target mon's sprite, and makes a white silhouette that shrinks away.
|
||||
void AnimTask_RolePlaySilhouette(u8 taskId)
|
||||
{
|
||||
bool8 isBackPic;
|
||||
bool8 isBackPic, isShiny;
|
||||
u32 personality;
|
||||
u32 otId;
|
||||
u16 species;
|
||||
s16 xOffset;
|
||||
u32 priority;
|
||||
@ -3269,7 +3268,7 @@ void AnimTask_RolePlaySilhouette(u8 taskId)
|
||||
{
|
||||
isBackPic = TRUE;
|
||||
personality = gContestResources->moveAnim->targetPersonality;
|
||||
otId = gContestResources->moveAnim->otId;
|
||||
isShiny = gContestResources->moveAnim->targetIsShiny;
|
||||
species = gContestResources->moveAnim->targetSpecies;
|
||||
xOffset = 20;
|
||||
priority = GetBattlerSpriteBGPriority(gBattleAnimAttacker);
|
||||
@ -3280,7 +3279,7 @@ void AnimTask_RolePlaySilhouette(u8 taskId)
|
||||
{
|
||||
isBackPic = FALSE;
|
||||
personality = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimTarget]], MON_DATA_PERSONALITY);
|
||||
otId = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimTarget]], MON_DATA_OT_ID);
|
||||
isShiny = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimTarget]], MON_DATA_IS_SHINY);
|
||||
if (gBattleSpritesDataPtr->battlerData[gBattleAnimTarget].transformSpecies == SPECIES_NONE)
|
||||
{
|
||||
if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER)
|
||||
@ -3300,7 +3299,7 @@ void AnimTask_RolePlaySilhouette(u8 taskId)
|
||||
{
|
||||
isBackPic = TRUE;
|
||||
personality = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimTarget]], MON_DATA_PERSONALITY);
|
||||
otId = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimTarget]], MON_DATA_OT_ID);
|
||||
isShiny = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimTarget]], MON_DATA_IS_SHINY);
|
||||
if (gBattleSpritesDataPtr->battlerData[gBattleAnimTarget].transformSpecies == SPECIES_NONE)
|
||||
{
|
||||
if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER)
|
||||
@ -3320,7 +3319,7 @@ void AnimTask_RolePlaySilhouette(u8 taskId)
|
||||
|
||||
coord1 = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X);
|
||||
coord2 = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y);
|
||||
spriteId = CreateAdditionalMonSpriteForMoveAnim(species, isBackPic, 0, coord1 + xOffset, coord2, 5, personality, otId, gBattleAnimTarget);
|
||||
spriteId = CreateAdditionalMonSpriteForMoveAnim(species, isBackPic, 0, coord1 + xOffset, coord2, 5, personality, isShiny, gBattleAnimTarget);
|
||||
|
||||
gSprites[spriteId].oam.priority = priority;
|
||||
gSprites[spriteId].oam.objMode = ST_OAM_OBJ_BLEND;
|
||||
@ -5162,10 +5161,9 @@ void AnimTask_SnatchOpposingMonMove(u8 taskId)
|
||||
{
|
||||
u8 spriteId, spriteId2;
|
||||
int personality;
|
||||
int otId;
|
||||
u16 species;
|
||||
u8 subpriority;
|
||||
bool8 isBackPic;
|
||||
bool8 isBackPic, isShiny;
|
||||
s16 x;
|
||||
|
||||
switch (gTasks[taskId].data[0])
|
||||
@ -5190,7 +5188,7 @@ void AnimTask_SnatchOpposingMonMove(u8 taskId)
|
||||
if (IsContest())
|
||||
{
|
||||
personality = gContestResources->moveAnim->personality;
|
||||
otId = gContestResources->moveAnim->otId;
|
||||
isShiny = gContestResources->moveAnim->isShiny;
|
||||
species = gContestResources->moveAnim->species;
|
||||
subpriority = GetBattlerSpriteSubpriority(gBattleAnimAttacker);
|
||||
isBackPic = FALSE;
|
||||
@ -5201,7 +5199,7 @@ void AnimTask_SnatchOpposingMonMove(u8 taskId)
|
||||
if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER)
|
||||
{
|
||||
personality = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_PERSONALITY);
|
||||
otId = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_OT_ID);
|
||||
isShiny = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_IS_SHINY);
|
||||
if (gBattleSpritesDataPtr->battlerData[gBattleAnimAttacker].transformSpecies == SPECIES_NONE)
|
||||
species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_SPECIES);
|
||||
else
|
||||
@ -5214,7 +5212,7 @@ void AnimTask_SnatchOpposingMonMove(u8 taskId)
|
||||
else
|
||||
{
|
||||
personality = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_PERSONALITY);
|
||||
otId = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_OT_ID);
|
||||
isShiny = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_IS_SHINY);
|
||||
if (gBattleSpritesDataPtr->battlerData[gBattleAnimAttacker].transformSpecies == SPECIES_NONE)
|
||||
species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_SPECIES);
|
||||
else
|
||||
@ -5226,7 +5224,7 @@ void AnimTask_SnatchOpposingMonMove(u8 taskId)
|
||||
}
|
||||
}
|
||||
|
||||
spriteId2 = CreateAdditionalMonSpriteForMoveAnim(species, isBackPic, 0, x, GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y), subpriority, personality, otId, gBattleAnimAttacker);
|
||||
spriteId2 = CreateAdditionalMonSpriteForMoveAnim(species, isBackPic, 0, x, GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y), subpriority, personality, isShiny, gBattleAnimAttacker);
|
||||
if (gBattleSpritesDataPtr->battlerData[gBattleAnimAttacker].transformSpecies != SPECIES_NONE)
|
||||
BlendPalette(OBJ_PLTT_ID(gSprites[spriteId2].oam.paletteNum), 16, 6, RGB_WHITE);
|
||||
|
||||
|
||||
@ -2053,7 +2053,7 @@ u8 GetBattlerSpriteBGPriorityRank(u8 battlerId)
|
||||
}
|
||||
|
||||
// Create pokemon sprite to be used for a move animation effect (e.g. Role Play / Snatch)
|
||||
u8 CreateAdditionalMonSpriteForMoveAnim(u16 species, bool8 isBackpic, u8 id, s16 x, s16 y, u8 subpriority, u32 personality, u32 trainerId, u32 battlerId)
|
||||
u8 CreateAdditionalMonSpriteForMoveAnim(u16 species, bool8 isBackpic, u8 id, s16 x, s16 y, u8 subpriority, u32 personality, bool8 isShiny, u32 battlerId)
|
||||
{
|
||||
u8 spriteId;
|
||||
u16 sheet = LoadSpriteSheet(&sSpriteSheets_MoveEffectMons[id]);
|
||||
@ -2063,7 +2063,7 @@ u8 CreateAdditionalMonSpriteForMoveAnim(u16 species, bool8 isBackpic, u8 id, s16
|
||||
gMonSpritesGfxPtr->buffer = AllocZeroed(MON_PIC_SIZE * MAX_MON_PIC_FRAMES);
|
||||
if (!isBackpic)
|
||||
{
|
||||
LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(species, trainerId, personality), OBJ_PLTT_ID(palette), PLTT_SIZE_4BPP);
|
||||
LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(species, isShiny, personality), OBJ_PLTT_ID(palette), PLTT_SIZE_4BPP);
|
||||
LoadSpecialPokePic(gMonSpritesGfxPtr->buffer,
|
||||
species,
|
||||
personality,
|
||||
@ -2071,7 +2071,7 @@ u8 CreateAdditionalMonSpriteForMoveAnim(u16 species, bool8 isBackpic, u8 id, s16
|
||||
}
|
||||
else
|
||||
{
|
||||
LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(species, trainerId, personality), OBJ_PLTT_ID(palette), PLTT_SIZE_4BPP);
|
||||
LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(species, isShiny, personality), OBJ_PLTT_ID(palette), PLTT_SIZE_4BPP);
|
||||
LoadSpecialPokePic(gMonSpritesGfxPtr->buffer,
|
||||
species,
|
||||
personality,
|
||||
|
||||
@ -2481,26 +2481,17 @@ void AnimTask_SetTargetToEffectBattler(u8 taskId)
|
||||
void TryShinyAnimation(u8 battler, struct Pokemon *mon)
|
||||
{
|
||||
bool8 isShiny;
|
||||
u32 otId, personality;
|
||||
u32 shinyValue;
|
||||
u8 taskCirc, taskDgnl;
|
||||
struct Pokemon* illusionMon;
|
||||
|
||||
isShiny = FALSE;
|
||||
isShiny = GetMonData(mon, MON_DATA_IS_SHINY);
|
||||
gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim = TRUE;
|
||||
illusionMon = GetIllusionMonPtr(battler);
|
||||
if (illusionMon != NULL)
|
||||
mon = illusionMon;
|
||||
|
||||
otId = GetMonData(mon, MON_DATA_OT_ID);
|
||||
personality = GetMonData(mon, MON_DATA_PERSONALITY);
|
||||
|
||||
if (IsBattlerSpriteVisible(battler) && IsValidForBattle(mon))
|
||||
{
|
||||
shinyValue = GET_SHINY_VALUE(otId, personality);
|
||||
if (shinyValue < SHINY_ODDS)
|
||||
isShiny = TRUE;
|
||||
|
||||
if (isShiny)
|
||||
{
|
||||
if (GetSpriteTileStartByTag(ANIM_TAG_GOLD_STARS) == 0xFFFF)
|
||||
|
||||
@ -2649,7 +2649,7 @@ void BtlController_HandleMoveAnimation(u32 battler, bool32 updateTvData)
|
||||
gWeatherMoveAnim = gBattleResources->bufferA[battler][12] | (gBattleResources->bufferA[battler][13] << 8);
|
||||
gAnimDisableStructPtr = (struct DisableStruct *)&gBattleResources->bufferA[battler][16];
|
||||
gTransformedPersonalities[battler] = gAnimDisableStructPtr->transformedMonPersonality;
|
||||
gTransformedOtIds[battler] = gAnimDisableStructPtr->transformedMonOtId;
|
||||
gTransformedShininess[battler] = gAnimDisableStructPtr->transformedMonShininess;
|
||||
gBattleSpritesDataPtr->healthBoxesData[battler].animationState = 0;
|
||||
gBattlerControllerFuncs[battler] = Controller_DoMoveAnimation;
|
||||
if (updateTvData)
|
||||
|
||||
@ -801,7 +801,7 @@ static void Task_ShowAiPoints(u8 taskId)
|
||||
}
|
||||
}
|
||||
data->aiMonSpriteId = CreateMonPicSprite(gBattleMons[data->aiBattlerId].species,
|
||||
gBattleMons[data->aiBattlerId].otId,
|
||||
gBattleMons[data->aiBattlerId].isShiny,
|
||||
gBattleMons[data->aiBattlerId].personality,
|
||||
TRUE,
|
||||
39, 130, 15, TAG_NONE);
|
||||
@ -864,7 +864,7 @@ static void PutAiInfoText(struct BattleDebugMenu *data)
|
||||
u16 holdEffect = AI_DATA->holdEffects[i];
|
||||
u16 item = AI_DATA->items[i];
|
||||
u8 x = (i == B_POSITION_PLAYER_LEFT) ? 83 + (i) * 75 : 83 + (i-1) * 75;
|
||||
AddTextPrinterParameterized(data->aiMovesWindowId, FONT_SMALL, gAbilityNames[ability], x, 0, 0, NULL);
|
||||
AddTextPrinterParameterized(data->aiMovesWindowId, FONT_SMALL, gAbilities[ability].name, x, 0, 0, NULL);
|
||||
AddTextPrinterParameterized(data->aiMovesWindowId, FONT_SMALL, ItemId_GetName(item), x, 15, 0, NULL);
|
||||
AddTextPrinterParameterized(data->aiMovesWindowId, FONT_SMALL, GetHoldEffectName(holdEffect), x, 30, 0, NULL);
|
||||
}
|
||||
@ -897,7 +897,7 @@ static void PutAiPartyText(struct BattleDebugMenu *data)
|
||||
AddTextPrinterParameterized5(data->aiMovesWindowId, FONT_SMALL_NARROW, text, i * 41, 0, 0, NULL, 0, 0);
|
||||
}
|
||||
|
||||
txtPtr = StringCopyN(text, gAbilityNames[aiMons[i].ability], 7); // The screen is too small to fit the whole string, so we need to drop the last letters.
|
||||
txtPtr = StringCopyN(text, gAbilities[aiMons[i].ability].name, 7); // The screen is too small to fit the whole string, so we need to drop the last letters.
|
||||
*txtPtr = EOS;
|
||||
AddTextPrinterParameterized5(data->aiMovesWindowId, FONT_SMALL_NARROW, text, i * 41, 15, 0, NULL, 0, 0);
|
||||
|
||||
@ -958,7 +958,7 @@ static void Task_ShowAiKnowledge(u8 taskId)
|
||||
}
|
||||
}
|
||||
data->aiMonSpriteId = CreateMonPicSprite(gBattleMons[data->aiBattlerId].species,
|
||||
gBattleMons[data->aiBattlerId].otId,
|
||||
gBattleMons[data->aiBattlerId].isShiny,
|
||||
gBattleMons[data->aiBattlerId].personality,
|
||||
TRUE,
|
||||
39, 130, 15, TAG_NONE);
|
||||
@ -1433,7 +1433,7 @@ static void PrintSecondaryEntries(struct BattleDebugMenu *data)
|
||||
}
|
||||
break;
|
||||
case LIST_ITEM_ABILITY:
|
||||
PadString(gAbilityNames[gBattleMons[data->battlerId].ability], text);
|
||||
PadString(gAbilities[gBattleMons[data->battlerId].ability].name, text);
|
||||
printer.currentY = printer.y = sSecondaryListTemplate.upText_Y;
|
||||
AddTextPrinter(&printer, 0, NULL);
|
||||
break;
|
||||
|
||||
@ -4152,6 +4152,7 @@ static bool32 IsDomeComboMoveEffect(u32 effect)
|
||||
case EFFECT_CHARGE:
|
||||
case EFFECT_BULK_UP:
|
||||
case EFFECT_ATTACK_ACCURACY_UP:
|
||||
case EFFECT_FILLET_AWAY:
|
||||
// Others
|
||||
case EFFECT_FOCUS_ENERGY:
|
||||
case EFFECT_LOCK_ON:
|
||||
@ -4343,7 +4344,7 @@ static void DisplayTrainerInfoOnCard(u8 flags, u8 trainerTourneyId)
|
||||
move = gSaveBlock2Ptr->frontier.domePlayerPartyData[i].moves[j];
|
||||
else
|
||||
move = gFacilityTrainerMons[DOME_MONS[trainerTourneyId][i]].moves[j];
|
||||
|
||||
|
||||
switch (k)
|
||||
{
|
||||
case MOVE_POINTS_COMBO:
|
||||
|
||||
@ -149,8 +149,8 @@ bool32 CanDynamax(u16 battlerId)
|
||||
// Returns whether a battler is transformed into a Gigantamax form.
|
||||
bool32 IsGigantamaxed(u16 battlerId)
|
||||
{
|
||||
// TODO: Incorporate Gigantamax factor.
|
||||
if ((gSpeciesInfo[gBattleMons[battlerId].species].isGigantamax))
|
||||
struct Pokemon *mon = &GetSideParty(GetBattlerSide(battlerId))[gBattlerPartyIndexes[battlerId]];
|
||||
if ((gSpeciesInfo[gBattleMons[battlerId].species].isGigantamax) && GetMonData(mon, MON_DATA_GIGANTAMAX_FACTOR))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
@ -162,9 +162,9 @@ void ApplyDynamaxHPMultiplier(u32 battler, struct Pokemon* mon)
|
||||
return;
|
||||
else
|
||||
{
|
||||
u16 mult = UQ_4_12(1.5); // placeholder
|
||||
u16 hp = UQ_4_12_TO_INT((GetMonData(mon, MON_DATA_HP) * mult) + UQ_4_12_ROUND);
|
||||
u16 maxHP = UQ_4_12_TO_INT((GetMonData(mon, MON_DATA_MAX_HP) * mult) + UQ_4_12_ROUND);
|
||||
u32 scale = 150 + 5 * GetMonData(mon, MON_DATA_DYNAMAX_LEVEL);
|
||||
u32 hp = (GetMonData(mon, MON_DATA_HP) * scale + 99) / 100;
|
||||
u32 maxHP = (GetMonData(mon, MON_DATA_MAX_HP) * scale + 99) / 100;
|
||||
SetMonData(mon, MON_DATA_HP, &hp);
|
||||
SetMonData(mon, MON_DATA_MAX_HP, &maxHP);
|
||||
}
|
||||
|
||||
@ -2017,9 +2017,9 @@ static void Select_CreateMonSprite(void)
|
||||
struct Pokemon *mon = &sFactorySelectScreen->mons[monId].monData;
|
||||
u16 species = GetMonData(mon, MON_DATA_SPECIES, NULL);
|
||||
u32 personality = GetMonData(mon, MON_DATA_PERSONALITY, NULL);
|
||||
u32 otId = GetMonData(mon, MON_DATA_OT_ID, NULL);
|
||||
bool8 isShiny = GetMonData(mon, MON_DATA_IS_SHINY, NULL);
|
||||
|
||||
sFactorySelectScreen->monPics[1].monSpriteId = CreateMonPicSprite(species, otId, personality, TRUE, 88, 32, 15, TAG_NONE);
|
||||
sFactorySelectScreen->monPics[1].monSpriteId = CreateMonPicSprite(species, isShiny, personality, TRUE, 88, 32, 15, TAG_NONE);
|
||||
gSprites[sFactorySelectScreen->monPics[1].monSpriteId].centerToCornerVecX = 0;
|
||||
gSprites[sFactorySelectScreen->monPics[1].monSpriteId].centerToCornerVecY = 0;
|
||||
|
||||
@ -2035,7 +2035,8 @@ static void Select_ReshowMonSprite(void)
|
||||
{
|
||||
struct Pokemon *mon;
|
||||
u16 species;
|
||||
u32 personality, otId;
|
||||
u32 personality;
|
||||
bool8 isShiny;
|
||||
|
||||
sFactorySelectScreen->monPics[1].bgSpriteId = CreateSprite(&sSpriteTemplate_Select_MonPicBgAnim, 120, 64, 1);
|
||||
StartSpriteAffineAnim(&gSprites[sFactorySelectScreen->monPics[1].bgSpriteId], 2);
|
||||
@ -2043,9 +2044,9 @@ static void Select_ReshowMonSprite(void)
|
||||
mon = &sFactorySelectScreen->mons[sFactorySelectScreen->cursorPos].monData;
|
||||
species = GetMonData(mon, MON_DATA_SPECIES, NULL);
|
||||
personality = GetMonData(mon, MON_DATA_PERSONALITY, NULL);
|
||||
otId = GetMonData(mon, MON_DATA_OT_ID, NULL);
|
||||
isShiny = GetMonData(mon, MON_DATA_IS_SHINY, NULL);
|
||||
|
||||
sFactorySelectScreen->monPics[1].monSpriteId = CreateMonPicSprite(species, otId, personality, TRUE, 88, 32, 15, TAG_NONE);
|
||||
sFactorySelectScreen->monPics[1].monSpriteId = CreateMonPicSprite(species, isShiny, personality, TRUE, 88, 32, 15, TAG_NONE);
|
||||
gSprites[sFactorySelectScreen->monPics[1].monSpriteId].centerToCornerVecX = 0;
|
||||
gSprites[sFactorySelectScreen->monPics[1].monSpriteId].centerToCornerVecY = 0;
|
||||
|
||||
@ -2065,9 +2066,9 @@ static void Select_CreateChosenMonsSprites(void)
|
||||
struct Pokemon *mon = &sFactorySelectScreen->mons[j].monData;
|
||||
u16 species = GetMonData(mon, MON_DATA_SPECIES, NULL);
|
||||
u32 personality = GetMonData(mon, MON_DATA_PERSONALITY, NULL);
|
||||
u32 otId = GetMonData(mon, MON_DATA_OT_ID, NULL);
|
||||
bool8 isShiny = GetMonData(mon, MON_DATA_IS_SHINY, NULL);
|
||||
|
||||
sFactorySelectScreen->monPics[i].monSpriteId = CreateMonPicSprite(species, otId, personality, TRUE, (i * 72) + 16, 32, i + 13, TAG_NONE);
|
||||
sFactorySelectScreen->monPics[i].monSpriteId = CreateMonPicSprite(species, isShiny, personality, TRUE, (i * 72) + 16, 32, i + 13, TAG_NONE);
|
||||
gSprites[sFactorySelectScreen->monPics[i].monSpriteId].centerToCornerVecX = 0;
|
||||
gSprites[sFactorySelectScreen->monPics[i].monSpriteId].centerToCornerVecY = 0;
|
||||
break;
|
||||
@ -4076,7 +4077,8 @@ static void Swap_ShowSummaryMonSprite(void)
|
||||
{
|
||||
struct Pokemon *mon;
|
||||
u16 species;
|
||||
u32 personality, otId;
|
||||
u32 personality;
|
||||
bool8 isShiny;
|
||||
|
||||
sFactorySwapScreen->monPic.bgSpriteId = CreateSprite(&sSpriteTemplate_Swap_MonPicBgAnim, 120, 64, 1);
|
||||
StartSpriteAffineAnim(&gSprites[sFactorySwapScreen->monPic.bgSpriteId], 2);
|
||||
@ -4084,13 +4086,9 @@ static void Swap_ShowSummaryMonSprite(void)
|
||||
mon = &gPlayerParty[sFactorySwapScreen->cursorPos];
|
||||
species = GetMonData(mon, MON_DATA_SPECIES, NULL);
|
||||
personality = GetMonData(mon, MON_DATA_PERSONALITY, NULL);
|
||||
otId = GetMonData(mon, MON_DATA_OT_ID, NULL);
|
||||
isShiny = GetMonData(mon, MON_DATA_IS_SHINY, NULL);
|
||||
|
||||
#ifdef BUGFIX
|
||||
sFactorySwapScreen->monPic.monSpriteId = CreateMonPicSprite(species, otId, personality, TRUE, 88, 32, 15, TAG_NONE);
|
||||
#else
|
||||
sFactorySwapScreen->monPic.monSpriteId = CreateMonPicSprite(species, personality, otId, TRUE, 88, 32, 15, TAG_NONE);
|
||||
#endif
|
||||
sFactorySwapScreen->monPic.monSpriteId = CreateMonPicSprite(species, isShiny, personality, TRUE, 88, 32, 15, TAG_NONE);
|
||||
gSprites[sFactorySwapScreen->monPic.monSpriteId].centerToCornerVecX = 0;
|
||||
gSprites[sFactorySwapScreen->monPic.monSpriteId].centerToCornerVecY = 0;
|
||||
|
||||
@ -4295,7 +4293,8 @@ static void Swap_CreateMonSprite(void)
|
||||
{
|
||||
struct Pokemon *mon;
|
||||
u16 species;
|
||||
u32 personality, otId;
|
||||
u32 personality;
|
||||
bool8 isShiny;
|
||||
|
||||
if (!sFactorySwapScreen->inEnemyScreen)
|
||||
mon = &gPlayerParty[sFactorySwapScreen->cursorPos];
|
||||
@ -4304,9 +4303,9 @@ static void Swap_CreateMonSprite(void)
|
||||
|
||||
species = GetMonData(mon, MON_DATA_SPECIES, NULL);
|
||||
personality = GetMonData(mon, MON_DATA_PERSONALITY, NULL);
|
||||
otId = GetMonData(mon, MON_DATA_OT_ID, NULL);
|
||||
isShiny = GetMonData(mon, MON_DATA_IS_SHINY, NULL);
|
||||
|
||||
sFactorySwapScreen->monPic.monSpriteId = CreateMonPicSprite(species, otId, personality, TRUE, 88, 32, 15, TAG_NONE);
|
||||
sFactorySwapScreen->monPic.monSpriteId = CreateMonPicSprite(species, isShiny, personality, TRUE, 88, 32, 15, TAG_NONE);
|
||||
gSprites[sFactorySwapScreen->monPic.monSpriteId].centerToCornerVecX = 0;
|
||||
gSprites[sFactorySwapScreen->monPic.monSpriteId].centerToCornerVecY = 0;
|
||||
|
||||
|
||||
@ -570,7 +570,7 @@ bool8 IsBattleSEPlaying(u8 battler)
|
||||
|
||||
void BattleLoadMonSpriteGfx(struct Pokemon *mon, u32 battler)
|
||||
{
|
||||
u32 monsPersonality, currentPersonality, otId, currentOtId, species, paletteOffset, position;
|
||||
u32 monsPersonality, currentPersonality, isShiny, species, paletteOffset, position;
|
||||
const void *lzPaletteData;
|
||||
struct Pokemon *illusionMon = GetIllusionMonPtr(battler);
|
||||
if (illusionMon != NULL)
|
||||
@ -580,13 +580,12 @@ void BattleLoadMonSpriteGfx(struct Pokemon *mon, u32 battler)
|
||||
return;
|
||||
|
||||
monsPersonality = GetMonData(mon, MON_DATA_PERSONALITY);
|
||||
otId = GetMonData(mon, MON_DATA_OT_ID);
|
||||
isShiny = GetMonData(mon, MON_DATA_IS_SHINY);
|
||||
|
||||
if (gBattleSpritesDataPtr->battlerData[battler].transformSpecies == SPECIES_NONE)
|
||||
{
|
||||
species = GetMonData(mon, MON_DATA_SPECIES);
|
||||
currentPersonality = monsPersonality;
|
||||
currentOtId = otId;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -594,12 +593,10 @@ void BattleLoadMonSpriteGfx(struct Pokemon *mon, u32 battler)
|
||||
if (B_TRANSFORM_SHINY >= GEN_4)
|
||||
{
|
||||
currentPersonality = gTransformedPersonalities[battler];
|
||||
currentOtId = gTransformedOtIds[battler];
|
||||
}
|
||||
else
|
||||
{
|
||||
currentPersonality = monsPersonality;
|
||||
currentOtId = otId;
|
||||
}
|
||||
}
|
||||
|
||||
@ -622,7 +619,7 @@ void BattleLoadMonSpriteGfx(struct Pokemon *mon, u32 battler)
|
||||
if (gBattleSpritesDataPtr->battlerData[battler].transformSpecies == SPECIES_NONE)
|
||||
lzPaletteData = GetMonFrontSpritePal(mon);
|
||||
else
|
||||
lzPaletteData = GetMonSpritePalFromSpeciesAndPersonality(species, currentOtId, currentPersonality);
|
||||
lzPaletteData = GetMonSpritePalFromSpeciesAndPersonality(species, isShiny, currentPersonality);
|
||||
|
||||
LZDecompressWram(lzPaletteData, gDecompressionBuffer);
|
||||
LoadPalette(gDecompressionBuffer, paletteOffset, PLTT_SIZE_4BPP);
|
||||
@ -867,7 +864,8 @@ void CopyBattleSpriteInvisibility(u8 battler)
|
||||
|
||||
void HandleSpeciesGfxDataChange(u8 battlerAtk, u8 battlerDef, bool32 megaEvo, bool8 trackEnemyPersonality)
|
||||
{
|
||||
u32 personalityValue, otId, position, paletteOffset, targetSpecies;
|
||||
u32 personalityValue, position, paletteOffset, targetSpecies;
|
||||
bool8 isShiny;
|
||||
const void *lzPaletteData, *src;
|
||||
void *dst;
|
||||
|
||||
@ -876,7 +874,7 @@ void HandleSpeciesGfxDataChange(u8 battlerAtk, u8 battlerDef, bool32 megaEvo, bo
|
||||
position = B_POSITION_PLAYER_LEFT;
|
||||
targetSpecies = gContestResources->moveAnim->targetSpecies;
|
||||
personalityValue = gContestResources->moveAnim->personality;
|
||||
otId = gContestResources->moveAnim->otId;
|
||||
isShiny = gContestResources->moveAnim->isShiny;
|
||||
|
||||
HandleLoadSpecialPokePic(FALSE,
|
||||
gMonSpritesGfxPtr->sprites.ptr[position],
|
||||
@ -897,14 +895,13 @@ void HandleSpeciesGfxDataChange(u8 battlerAtk, u8 battlerDef, bool32 megaEvo, bo
|
||||
if (B_TRANSFORM_SHINY >= GEN_4 && trackEnemyPersonality)
|
||||
{
|
||||
personalityValue = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerAtk]], MON_DATA_PERSONALITY);
|
||||
otId = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerAtk]], MON_DATA_OT_ID);
|
||||
isShiny = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerAtk]], MON_DATA_IS_SHINY);
|
||||
}
|
||||
else
|
||||
{
|
||||
personalityValue = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerAtk]], MON_DATA_PERSONALITY);
|
||||
otId = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerAtk]], MON_DATA_OT_ID);
|
||||
isShiny = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerAtk]], MON_DATA_IS_SHINY);
|
||||
}
|
||||
otId = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerAtk]], MON_DATA_OT_ID);
|
||||
|
||||
HandleLoadSpecialPokePic(FALSE,
|
||||
gMonSpritesGfxPtr->sprites.ptr[position],
|
||||
@ -916,13 +913,12 @@ void HandleSpeciesGfxDataChange(u8 battlerAtk, u8 battlerDef, bool32 megaEvo, bo
|
||||
if (B_TRANSFORM_SHINY >= GEN_4 && trackEnemyPersonality)
|
||||
{
|
||||
personalityValue = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerAtk]], MON_DATA_PERSONALITY);
|
||||
otId = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerAtk]], MON_DATA_OT_ID);
|
||||
|
||||
isShiny = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerAtk]], MON_DATA_IS_SHINY);
|
||||
}
|
||||
else
|
||||
{
|
||||
personalityValue = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerAtk]], MON_DATA_PERSONALITY);
|
||||
otId = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerAtk]], MON_DATA_OT_ID);
|
||||
isShiny = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerAtk]], MON_DATA_IS_SHINY);
|
||||
}
|
||||
|
||||
HandleLoadSpecialPokePic(TRUE,
|
||||
@ -935,7 +931,7 @@ void HandleSpeciesGfxDataChange(u8 battlerAtk, u8 battlerDef, bool32 megaEvo, bo
|
||||
dst = (void *)(OBJ_VRAM0 + gSprites[gBattlerSpriteIds[battlerAtk]].oam.tileNum * 32);
|
||||
DmaCopy32(3, src, dst, MON_PIC_SIZE);
|
||||
paletteOffset = OBJ_PLTT_ID(battlerAtk);
|
||||
lzPaletteData = GetMonSpritePalFromSpeciesAndPersonality(targetSpecies, otId, personalityValue);
|
||||
lzPaletteData = GetMonSpritePalFromSpeciesAndPersonality(targetSpecies, isShiny, personalityValue);
|
||||
LZDecompressWram(lzPaletteData, gDecompressionBuffer);
|
||||
LoadPalette(gDecompressionBuffer, paletteOffset, PLTT_SIZE_4BPP);
|
||||
|
||||
|
||||
@ -3113,7 +3113,7 @@ static void PrintBattlerOnAbilityPopUp(u8 battlerId, u8 spriteId1, u8 spriteId2)
|
||||
|
||||
static void PrintAbilityOnAbilityPopUp(u32 ability, u8 spriteId1, u8 spriteId2)
|
||||
{
|
||||
PrintOnAbilityPopUp(gAbilityNames[ability],
|
||||
PrintOnAbilityPopUp(gAbilities[ability].name,
|
||||
(void*)(OBJ_VRAM0) + (gSprites[spriteId1].oam.tileNum * 32) + 256,
|
||||
(void*)(OBJ_VRAM0) + (gSprites[spriteId2].oam.tileNum * 32) + 256,
|
||||
5, 12,
|
||||
|
||||
@ -214,7 +214,7 @@ EWRAM_DATA u8 gBattlerStatusSummaryTaskId[MAX_BATTLERS_COUNT] = {0};
|
||||
EWRAM_DATA u8 gBattlerInMenuId = 0;
|
||||
EWRAM_DATA bool8 gDoingBattleAnim = FALSE;
|
||||
EWRAM_DATA u32 gTransformedPersonalities[MAX_BATTLERS_COUNT] = {0};
|
||||
EWRAM_DATA u32 gTransformedOtIds[MAX_BATTLERS_COUNT] = {0};
|
||||
EWRAM_DATA bool8 gTransformedShininess[MAX_BATTLERS_COUNT] = {0};
|
||||
EWRAM_DATA u8 gPlayerDpadHoldFrames = 0;
|
||||
EWRAM_DATA struct BattleSpriteData *gBattleSpritesDataPtr = NULL;
|
||||
EWRAM_DATA struct MonSpritesGfx *gMonSpritesGfxPtr = NULL;
|
||||
@ -409,8 +409,6 @@ static const u16 sTrainerBallTable[TRAINER_CLASS_COUNT] =
|
||||
};
|
||||
#endif
|
||||
|
||||
#include "data/text/abilities.h"
|
||||
|
||||
static void (* const sTurnActionsFuncsTable[])(void) =
|
||||
{
|
||||
[B_ACTION_USE_MOVE] = HandleAction_UseMove,
|
||||
@ -2018,6 +2016,21 @@ u8 CreateNPCTrainerPartyFromTrainer(struct Pokemon *party, const struct Trainer
|
||||
{
|
||||
SetMonData(&party[i], MON_DATA_NICKNAME, partyData[i].nickname);
|
||||
}
|
||||
if (partyData[i].isShiny)
|
||||
{
|
||||
u32 data = TRUE;
|
||||
SetMonData(&party[i], MON_DATA_IS_SHINY, &data);
|
||||
}
|
||||
if (partyData[i].dynamaxLevel > 0)
|
||||
{
|
||||
u32 data = partyData[i].dynamaxLevel;
|
||||
SetMonData(&party[i], MON_DATA_DYNAMAX_LEVEL, &data);
|
||||
}
|
||||
if (partyData[i].gigantamaxFactor)
|
||||
{
|
||||
u32 data = partyData[i].gigantamaxFactor;
|
||||
SetMonData(&party[i], MON_DATA_GIGANTAMAX_FACTOR, &data);
|
||||
}
|
||||
CalculateMonStats(&party[i]);
|
||||
|
||||
#if B_TRAINER_CLASS_POKE_BALLS >= GEN_7
|
||||
|
||||
@ -3407,19 +3407,19 @@ u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst)
|
||||
}
|
||||
break;
|
||||
case B_TXT_LAST_ABILITY: // last used ability
|
||||
toCpy = gAbilityNames[gLastUsedAbility];
|
||||
toCpy = gAbilities[gLastUsedAbility].name;
|
||||
break;
|
||||
case B_TXT_ATK_ABILITY: // attacker ability
|
||||
toCpy = gAbilityNames[sBattlerAbilities[gBattlerAttacker]];
|
||||
toCpy = gAbilities[sBattlerAbilities[gBattlerAttacker]].name;
|
||||
break;
|
||||
case B_TXT_DEF_ABILITY: // target ability
|
||||
toCpy = gAbilityNames[sBattlerAbilities[gBattlerTarget]];
|
||||
toCpy = gAbilities[sBattlerAbilities[gBattlerTarget]].name;
|
||||
break;
|
||||
case B_TXT_SCR_ACTIVE_ABILITY: // scripting active ability
|
||||
toCpy = gAbilityNames[sBattlerAbilities[gBattleScripting.battler]];
|
||||
toCpy = gAbilities[sBattlerAbilities[gBattleScripting.battler]].name;
|
||||
break;
|
||||
case B_TXT_EFF_ABILITY: // effect battler ability
|
||||
toCpy = gAbilityNames[sBattlerAbilities[gEffectBattler]];
|
||||
toCpy = gAbilities[sBattlerAbilities[gEffectBattler]].name;
|
||||
break;
|
||||
case B_TXT_TRAINER1_CLASS: // trainer class name
|
||||
toCpy = BattleStringGetOpponentClassByTrainerId(gTrainerBattleOpponent_A);
|
||||
@ -3781,7 +3781,7 @@ void ExpandBattleTextBuffPlaceholders(const u8 *src, u8 *dst)
|
||||
srcID += 2;
|
||||
break;
|
||||
case B_BUFF_ABILITY: // ability names
|
||||
StringAppend(dst, gAbilityNames[T1_READ_16(&src[srcID + 1])]);
|
||||
StringAppend(dst, gAbilities[T1_READ_16(&src[srcID + 1])].name);
|
||||
srcID += 3;
|
||||
break;
|
||||
case B_BUFF_ITEM: // item name
|
||||
|
||||
@ -886,14 +886,8 @@ static bool8 TryInflictRandomStatus(void)
|
||||
|
||||
for (i = 0; i < FRONTIER_PARTY_SIZE; i++)
|
||||
indices[i] = i;
|
||||
for (j = 0; j < 10; j++)
|
||||
{
|
||||
u8 temp, id;
|
||||
|
||||
i = Random() % FRONTIER_PARTY_SIZE;
|
||||
id = Random() % FRONTIER_PARTY_SIZE;
|
||||
SWAP(indices[i], indices[id], temp);
|
||||
}
|
||||
Shuffle(indices, FRONTIER_PARTY_SIZE, sizeof(indices[0]));
|
||||
|
||||
if (gSaveBlock2Ptr->frontier.curChallengeBattleNum <= 4)
|
||||
count = 1;
|
||||
@ -1265,7 +1259,7 @@ static void Task_DoStatusInflictionScreenFlash(u8 taskId)
|
||||
|
||||
static void TryHealMons(u8 healCount)
|
||||
{
|
||||
u8 j, i, k;
|
||||
u8 j, i;
|
||||
u8 indices[FRONTIER_PARTY_SIZE];
|
||||
|
||||
if (healCount == 0)
|
||||
@ -1276,15 +1270,7 @@ static void TryHealMons(u8 healCount)
|
||||
|
||||
// Only 'healCount' number of pokemon will be healed.
|
||||
// The order in which they're (attempted to be) healed is random,
|
||||
// and determined by performing 10 random swaps to this index array.
|
||||
for (k = 0; k < 10; k++)
|
||||
{
|
||||
u8 temp;
|
||||
|
||||
i = Random() % FRONTIER_PARTY_SIZE;
|
||||
j = Random() % FRONTIER_PARTY_SIZE;
|
||||
SWAP(indices[i], indices[j], temp);
|
||||
}
|
||||
Shuffle(indices, FRONTIER_PARTY_SIZE, sizeof(indices[0]));
|
||||
|
||||
for (i = 0; i < FRONTIER_PARTY_SIZE; i++)
|
||||
{
|
||||
|
||||
@ -543,7 +543,7 @@ static void Cmd_setsafeguard(void);
|
||||
static void Cmd_magnitudedamagecalculation(void);
|
||||
static void Cmd_jumpifnopursuitswitchdmg(void);
|
||||
static void Cmd_setsunny(void);
|
||||
static void Cmd_maxattackhalvehp(void);
|
||||
static void Cmd_halvehp(void);
|
||||
static void Cmd_copyfoestats(void);
|
||||
static void Cmd_rapidspinfree(void);
|
||||
static void Cmd_setdefensecurlbit(void);
|
||||
@ -802,7 +802,7 @@ void (* const gBattleScriptingCommandsTable[])(void) =
|
||||
Cmd_magnitudedamagecalculation, //0xB9
|
||||
Cmd_jumpifnopursuitswitchdmg, //0xBA
|
||||
Cmd_setsunny, //0xBB
|
||||
Cmd_maxattackhalvehp, //0xBC
|
||||
Cmd_halvehp, //0xBC
|
||||
Cmd_copyfoestats, //0xBD
|
||||
Cmd_rapidspinfree, //0xBE
|
||||
Cmd_setdefensecurlbit, //0xBF
|
||||
@ -12308,7 +12308,7 @@ static void Cmd_transformdataexecution(void)
|
||||
gDisableStructs[gBattlerAttacker].disabledMove = MOVE_NONE;
|
||||
gDisableStructs[gBattlerAttacker].disableTimer = 0;
|
||||
gDisableStructs[gBattlerAttacker].transformedMonPersonality = gBattleMons[gBattlerTarget].personality;
|
||||
gDisableStructs[gBattlerAttacker].transformedMonOtId = gBattleMons[gBattlerTarget].otId;
|
||||
gDisableStructs[gBattlerAttacker].transformedMonShininess = gBattleMons[gBattlerTarget].isShiny;
|
||||
gDisableStructs[gBattlerAttacker].mimickedMoves = 0;
|
||||
gDisableStructs[gBattlerAttacker].usedMoves = 0;
|
||||
|
||||
@ -12693,10 +12693,8 @@ static void Cmd_copymovepermanently(void)
|
||||
gChosenMove = MOVE_UNAVAILABLE;
|
||||
|
||||
if (!(gBattleMons[gBattlerAttacker].status2 & STATUS2_TRANSFORMED)
|
||||
&& gLastPrintedMoves[gBattlerTarget] != MOVE_STRUGGLE
|
||||
&& gLastPrintedMoves[gBattlerTarget] != MOVE_NONE
|
||||
&& gLastPrintedMoves[gBattlerTarget] != MOVE_UNAVAILABLE
|
||||
&& gLastPrintedMoves[gBattlerTarget] != MOVE_SKETCH)
|
||||
&& !gBattleMoves[gLastPrintedMoves[gBattlerTarget]].sketchBanned)
|
||||
{
|
||||
s32 i;
|
||||
|
||||
@ -13324,8 +13322,8 @@ static void Cmd_setsunny(void)
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
|
||||
// Belly Drum
|
||||
static void Cmd_maxattackhalvehp(void)
|
||||
// Belly Drum, Fillet Away
|
||||
static void Cmd_halvehp(void)
|
||||
{
|
||||
CMD_ARGS(const u8 *failInstr);
|
||||
|
||||
@ -13334,11 +13332,8 @@ static void Cmd_maxattackhalvehp(void)
|
||||
if (!(GetNonDynamaxMaxHP(gBattlerAttacker) / 2))
|
||||
halfHp = 1;
|
||||
|
||||
// Belly Drum fails if the user's current HP is less than half its maximum, or if the user's Attack is already at +6 (even if the user has Contrary).
|
||||
if (gBattleMons[gBattlerAttacker].statStages[STAT_ATK] < MAX_STAT_STAGE
|
||||
&& gBattleMons[gBattlerAttacker].hp > halfHp)
|
||||
if (gBattleMons[gBattlerAttacker].hp > halfHp)
|
||||
{
|
||||
gBattleMons[gBattlerAttacker].statStages[STAT_ATK] = MAX_STAT_STAGE;
|
||||
gBattleMoveDamage = GetNonDynamaxMaxHP(gBattlerAttacker) / 2;
|
||||
if (gBattleMoveDamage == 0)
|
||||
gBattleMoveDamage = 1;
|
||||
@ -15171,10 +15166,11 @@ static void Cmd_displaydexinfo(void)
|
||||
case 1:
|
||||
if (!gPaletteFade.active)
|
||||
{
|
||||
struct Pokemon *mon = &gEnemyParty[gBattlerPartyIndexes[GetCatchingBattler()]];
|
||||
FreeAllWindowBuffers();
|
||||
gBattleCommunication[TASK_ID] = DisplayCaughtMonDexPage(species,
|
||||
gBattleMons[GetCatchingBattler()].otId,
|
||||
gBattleMons[GetCatchingBattler()].personality);
|
||||
GetMonData(mon, MON_DATA_IS_SHINY),
|
||||
GetMonData(mon, MON_DATA_PERSONALITY));
|
||||
gBattleCommunication[0]++;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -2990,21 +2990,17 @@ static void FillPartnerParty(u16 trainerId)
|
||||
else
|
||||
otID = ((firstIdPart % 72) * 1000) + ((secondIdPart % 23) * 10) + (thirdIdPart % 37) % 65536;
|
||||
|
||||
do
|
||||
{
|
||||
personality = Random32();
|
||||
} while (IsShinyOtIdPersonality(otID, personality));
|
||||
|
||||
personality = Random32();
|
||||
if (partyData[i].gender == TRAINER_MON_MALE)
|
||||
personality = (personality & 0xFFFFFF00) | GeneratePersonalityForGender(MON_MALE, partyData[i].species);
|
||||
else if (partyData[i].gender == TRAINER_MON_FEMALE)
|
||||
personality = (personality & 0xFFFFFF00) | GeneratePersonalityForGender(MON_FEMALE, partyData[i].species);
|
||||
if (partyData[i].nature != 0)
|
||||
ModifyPersonalityForNature(&personality, partyData[i].nature - 1);
|
||||
if (partyData[i].isShiny)
|
||||
otID ^= GET_SHINY_VALUE(otID, personality) << 16;
|
||||
|
||||
CreateMon(&gPlayerParty[i + 3], partyData[i].species, partyData[i].lvl, 0, TRUE, personality, OT_ID_PRESET, otID);
|
||||
j = partyData[i].isShiny;
|
||||
SetMonData(&gPlayerParty[i + 3], MON_DATA_IS_SHINY, &j);
|
||||
SetMonData(&gPlayerParty[i + 3], MON_DATA_HELD_ITEM, &partyData[i].heldItem);
|
||||
CustomTrainerPartyAssignMoves(&gPlayerParty[i + 3], &partyData[i]);
|
||||
|
||||
|
||||
@ -10555,6 +10555,7 @@ u16 GetBattleFormChangeTargetSpecies(u32 battler, u16 method)
|
||||
u16 targetSpecies = SPECIES_NONE;
|
||||
u16 species = gBattleMons[battler].species;
|
||||
const struct FormChange *formChanges = GetSpeciesFormChanges(species);
|
||||
struct Pokemon *mon = &GetBattlerParty(battler)[gBattlerPartyIndexes[battler]];
|
||||
u16 heldItem;
|
||||
|
||||
if (formChanges != NULL)
|
||||
@ -10602,8 +10603,8 @@ u16 GetBattleFormChangeTargetSpecies(u32 battler, u16 method)
|
||||
}
|
||||
break;
|
||||
case FORM_CHANGE_BATTLE_GIGANTAMAX:
|
||||
// TODO: check Gigantamax factor
|
||||
targetSpecies = formChanges[i].targetSpecies;
|
||||
if (GetMonData(mon, MON_DATA_GIGANTAMAX_FACTOR))
|
||||
targetSpecies = formChanges[i].targetSpecies;
|
||||
break;
|
||||
case FORM_CHANGE_BATTLE_WEATHER:
|
||||
// Check if there is a required ability and if the battler's ability does not match it
|
||||
|
||||
@ -98,7 +98,7 @@ static void PrintContestantMonName(u8);
|
||||
static void PrintContestantMonNameWithColor(u8, u8);
|
||||
static u8 CreateJudgeSprite(void);
|
||||
static u8 CreateJudgeSpeechBubbleSprite(void);
|
||||
static u8 CreateContestantSprite(u16, u32, u32, u32);
|
||||
static u8 CreateContestantSprite(u16, bool8, u32, u32);
|
||||
static void PrintContestMoveDescription(u16);
|
||||
static u16 SanitizeSpecies(u16);
|
||||
static void ContestClearGeneralTextWindow(void);
|
||||
@ -1781,7 +1781,7 @@ static void Task_DoAppeals(u8 taskId)
|
||||
SetMoveAnimAttackerData(eContest.currentContestant);
|
||||
spriteId = CreateContestantSprite(
|
||||
gContestMons[eContest.currentContestant].species,
|
||||
gContestMons[eContest.currentContestant].otId,
|
||||
gContestMons[eContest.currentContestant].isShiny,
|
||||
gContestMons[eContest.currentContestant].personality,
|
||||
eContest.currentContestant);
|
||||
gSprites[spriteId].x2 = 120;
|
||||
@ -2811,6 +2811,7 @@ void CreateContestMonFromParty(u8 partyIndex)
|
||||
gContestMons[gContestPlayerMonIndex].moves[3] = GetMonData(&gPlayerParty[partyIndex], MON_DATA_MOVE4);
|
||||
gContestMons[gContestPlayerMonIndex].personality = GetMonData(&gPlayerParty[partyIndex], MON_DATA_PERSONALITY);
|
||||
gContestMons[gContestPlayerMonIndex].otId = GetMonData(&gPlayerParty[partyIndex], MON_DATA_OT_ID);
|
||||
gContestMons[gContestPlayerMonIndex].isShiny = GetMonData(&gPlayerParty[partyIndex], MON_DATA_IS_SHINY);
|
||||
|
||||
heldItem = GetMonData(&gPlayerParty[partyIndex], MON_DATA_HELD_ITEM);
|
||||
cool = gContestMons[gContestPlayerMonIndex].cool;
|
||||
@ -3114,14 +3115,14 @@ static u8 CreateJudgeSpeechBubbleSprite(void)
|
||||
return spriteId;
|
||||
}
|
||||
|
||||
static u8 CreateContestantSprite(u16 species, u32 otId, u32 personality, u32 index)
|
||||
static u8 CreateContestantSprite(u16 species, bool8 isShiny, u32 personality, u32 index)
|
||||
{
|
||||
u8 spriteId;
|
||||
species = SanitizeSpecies(species);
|
||||
|
||||
HandleLoadSpecialPokePic(FALSE, gMonSpritesGfxPtr->sprites.ptr[B_POSITION_PLAYER_LEFT], species, personality);
|
||||
|
||||
LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(species, otId, personality), OBJ_PLTT_ID(2), PLTT_SIZE_4BPP);
|
||||
LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(species, isShiny, personality), OBJ_PLTT_ID(2), PLTT_SIZE_4BPP);
|
||||
SetMultiuseSpriteTemplateToPokemon(species, B_POSITION_PLAYER_LEFT);
|
||||
|
||||
spriteId = CreateSprite(&gMultiuseSpriteTemplate, 0x70, GetBattlerSpriteFinal_Y(2, species, FALSE), 30);
|
||||
@ -5354,6 +5355,7 @@ static void SetMoveAnimAttackerData(u8 contestant)
|
||||
gContestResources->moveAnim->species = SanitizeSpecies(gContestMons[contestant].species);
|
||||
gContestResources->moveAnim->personality = gContestMons[contestant].personality;
|
||||
gContestResources->moveAnim->otId = gContestMons[contestant].otId;
|
||||
gContestResources->moveAnim->isShiny = gContestMons[contestant].isShiny;
|
||||
}
|
||||
|
||||
static void CreateInvisibleBattleTargetSprite(void)
|
||||
@ -5565,6 +5567,7 @@ bool8 SaveContestWinner(u8 rank)
|
||||
{
|
||||
// Set the most recent winner so the artist can show the player their painting
|
||||
gCurContestWinner.personality = gContestMons[i].personality;
|
||||
gCurContestWinner.isShiny = gContestMons[i].isShiny;
|
||||
gCurContestWinner.trainerId = gContestMons[i].otId;
|
||||
gCurContestWinner.species = gContestMons[i].species;
|
||||
StringCopy(gCurContestWinner.monName, gContestMons[i].nickname);
|
||||
|
||||
@ -363,7 +363,7 @@ static void VBlankCB_ContestPainting(void)
|
||||
|
||||
static void InitContestMonPixels(u16 species, bool8 backPic)
|
||||
{
|
||||
const void *pal = GetMonSpritePalFromSpeciesAndPersonality(species, gContestPaintingWinner->trainerId, gContestPaintingWinner->personality);
|
||||
const void *pal = GetMonSpritePalFromSpeciesAndPersonality(species, gContestPaintingWinner->isShiny, gContestPaintingWinner->personality);
|
||||
LZDecompressVram(pal, gContestPaintingMonPalette);
|
||||
if (!backPic)
|
||||
{
|
||||
|
||||
@ -879,7 +879,7 @@ static void Task_ShowWinnerMonBanner(u8 taskId)
|
||||
int i;
|
||||
u8 spriteId;
|
||||
u16 species;
|
||||
u32 otId;
|
||||
bool8 isShiny;
|
||||
u32 personality;
|
||||
|
||||
switch (gTasks[taskId].tState)
|
||||
@ -891,13 +891,13 @@ static void Task_ShowWinnerMonBanner(u8 taskId)
|
||||
GET_CONTEST_WINNER_ID(i);
|
||||
species = gContestMons[i].species;
|
||||
personality = gContestMons[i].personality;
|
||||
otId = gContestMons[i].otId;
|
||||
isShiny = gContestMons[i].isShiny;
|
||||
HandleLoadSpecialPokePic(TRUE,
|
||||
gMonSpritesGfxPtr->sprites.ptr[B_POSITION_OPPONENT_LEFT],
|
||||
species,
|
||||
personality);
|
||||
|
||||
LoadCompressedSpritePaletteWithTag(GetMonSpritePalFromSpeciesAndPersonality(species, otId, personality), species);
|
||||
LoadCompressedSpritePaletteWithTag(GetMonSpritePalFromSpeciesAndPersonality(species, isShiny, personality), species);
|
||||
SetMultiuseSpriteTemplateToPokemon(species, B_POSITION_OPPONENT_LEFT);
|
||||
gMultiuseSpriteTemplate.paletteTag = species;
|
||||
spriteId = CreateSprite(&gMultiuseSpriteTemplate, DISPLAY_WIDTH + 32, DISPLAY_HEIGHT / 2, 10);
|
||||
@ -2552,11 +2552,12 @@ bool8 IsContestDebugActive(void)
|
||||
|
||||
void ShowContestEntryMonPic(void)
|
||||
{
|
||||
u32 personality, otId;
|
||||
u32 personality;
|
||||
u16 species;
|
||||
u8 spriteId;
|
||||
u8 taskId;
|
||||
u8 left, top;
|
||||
bool32 isShiny;
|
||||
|
||||
if (FindTaskIdByFunc(Task_ShowContestEntryMonPic) == TASK_NONE)
|
||||
{
|
||||
@ -2565,13 +2566,13 @@ void ShowContestEntryMonPic(void)
|
||||
top = 3;
|
||||
species = gContestMons[gSpecialVar_0x8006].species;
|
||||
personality = gContestMons[gSpecialVar_0x8006].personality;
|
||||
otId = gContestMons[gSpecialVar_0x8006].otId;
|
||||
isShiny = gContestMons[gSpecialVar_0x8006].isShiny;
|
||||
taskId = CreateTask(Task_ShowContestEntryMonPic, 0x50);
|
||||
gTasks[taskId].data[0] = 0;
|
||||
gTasks[taskId].data[1] = species;
|
||||
HandleLoadSpecialPokePic(TRUE, gMonSpritesGfxPtr->sprites.ptr[B_POSITION_OPPONENT_LEFT], species, personality);
|
||||
|
||||
LoadCompressedSpritePaletteWithTag(GetMonSpritePalFromSpeciesAndPersonality(species, otId, personality), species);
|
||||
LoadCompressedSpritePaletteWithTag(GetMonSpritePalFromSpeciesAndPersonality(species, isShiny, personality), species);
|
||||
SetMultiuseSpriteTemplateToPokemon(species, B_POSITION_OPPONENT_LEFT);
|
||||
gMultiuseSpriteTemplate.paletteTag = species;
|
||||
spriteId = CreateSprite(&gMultiuseSpriteTemplate, (left + 1) * 8 + 32, (top * 8) + 40, 0);
|
||||
|
||||
2068
src/data/abilities.h
Normal file
2068
src/data/abilities.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -13,6 +13,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.category = BATTLE_CATEGORY_PHYSICAL,
|
||||
.metronomeBanned = TRUE,
|
||||
.mirrorMoveBanned = TRUE,
|
||||
.sketchBanned = TRUE,
|
||||
},
|
||||
|
||||
[MOVE_POUND] =
|
||||
@ -2844,6 +2845,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.instructBanned = TRUE,
|
||||
.encoreBanned = TRUE,
|
||||
.assistBanned = TRUE,
|
||||
.sketchBanned = TRUE,
|
||||
},
|
||||
|
||||
[MOVE_SKETCH] =
|
||||
@ -2868,6 +2870,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.instructBanned = TRUE,
|
||||
.encoreBanned = TRUE,
|
||||
.assistBanned = TRUE,
|
||||
.sketchBanned = TRUE,
|
||||
},
|
||||
|
||||
[MOVE_TRIPLE_KICK] =
|
||||
@ -3063,6 +3066,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.category = BATTLE_CATEGORY_SPECIAL,
|
||||
.windMove = TRUE,
|
||||
},
|
||||
|
||||
[MOVE_COTTON_SPORE] =
|
||||
@ -5117,7 +5121,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
[MOVE_LUSTER_PURGE] =
|
||||
{
|
||||
.effect = EFFECT_SPECIAL_DEFENSE_DOWN_HIT,
|
||||
.power = 70,
|
||||
.power = (B_UPDATED_MOVE_DATA >= GEN_9) ? 95 : 70,
|
||||
.type = TYPE_PSYCHIC,
|
||||
.accuracy = 100,
|
||||
.pp = 5,
|
||||
@ -5131,7 +5135,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
[MOVE_MIST_BALL] =
|
||||
{
|
||||
.effect = EFFECT_SPECIAL_ATTACK_DOWN_HIT,
|
||||
.power = 70,
|
||||
.power = (B_UPDATED_MOVE_DATA >= GEN_9) ? 95 : 70,
|
||||
.type = TYPE_PSYCHIC,
|
||||
.accuracy = 100,
|
||||
.pp = 5,
|
||||
@ -7900,6 +7904,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.category = BATTLE_CATEGORY_STATUS,
|
||||
.zMove = { .effect = Z_EFFECT_RESET_STATS },
|
||||
.magicCoatAffected = TRUE,
|
||||
.sketchBanned = (B_SKETCH_BANS >= GEN_9),
|
||||
},
|
||||
|
||||
[MOVE_SEED_FLARE] =
|
||||
@ -10463,6 +10468,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.ignoresProtect = TRUE,
|
||||
.ignoresSubstitute = TRUE,
|
||||
.metronomeBanned = TRUE,
|
||||
.sketchBanned = (B_SKETCH_BANS >= GEN_9),
|
||||
},
|
||||
|
||||
[MOVE_SHORE_UP] =
|
||||
@ -13220,6 +13226,8 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.ignoresProtect = TRUE,
|
||||
.mirrorMoveBanned = TRUE,
|
||||
.metronomeBanned = TRUE,
|
||||
.healBlockBanned = TRUE,
|
||||
.sketchBanned = (B_SKETCH_BANS >= GEN_9),
|
||||
},
|
||||
|
||||
[MOVE_SALT_CURE] =
|
||||
@ -13285,7 +13293,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
|
||||
[MOVE_FILLET_AWAY] =
|
||||
{
|
||||
.effect = EFFECT_PLACEHOLDER, // EFFECT_FILLET_AWAY
|
||||
.effect = EFFECT_FILLET_AWAY,
|
||||
.power = 0,
|
||||
.type = TYPE_NORMAL,
|
||||
.accuracy = 0,
|
||||
@ -13620,7 +13628,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.category = BATTLE_CATEGORY_PHYSICAL,
|
||||
.makesContact = TRUE,
|
||||
.slicingMove = TRUE,
|
||||
.healBlockBanned = B_EXTRAPOLATED_MOVE_FLAGS,
|
||||
.healBlockBanned = TRUE,
|
||||
},
|
||||
|
||||
[MOVE_DOUBLE_SHOCK] =
|
||||
@ -13704,6 +13712,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.instructBanned = TRUE,
|
||||
.encoreBanned = TRUE,
|
||||
.assistBanned = TRUE,
|
||||
.sketchBanned = (B_SKETCH_BANS >= GEN_9),
|
||||
},
|
||||
|
||||
[MOVE_WICKED_TORQUE] =
|
||||
@ -13727,6 +13736,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.instructBanned = TRUE,
|
||||
.encoreBanned = TRUE,
|
||||
.assistBanned = TRUE,
|
||||
.sketchBanned = (B_SKETCH_BANS >= GEN_9),
|
||||
},
|
||||
|
||||
[MOVE_NOXIOUS_TORQUE] =
|
||||
@ -13750,6 +13760,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.instructBanned = TRUE,
|
||||
.encoreBanned = TRUE,
|
||||
.assistBanned = TRUE,
|
||||
.sketchBanned = (B_SKETCH_BANS >= GEN_9),
|
||||
},
|
||||
|
||||
[MOVE_COMBAT_TORQUE] =
|
||||
@ -13773,6 +13784,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.instructBanned = TRUE,
|
||||
.encoreBanned = TRUE,
|
||||
.assistBanned = TRUE,
|
||||
.sketchBanned = (B_SKETCH_BANS >= GEN_9),
|
||||
},
|
||||
|
||||
[MOVE_MAGICAL_TORQUE] =
|
||||
@ -13796,6 +13808,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.instructBanned = TRUE,
|
||||
.encoreBanned = TRUE,
|
||||
.assistBanned = TRUE,
|
||||
.sketchBanned = (B_SKETCH_BANS >= GEN_9),
|
||||
},
|
||||
|
||||
[MOVE_PSYBLADE] =
|
||||
@ -13854,7 +13867,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.category = BATTLE_CATEGORY_SPECIAL,
|
||||
.thawsUser = TRUE,
|
||||
.metronomeBanned = TRUE,
|
||||
.healBlockBanned = B_EXTRAPOLATED_MOVE_FLAGS,
|
||||
.healBlockBanned = TRUE,
|
||||
},
|
||||
|
||||
[MOVE_SYRUP_BOMB] =
|
||||
@ -13888,6 +13901,226 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
.metronomeBanned = TRUE,
|
||||
},
|
||||
|
||||
[MOVE_ELECTRO_SHOT] =
|
||||
{
|
||||
.effect = EFFECT_PLACEHOLDER, //EFFECT_ELECTRO_SHOT
|
||||
.power = 130,
|
||||
.type = TYPE_ELECTRIC,
|
||||
.accuracy = 100,
|
||||
.pp = 10,
|
||||
.secondaryEffectChance = 0,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.category = BATTLE_CATEGORY_SPECIAL,
|
||||
//.sheerForceBoost = TRUE, (uncomment when effect is implemented, otherwise it breaks the Sheer Force Test)
|
||||
},
|
||||
|
||||
[MOVE_TERA_STARSTORM] =
|
||||
{
|
||||
.effect = EFFECT_PLACEHOLDER, //EFFECT_TERA_STARSTORM
|
||||
.power = 120,
|
||||
.type = TYPE_NORMAL, // Stellar type if used by Terapagos-Stellar
|
||||
.accuracy = 100,
|
||||
.pp = 5,
|
||||
.secondaryEffectChance = 0,
|
||||
.target = MOVE_TARGET_SELECTED, // MOVE_TARGET_BOTH if used by Terapagos-Stellar
|
||||
.priority = 0,
|
||||
.category = BATTLE_CATEGORY_SPECIAL,
|
||||
.assistBanned = TRUE,
|
||||
.copycatBanned = TRUE,
|
||||
.mimicBanned = TRUE,
|
||||
.sketchBanned = (B_SKETCH_BANS >= GEN_9),
|
||||
},
|
||||
|
||||
[MOVE_FICKLE_BEAM] =
|
||||
{
|
||||
.effect = EFFECT_PLACEHOLDER, //EFFECT_FICKLE_BEAM
|
||||
.power = 80,
|
||||
.type = TYPE_DRAGON,
|
||||
.accuracy = 100,
|
||||
.pp = 5,
|
||||
.secondaryEffectChance = 0,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.category = BATTLE_CATEGORY_SPECIAL,
|
||||
},
|
||||
|
||||
[MOVE_BURNING_BULWARK] =
|
||||
{
|
||||
.effect = EFFECT_PROTECT, // NEEDS ACTUAL PROTECT SIDE EFFECT
|
||||
.power = 0,
|
||||
.type = TYPE_FIRE,
|
||||
.accuracy = 0,
|
||||
.pp = 10,
|
||||
.secondaryEffectChance = 0,
|
||||
.target = MOVE_TARGET_USER,
|
||||
.priority = 4,
|
||||
.category = BATTLE_CATEGORY_STATUS,
|
||||
.zMove = { .effect = Z_EFFECT_RESET_STATS },
|
||||
.protectionMove = TRUE,
|
||||
.ignoresProtect = TRUE,
|
||||
.mirrorMoveBanned = TRUE,
|
||||
.metronomeBanned = TRUE,
|
||||
.copycatBanned = TRUE,
|
||||
.assistBanned = TRUE,
|
||||
},
|
||||
|
||||
[MOVE_THUNDERCLAP] =
|
||||
{
|
||||
.effect = EFFECT_SUCKER_PUNCH,
|
||||
.power = 70,
|
||||
.type = TYPE_ELECTRIC,
|
||||
.accuracy = 100,
|
||||
.pp = 5,
|
||||
.secondaryEffectChance = 0,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 1,
|
||||
.category = BATTLE_CATEGORY_SPECIAL,
|
||||
},
|
||||
|
||||
[MOVE_MIGHTY_CLEAVE] =
|
||||
{
|
||||
.effect = EFFECT_FEINT,
|
||||
.power = 95,
|
||||
.type = TYPE_ROCK,
|
||||
.accuracy = 100,
|
||||
.pp = 5,
|
||||
.secondaryEffectChance = 100,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.category = BATTLE_CATEGORY_PHYSICAL,
|
||||
.makesContact = TRUE,
|
||||
.slicingMove = TRUE,
|
||||
},
|
||||
|
||||
[MOVE_TACHYON_CUTTER] =
|
||||
{
|
||||
.effect = EFFECT_HIT,
|
||||
.power = 50,
|
||||
.type = TYPE_STEEL,
|
||||
.accuracy = 0,
|
||||
.pp = 10,
|
||||
.secondaryEffectChance = 0,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.category = BATTLE_CATEGORY_SPECIAL,
|
||||
.strikeCount = 2,
|
||||
.slicingMove = TRUE,
|
||||
},
|
||||
|
||||
[MOVE_HARD_PRESS] =
|
||||
{
|
||||
.effect = EFFECT_WRING_OUT,
|
||||
.power = 1,
|
||||
.type = TYPE_STEEL,
|
||||
.accuracy = 100,
|
||||
.pp = 10,
|
||||
.secondaryEffectChance = 0,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.category = BATTLE_CATEGORY_PHYSICAL,
|
||||
.makesContact = TRUE,
|
||||
},
|
||||
|
||||
[MOVE_DRAGON_CHEER] =
|
||||
{
|
||||
.effect = EFFECT_PLACEHOLDER, //EFFECT_DRAGON_CHEER
|
||||
.power = 0,
|
||||
.type = TYPE_DRAGON,
|
||||
.accuracy = 0,
|
||||
.pp = 15,
|
||||
.secondaryEffectChance = 0,
|
||||
.target = MOVE_TARGET_ALLY,
|
||||
.priority = 0,
|
||||
.category = BATTLE_CATEGORY_STATUS,
|
||||
.ignoresSubstitute = TRUE,
|
||||
},
|
||||
|
||||
[MOVE_ALLURING_VOICE] =
|
||||
{
|
||||
.effect = EFFECT_PLACEHOLDER, //EFFECT_ALLURING_VOICE
|
||||
.power = 80,
|
||||
.type = TYPE_FAIRY,
|
||||
.accuracy = 100,
|
||||
.pp = 10,
|
||||
.secondaryEffectChance = 0,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.category = BATTLE_CATEGORY_SPECIAL,
|
||||
.soundMove = TRUE,
|
||||
.ignoresSubstitute = TRUE,
|
||||
},
|
||||
|
||||
[MOVE_TEMPER_FLARE] =
|
||||
{
|
||||
.effect = EFFECT_STOMPING_TANTRUM,
|
||||
.power = 75,
|
||||
.type = TYPE_FIRE,
|
||||
.accuracy = 100,
|
||||
.pp = 10,
|
||||
.secondaryEffectChance = 0,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.category = BATTLE_CATEGORY_PHYSICAL,
|
||||
.makesContact = TRUE,
|
||||
},
|
||||
|
||||
[MOVE_SUPERCELL_SLAM] =
|
||||
{
|
||||
.effect = EFFECT_RECOIL_IF_MISS,
|
||||
.power = 100,
|
||||
.type = TYPE_ELECTRIC,
|
||||
.accuracy = 95,
|
||||
.pp = 15,
|
||||
.secondaryEffectChance = 0,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.category = BATTLE_CATEGORY_PHYSICAL,
|
||||
.makesContact = TRUE,
|
||||
},
|
||||
|
||||
[MOVE_PSYCHIC_NOISE] =
|
||||
{
|
||||
.effect = EFFECT_PLACEHOLDER, //EFFECT_PSYCHIC_NOISE
|
||||
.power = 75,
|
||||
.type = TYPE_PSYCHIC,
|
||||
.accuracy = 100,
|
||||
.pp = 10,
|
||||
.secondaryEffectChance = 0,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.category = BATTLE_CATEGORY_SPECIAL,
|
||||
.soundMove = TRUE,
|
||||
.ignoresSubstitute = TRUE,
|
||||
},
|
||||
|
||||
[MOVE_UPPER_HAND] =
|
||||
{
|
||||
.effect = EFFECT_PLACEHOLDER, //EFFECT_UPPER_HAND
|
||||
.power = 65,
|
||||
.type = TYPE_FIGHTING,
|
||||
.accuracy = 100,
|
||||
.pp = 15,
|
||||
.secondaryEffectChance = 0,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 3,
|
||||
.category = BATTLE_CATEGORY_PHYSICAL,
|
||||
.makesContact = TRUE,
|
||||
},
|
||||
|
||||
[MOVE_MALIGNANT_CHAIN] =
|
||||
{
|
||||
.effect = EFFECT_POISON_FANG,
|
||||
.power = 100,
|
||||
.type = TYPE_POISON,
|
||||
.accuracy = 100,
|
||||
.pp = 5,
|
||||
.secondaryEffectChance = 50,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
.priority = 0,
|
||||
.category = BATTLE_CATEGORY_SPECIAL,
|
||||
},
|
||||
|
||||
// Z-Moves
|
||||
[MOVE_BREAKNECK_BLITZ] =
|
||||
{
|
||||
|
||||
@ -6074,6 +6074,36 @@ const struct ContestMove gContestMoves[MOVES_COUNT] =
|
||||
[MOVE_SYRUP_BOMB] = {0}, // TODO
|
||||
|
||||
[MOVE_IVY_CUDGEL] = {0}, // TODO
|
||||
|
||||
[MOVE_ELECTRO_SHOT] = {0}, // TODO
|
||||
|
||||
[MOVE_TERA_STARSTORM] = {0}, // TODO
|
||||
|
||||
[MOVE_FICKLE_BEAM] = {0}, // TODO
|
||||
|
||||
[MOVE_BURNING_BULWARK] = {0}, // TODO
|
||||
|
||||
[MOVE_THUNDERCLAP] = {0}, // TODO
|
||||
|
||||
[MOVE_MIGHTY_CLEAVE] = {0}, // TODO
|
||||
|
||||
[MOVE_TACHYON_CUTTER] = {0}, // TODO
|
||||
|
||||
[MOVE_HARD_PRESS] = {0}, // TODO
|
||||
|
||||
[MOVE_DRAGON_CHEER] = {0}, // TODO
|
||||
|
||||
[MOVE_ALLURING_VOICE] = {0}, // TODO
|
||||
|
||||
[MOVE_TEMPER_FLARE] = {0}, // TODO
|
||||
|
||||
[MOVE_SUPERCELL_SLAM] = {0}, // TODO
|
||||
|
||||
[MOVE_PSYCHIC_NOISE] = {0}, // TODO
|
||||
|
||||
[MOVE_UPPER_HAND] = {0}, // TODO
|
||||
|
||||
[MOVE_MALIGNANT_CHAIN] = {0}, // TODO
|
||||
};
|
||||
|
||||
const struct ContestEffect gContestEffects[] =
|
||||
|
||||
@ -663,6 +663,9 @@ const u32 gItemIconPalette_UnremarkableTeacup[] = INCBIN_U32("graphics/items/ico
|
||||
const u32 gItemIcon_MasterpieceTeacup[] = INCBIN_U32("graphics/items/icons/masterpiece_teacup.4bpp.lz");
|
||||
const u32 gItemIconPalette_MasterpieceTeacup[] = INCBIN_U32("graphics/items/icon_palettes/masterpiece_teacup.gbapal.lz");
|
||||
|
||||
const u32 gItemIcon_MetalAlloy[] = INCBIN_U32("graphics/items/icons/metal_alloy.4bpp.lz");
|
||||
const u32 gItemIconPalette_MetalAlloy[] = INCBIN_U32("graphics/items/icon_palettes/metal_alloy.gbapal.lz");
|
||||
|
||||
// Nectars
|
||||
|
||||
const u32 gItemIcon_RedNectar[] = INCBIN_U32("graphics/items/icons/red_nectar.4bpp.lz");
|
||||
|
||||
@ -859,6 +859,8 @@ const u32 *const gItemIconTable[ITEMS_COUNT + 1][2] =
|
||||
[ITEM_SWIFT_MOCHI] = {gItemIcon_Mochi, gItemIconPalette_SwiftMochi},
|
||||
[ITEM_FRESH_START_MOCHI] = {gItemIcon_Mochi, gItemIconPalette_FreshStartMochi},
|
||||
[ITEM_GLIMMERING_CHARM] = {gItemIcon_GlimmeringCharm, gItemIconPalette_GlimmeringCharm},
|
||||
[ITEM_METAL_ALLOY] = {gItemIcon_MetalAlloy, gItemIconPalette_MetalAlloy},
|
||||
[ITEM_STELLAR_TERA_SHARD] = {gItemIcon_QuestionMark, gItemIconPalette_QuestionMark}, //{gItemIcon_TeraShard, gItemIconPalette_StellarTeraShard},
|
||||
// Return to field arrow
|
||||
[ITEMS_COUNT] = {gItemIcon_ReturnToFieldArrow, gItemIconPalette_ReturnToFieldArrow},
|
||||
};
|
||||
|
||||
892
src/data/items.h
892
src/data/items.h
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -3284,6 +3284,54 @@ static const u8 sIvyCudgelDescription[] = _(
|
||||
"Type changes with held mask.\n"
|
||||
"High critical-hit ratio.");
|
||||
|
||||
static const u8 sElectroShotDescription[] = _(
|
||||
"Absorbs electricity in one turn,\n"
|
||||
"then attacks next turn.");
|
||||
|
||||
static const u8 sTeraStarstormDescription[] = _(
|
||||
"Damages all opponents if user is\n"
|
||||
"Stellar form Terapagos.");
|
||||
|
||||
static const u8 sFickleBeamDescription[] = _(
|
||||
"Shoots a beam of light. Sometimes\n"
|
||||
"twice as strong.");
|
||||
|
||||
static const u8 sBurningBulwarkDescription[] = _(
|
||||
"Evades attack, and burns\n"
|
||||
"the foe if struck.");
|
||||
|
||||
static const u8 sTachyonCutterDescription[] = _(
|
||||
"Launches particle blades at\n"
|
||||
"the target. Strikes twice.");
|
||||
|
||||
static const u8 sDragonCheerDescription[] = _(
|
||||
"Increases allies' critical hit\n"
|
||||
"ration, especially if Dragons.");
|
||||
|
||||
static const u8 sAlluringVoiceDescription[] = _(
|
||||
"Confuses the target if their\n"
|
||||
"stats were boosted this turn.");
|
||||
|
||||
static const u8 sTemperFlareDescription[] = _(
|
||||
"A desperation attack. Power\n"
|
||||
"doubles if last move failed.");
|
||||
|
||||
static const u8 sSupercellSlamDescription[] = _(
|
||||
"An electrified slam. If it\n"
|
||||
"misses, the user is hurt.");
|
||||
|
||||
static const u8 sPsychicNoiseDescription[] = _(
|
||||
"Unpleasant sound waves that\n"
|
||||
"damage and prevent healing.");
|
||||
|
||||
static const u8 sUpperHandDescription[] = _(
|
||||
"Makes the target flinch if\n"
|
||||
"readying a priority move.");
|
||||
|
||||
static const u8 sMalignantChainDescription[] = _(
|
||||
"A corrosive chain attack\n"
|
||||
"that may badly poison.");
|
||||
|
||||
const u8 gNotDoneYetDescription[] = _(
|
||||
"This move can't be used. Its\n"
|
||||
"effect is in development.");
|
||||
@ -4127,4 +4175,19 @@ const u8 *const gMoveDescriptionPointers[MOVES_COUNT - 1] =
|
||||
[MOVE_MATCHA_GOTCHA - 1] = sMatchaGotchaDescription,
|
||||
[MOVE_SYRUP_BOMB - 1] = sSyrupBombDescription,
|
||||
[MOVE_IVY_CUDGEL - 1] = sIvyCudgelDescription,
|
||||
[MOVE_ELECTRO_SHOT - 1] = sElectroShotDescription,
|
||||
[MOVE_TERA_STARSTORM - 1] = sTeraStarstormDescription,
|
||||
[MOVE_FICKLE_BEAM - 1] = sFickleBeamDescription,
|
||||
[MOVE_BURNING_BULWARK - 1] = sBurningBulwarkDescription,
|
||||
[MOVE_THUNDERCLAP - 1] = sSuckerPunchDescription,
|
||||
[MOVE_MIGHTY_CLEAVE - 1] = sFeintDescription,
|
||||
[MOVE_TACHYON_CUTTER - 1] = sTachyonCutterDescription,
|
||||
[MOVE_HARD_PRESS - 1] = sWringOutDescription,
|
||||
[MOVE_DRAGON_CHEER - 1] = sDragonCheerDescription,
|
||||
[MOVE_ALLURING_VOICE - 1] = sAlluringVoiceDescription,
|
||||
[MOVE_TEMPER_FLARE - 1] = sTemperFlareDescription,
|
||||
[MOVE_SUPERCELL_SLAM - 1] = sSupercellSlamDescription,
|
||||
[MOVE_PSYCHIC_NOISE - 1] = sPsychicNoiseDescription,
|
||||
[MOVE_UPPER_HAND - 1] = sUpperHandDescription,
|
||||
[MOVE_MALIGNANT_CHAIN - 1] = sMalignantChainDescription,
|
||||
};
|
||||
|
||||
@ -835,6 +835,21 @@ const u8 gMoveNames[MOVES_COUNT_DYNAMAX][MOVE_NAME_LENGTH + 1] =
|
||||
[MOVE_MATCHA_GOTCHA] = _("Matcha Gotcha"),
|
||||
[MOVE_SYRUP_BOMB] = _("Syrup Bomb"),
|
||||
[MOVE_IVY_CUDGEL] = _("Ivy Cudgel"),
|
||||
[MOVE_ELECTRO_SHOT] = _("Electro Shot"),
|
||||
[MOVE_TERA_STARSTORM] = _("Tera Starstorm"),
|
||||
[MOVE_FICKLE_BEAM] = _("Fickle Beam"),
|
||||
[MOVE_BURNING_BULWARK] = _("Burning Bulwark"),
|
||||
[MOVE_THUNDERCLAP] = _("Thunderclap"),
|
||||
[MOVE_MIGHTY_CLEAVE] = _("Mighty Cleave"),
|
||||
[MOVE_TACHYON_CUTTER] = _("Tachyon Cutter"),
|
||||
[MOVE_HARD_PRESS] = _("Hard Press"),
|
||||
[MOVE_DRAGON_CHEER] = _("Dragon Cheer"),
|
||||
[MOVE_ALLURING_VOICE] = _("Alluring Voice"),
|
||||
[MOVE_TEMPER_FLARE] = _("Temper Flare"),
|
||||
[MOVE_SUPERCELL_SLAM] = _("Supercell Slam"),
|
||||
[MOVE_PSYCHIC_NOISE] = _("Psychic Noise"),
|
||||
[MOVE_UPPER_HAND] = _("Upper Hand"),
|
||||
[MOVE_MALIGNANT_CHAIN] = _("Malignant Chain"),
|
||||
// Max Moves
|
||||
[MOVE_MAX_GUARD] = _("Max Guard"),
|
||||
[MOVE_MAX_STRIKE] = _("Max Strike"),
|
||||
@ -1727,6 +1742,21 @@ const u8 gMoveNames[MOVES_COUNT_DYNAMAX][MOVE_NAME_LENGTH + 1] =
|
||||
[MOVE_MATCHA_GOTCHA] = _("MatchaGotcha"),
|
||||
[MOVE_SYRUP_BOMB] = _("Syrup Bomb"),
|
||||
[MOVE_IVY_CUDGEL] = _("Ivy Cudgel"),
|
||||
[MOVE_ELECTRO_SHOT] = _("Electro Shot"),
|
||||
[MOVE_TERA_STARSTORM] = _("TeraStarstrm"),
|
||||
[MOVE_FICKLE_BEAM] = _("Fickle Beam"),
|
||||
[MOVE_BURNING_BULWARK] = _("BurnngBulwrk"),
|
||||
[MOVE_THUNDERCLAP] = _("Thunderclap"),
|
||||
[MOVE_MIGHTY_CLEAVE] = _("MightyCleave"),
|
||||
[MOVE_TACHYON_CUTTER] = _("TachyonCuttr"),
|
||||
[MOVE_HARD_PRESS] = _("Hard Press"),
|
||||
[MOVE_DRAGON_CHEER] = _("Dragon Cheer"),
|
||||
[MOVE_ALLURING_VOICE] = _("AllurngVoice"),
|
||||
[MOVE_TEMPER_FLARE] = _("Temper Flare"),
|
||||
[MOVE_SUPERCELL_SLAM] = _("SuprcellSlam"),
|
||||
[MOVE_PSYCHIC_NOISE] = _("PsychicNoise"),
|
||||
[MOVE_UPPER_HAND] = _("Upper Hand"),
|
||||
[MOVE_MALIGNANT_CHAIN] = _("MalignntChan"),
|
||||
// Max Moves
|
||||
[MOVE_MAX_GUARD] = _("M-Guard"),
|
||||
[MOVE_MAX_STRIKE] = _("M-Strike"),
|
||||
|
||||
@ -229,7 +229,6 @@ static void StorePokemonInDaycare(struct Pokemon *mon, struct DaycareMon *daycar
|
||||
}
|
||||
|
||||
daycareMon->mon = mon->box;
|
||||
BoxMonRestorePP(&daycareMon->mon);
|
||||
daycareMon->steps = 0;
|
||||
ZeroMonData(mon);
|
||||
CompactPartySlots();
|
||||
|
||||
28
src/debug.c
28
src/debug.c
@ -3017,7 +3017,7 @@ static void ResetMonDataStruct(struct DebugMonData *sDebugMonData)
|
||||
{
|
||||
sDebugMonData->species = 1;
|
||||
sDebugMonData->level = MIN_LEVEL;
|
||||
sDebugMonData->isShiny = 0;
|
||||
sDebugMonData->isShiny = FALSE;
|
||||
sDebugMonData->nature = 0;
|
||||
sDebugMonData->abilityNum = 0;
|
||||
sDebugMonData->mon_iv_hp = 0;
|
||||
@ -3343,7 +3343,7 @@ static void DebugAction_Give_Pokemon_SelectNature(u8 taskId)
|
||||
ConvertIntToDecimalStringN(gStringVar3, gTasks[taskId].tInput, STR_CONV_MODE_LEADING_ZEROS, 2);
|
||||
StringCopyPadded(gStringVar3, gStringVar3, CHAR_SPACE, 15);
|
||||
abilityId = GetAbilityBySpecies(sDebugMonData->species, 0);
|
||||
StringCopy(gStringVar1, gAbilityNames[abilityId]);
|
||||
StringCopy(gStringVar1, gAbilities[abilityId].name);
|
||||
StringExpandPlaceholders(gStringVar4, sDebugText_PokemonAbility);
|
||||
AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 1, 1, 0, NULL);
|
||||
|
||||
@ -3388,7 +3388,7 @@ static void DebugAction_Give_Pokemon_SelectAbility(u8 taskId)
|
||||
StringCopy(gStringVar2, gText_DigitIndicator[gTasks[taskId].tDigit]);
|
||||
ConvertIntToDecimalStringN(gStringVar3, gTasks[taskId].tInput, STR_CONV_MODE_LEADING_ZEROS, 2);
|
||||
StringCopyPadded(gStringVar3, gStringVar3, CHAR_SPACE, 15);
|
||||
StringCopy(gStringVar1, gAbilityNames[abilityId]);
|
||||
StringCopy(gStringVar1, gAbilities[abilityId].name);
|
||||
StringExpandPlaceholders(gStringVar4, sDebugText_PokemonAbility);
|
||||
AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 1, 1, 0, NULL);
|
||||
}
|
||||
@ -3687,7 +3687,7 @@ static void DebugAction_Give_Pokemon_ComplexCreateMon(u8 taskId) //https://githu
|
||||
u8 iv_val;
|
||||
u16 species = sDebugMonData->species;
|
||||
u8 level = sDebugMonData->level;
|
||||
u8 isShiny = sDebugMonData->isShiny; //Shiny: no 0, yes 1
|
||||
bool8 isShiny = sDebugMonData->isShiny;
|
||||
u8 nature = sDebugMonData->nature;
|
||||
u8 abilityNum = sDebugMonData->abilityNum;
|
||||
moves[0] = sDebugMonData->mon_move_0;
|
||||
@ -3704,26 +3704,10 @@ static void DebugAction_Give_Pokemon_ComplexCreateMon(u8 taskId) //https://githu
|
||||
//Nature
|
||||
if (nature == NUM_NATURES || nature == 0xFF)
|
||||
nature = Random() % NUM_NATURES;
|
||||
CreateMonWithNature(&mon, species, level, 32, nature);
|
||||
|
||||
//Shininess
|
||||
if (isShiny == 1)
|
||||
{
|
||||
u32 personality;
|
||||
u32 otid = gSaveBlock2Ptr->playerTrainerId[0]
|
||||
| (gSaveBlock2Ptr->playerTrainerId[1] << 8)
|
||||
| (gSaveBlock2Ptr->playerTrainerId[2] << 16)
|
||||
| (gSaveBlock2Ptr->playerTrainerId[3] << 24);
|
||||
|
||||
do
|
||||
{
|
||||
personality = Random32();
|
||||
personality = ((((Random() % 8) ^ (HIHALF(otid) ^ LOHALF(otid))) ^ LOHALF(personality)) << 16) | LOHALF(personality);
|
||||
} while (nature != GetNatureFromPersonality(personality));
|
||||
|
||||
CreateMon(&mon, species, level, 32, 1, personality, OT_ID_PRESET, otid);
|
||||
}
|
||||
else
|
||||
CreateMonWithNature(&mon, species, level, 32, nature);
|
||||
SetMonData(&mon, MON_DATA_IS_SHINY, &isShiny);
|
||||
|
||||
//IVs
|
||||
for (i = 0; i < NUM_STATS; i++)
|
||||
|
||||
@ -209,7 +209,8 @@ void EvolutionScene(struct Pokemon *mon, u16 postEvoSpecies, bool8 canStopEvo, u
|
||||
{
|
||||
u8 name[POKEMON_NAME_BUFFER_SIZE];
|
||||
u16 currSpecies;
|
||||
u32 trainerId, personality;
|
||||
u32 personality;
|
||||
bool32 isShiny;
|
||||
u8 id;
|
||||
|
||||
SetHBlankCallback(NULL);
|
||||
@ -255,13 +256,13 @@ void EvolutionScene(struct Pokemon *mon, u16 postEvoSpecies, bool8 canStopEvo, u
|
||||
|
||||
// preEvo sprite
|
||||
currSpecies = GetMonData(mon, MON_DATA_SPECIES);
|
||||
trainerId = GetMonData(mon, MON_DATA_OT_ID);
|
||||
isShiny = GetMonData(mon, MON_DATA_IS_SHINY);
|
||||
personality = GetMonData(mon, MON_DATA_PERSONALITY);
|
||||
LoadSpecialPokePic(gMonSpritesGfxPtr->sprites.ptr[B_POSITION_OPPONENT_LEFT],
|
||||
currSpecies,
|
||||
personality,
|
||||
TRUE);
|
||||
LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(currSpecies, trainerId, personality), OBJ_PLTT_ID(1), PLTT_SIZE_4BPP);
|
||||
LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(currSpecies, isShiny, personality), OBJ_PLTT_ID(1), PLTT_SIZE_4BPP);
|
||||
|
||||
SetMultiuseSpriteTemplateToPokemon(currSpecies, B_POSITION_OPPONENT_LEFT);
|
||||
gMultiuseSpriteTemplate.affineAnims = gDummySpriteAffineAnimTable;
|
||||
@ -276,7 +277,7 @@ void EvolutionScene(struct Pokemon *mon, u16 postEvoSpecies, bool8 canStopEvo, u
|
||||
postEvoSpecies,
|
||||
personality,
|
||||
TRUE);
|
||||
LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(postEvoSpecies, trainerId, personality), OBJ_PLTT_ID(2), PLTT_SIZE_4BPP);
|
||||
LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(postEvoSpecies, isShiny, personality), OBJ_PLTT_ID(2), PLTT_SIZE_4BPP);
|
||||
|
||||
SetMultiuseSpriteTemplateToPokemon(postEvoSpecies, B_POSITION_OPPONENT_RIGHT);
|
||||
gMultiuseSpriteTemplate.affineAnims = gDummySpriteAffineAnimTable;
|
||||
@ -310,11 +311,12 @@ static void CB2_EvolutionSceneLoadGraphics(void)
|
||||
{
|
||||
u8 id;
|
||||
u16 postEvoSpecies;
|
||||
u32 trainerId, personality;
|
||||
u32 personality;
|
||||
struct Pokemon *mon = &gPlayerParty[gTasks[sEvoStructPtr->evoTaskId].tPartyId];
|
||||
bool8 isShiny;
|
||||
|
||||
postEvoSpecies = gTasks[sEvoStructPtr->evoTaskId].tPostEvoSpecies;
|
||||
trainerId = GetMonData(mon, MON_DATA_OT_ID);
|
||||
isShiny = GetMonData(mon, MON_DATA_IS_SHINY);
|
||||
personality = GetMonData(mon, MON_DATA_PERSONALITY);
|
||||
|
||||
SetHBlankCallback(NULL);
|
||||
@ -352,7 +354,7 @@ static void CB2_EvolutionSceneLoadGraphics(void)
|
||||
postEvoSpecies,
|
||||
personality,
|
||||
TRUE);
|
||||
LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(postEvoSpecies, trainerId, personality), OBJ_PLTT_ID(2), PLTT_SIZE_4BPP);
|
||||
LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(postEvoSpecies, isShiny, personality), OBJ_PLTT_ID(2), PLTT_SIZE_4BPP);
|
||||
|
||||
SetMultiuseSpriteTemplateToPokemon(postEvoSpecies, B_POSITION_OPPONENT_RIGHT);
|
||||
gMultiuseSpriteTemplate.affineAnims = gDummySpriteAffineAnimTable;
|
||||
@ -416,13 +418,13 @@ static void CB2_TradeEvolutionSceneLoadGraphics(void)
|
||||
break;
|
||||
case 4:
|
||||
{
|
||||
u32 trainerId = GetMonData(mon, MON_DATA_OT_ID);
|
||||
bool8 isShiny = GetMonData(mon, MON_DATA_IS_SHINY);
|
||||
u32 personality = GetMonData(mon, MON_DATA_PERSONALITY);
|
||||
LoadSpecialPokePic(gMonSpritesGfxPtr->sprites.ptr[B_POSITION_OPPONENT_RIGHT],
|
||||
postEvoSpecies,
|
||||
personality,
|
||||
TRUE);
|
||||
LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(postEvoSpecies, trainerId, personality), OBJ_PLTT_ID(2), PLTT_SIZE_4BPP);
|
||||
LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(postEvoSpecies, isShiny, personality), OBJ_PLTT_ID(2), PLTT_SIZE_4BPP);
|
||||
gMain.state++;
|
||||
}
|
||||
break;
|
||||
@ -464,8 +466,9 @@ void TradeEvolutionScene(struct Pokemon *mon, u16 postEvoSpecies, u8 preEvoSprit
|
||||
{
|
||||
u8 name[POKEMON_NAME_BUFFER_SIZE];
|
||||
u16 currSpecies;
|
||||
u32 trainerId, personality;
|
||||
u32 personality;
|
||||
u8 id;
|
||||
bool8 isShiny;
|
||||
|
||||
GetMonData(mon, MON_DATA_NICKNAME, name);
|
||||
StringCopy_Nickname(gStringVar1, name);
|
||||
@ -476,7 +479,7 @@ void TradeEvolutionScene(struct Pokemon *mon, u16 postEvoSpecies, u8 preEvoSprit
|
||||
// preEvo sprite
|
||||
currSpecies = GetMonData(mon, MON_DATA_SPECIES);
|
||||
personality = GetMonData(mon, MON_DATA_PERSONALITY);
|
||||
trainerId = GetMonData(mon, MON_DATA_OT_ID);
|
||||
isShiny = GetMonData(mon, MON_DATA_IS_SHINY);
|
||||
|
||||
sEvoStructPtr = AllocZeroed(sizeof(struct EvoInfo));
|
||||
sEvoStructPtr->preEvoSpriteId = preEvoSpriteId;
|
||||
@ -486,7 +489,7 @@ void TradeEvolutionScene(struct Pokemon *mon, u16 postEvoSpecies, u8 preEvoSprit
|
||||
personality,
|
||||
TRUE);
|
||||
|
||||
LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(postEvoSpecies, trainerId, personality), OBJ_PLTT_ID(2), PLTT_SIZE_4BPP);
|
||||
LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(postEvoSpecies, isShiny, personality), OBJ_PLTT_ID(2), PLTT_SIZE_4BPP);
|
||||
|
||||
SetMultiuseSpriteTemplateToPokemon(postEvoSpecies, B_POSITION_OPPONENT_LEFT);
|
||||
gMultiuseSpriteTemplate.affineAnims = gDummySpriteAffineAnimTable;
|
||||
@ -564,8 +567,6 @@ static void CreateShedinja(u16 preEvoSpecies, struct Pokemon *mon)
|
||||
SetMonData(&gPlayerParty[gPlayerPartyCount], MON_DATA_NICKNAME, GetSpeciesName(evolutions[1].targetSpecies));
|
||||
SetMonData(&gPlayerParty[gPlayerPartyCount], MON_DATA_HELD_ITEM, &data);
|
||||
SetMonData(&gPlayerParty[gPlayerPartyCount], MON_DATA_MARKINGS, &data);
|
||||
SetMonData(&gPlayerParty[gPlayerPartyCount], MON_DATA_ENCRYPT_SEPARATOR, &data);
|
||||
|
||||
#if P_SHEDINJA_BALL >= GEN_4
|
||||
SetMonData(&gPlayerParty[gPlayerPartyCount], MON_DATA_POKEBALL, &ball);
|
||||
RemoveBagItem(ball, 1);
|
||||
@ -573,7 +574,7 @@ static void CreateShedinja(u16 preEvoSpecies, struct Pokemon *mon)
|
||||
|
||||
for (i = MON_DATA_COOL_RIBBON; i < MON_DATA_COOL_RIBBON + CONTEST_CATEGORIES_COUNT; i++)
|
||||
SetMonData(&gPlayerParty[gPlayerPartyCount], i, &data);
|
||||
for (i = MON_DATA_CHAMPION_RIBBON; i <= MON_DATA_UNUSED_RIBBONS; i++)
|
||||
for (i = MON_DATA_CHAMPION_RIBBON; i <= MON_DATA_WORLD_RIBBON; i++)
|
||||
SetMonData(&gPlayerParty[gPlayerPartyCount], i, &data);
|
||||
|
||||
SetMonData(&gPlayerParty[gPlayerPartyCount], MON_DATA_STATUS, &data);
|
||||
|
||||
@ -183,7 +183,7 @@ static void AnimateIndoorShowMonBg(struct Task *);
|
||||
static bool8 SlideIndoorBannerOnscreen(struct Task *);
|
||||
static bool8 SlideIndoorBannerOffscreen(struct Task *);
|
||||
|
||||
static u8 InitFieldMoveMonSprite(u32, u32, u32);
|
||||
static u8 InitFieldMoveMonSprite(u32, bool8, u32);
|
||||
static void SpriteCB_FieldMoveMonSlideOnscreen(struct Sprite *);
|
||||
static void SpriteCB_FieldMoveMonWaitAfterCry(struct Sprite *);
|
||||
static void SpriteCB_FieldMoveMonSlideOffscreen(struct Sprite *);
|
||||
@ -919,7 +919,7 @@ u8 AddNewGameBirchObject(s16 x, s16 y, u8 subpriority)
|
||||
|
||||
u8 CreateMonSprite_PicBox(u16 species, s16 x, s16 y, u8 subpriority)
|
||||
{
|
||||
s32 spriteId = CreateMonPicSprite(species, 0, 0x8000, TRUE, x, y, 0, species);
|
||||
s32 spriteId = CreateMonPicSprite(species, FALSE, 0x8000, TRUE, x, y, 0, species);
|
||||
PreservePaletteInWeather(IndexOfSpritePaletteTag(species) + 0x10);
|
||||
if (spriteId == 0xFFFF)
|
||||
return MAX_SPRITES;
|
||||
@ -927,10 +927,10 @@ u8 CreateMonSprite_PicBox(u16 species, s16 x, s16 y, u8 subpriority)
|
||||
return spriteId;
|
||||
}
|
||||
|
||||
u8 CreateMonSprite_FieldMove(u16 species, u32 otId, u32 personality, s16 x, s16 y, u8 subpriority)
|
||||
u8 CreateMonSprite_FieldMove(u16 species, bool8 isShiny, u32 personality, s16 x, s16 y, u8 subpriority)
|
||||
{
|
||||
u16 spriteId = CreateMonPicSprite(species, otId, personality, TRUE, x, y, 0, species);
|
||||
PreservePaletteInWeather(IndexOfSpritePaletteTag(species) + 0x10);
|
||||
u16 spriteId = CreateMonPicSprite(species, isShiny, personality, TRUE, x, y, 0, species);
|
||||
PreservePaletteInWeather(gSprites[spriteId].oam.paletteNum + 0x10);
|
||||
if (spriteId == 0xFFFF)
|
||||
return MAX_SPRITES;
|
||||
else
|
||||
@ -2586,7 +2586,7 @@ bool8 FldEff_FieldMoveShowMonInit(void)
|
||||
bool32 noDucking = gFieldEffectArguments[0] & SHOW_MON_CRY_NO_DUCKING;
|
||||
pokemon = &gPlayerParty[(u8)gFieldEffectArguments[0]];
|
||||
gFieldEffectArguments[0] = GetMonData(pokemon, MON_DATA_SPECIES);
|
||||
gFieldEffectArguments[1] = GetMonData(pokemon, MON_DATA_OT_ID);
|
||||
gFieldEffectArguments[1] = GetMonData(pokemon, MON_DATA_IS_SHINY);
|
||||
gFieldEffectArguments[2] = GetMonData(pokemon, MON_DATA_PERSONALITY);
|
||||
gFieldEffectArguments[0] |= noDucking;
|
||||
FieldEffectStart(FLDEFF_FIELD_MOVE_SHOW_MON);
|
||||
@ -2926,14 +2926,14 @@ static bool8 SlideIndoorBannerOffscreen(struct Task *task)
|
||||
#undef tBgOffset
|
||||
#undef tMonSpriteId
|
||||
|
||||
static u8 InitFieldMoveMonSprite(u32 species, u32 otId, u32 personality)
|
||||
static u8 InitFieldMoveMonSprite(u32 species, bool8 isShiny, u32 personality)
|
||||
{
|
||||
bool16 noDucking;
|
||||
u8 monSprite;
|
||||
struct Sprite *sprite;
|
||||
noDucking = (species & SHOW_MON_CRY_NO_DUCKING) >> 16;
|
||||
species &= ~SHOW_MON_CRY_NO_DUCKING;
|
||||
monSprite = CreateMonSprite_FieldMove(species, otId, personality, 320, 80, 0);
|
||||
monSprite = CreateMonSprite_FieldMove(species, isShiny, personality, 320, 80, 0);
|
||||
sprite = &gSprites[monSprite];
|
||||
sprite->callback = SpriteCallbackDummy;
|
||||
sprite->oam.priority = 0;
|
||||
|
||||
@ -2462,10 +2462,7 @@ void CreateFrontierBrainPokemon(void)
|
||||
|
||||
do
|
||||
{
|
||||
do
|
||||
{
|
||||
j = Random32(); //should just be one while loop, but that doesn't match
|
||||
} while (IsShinyOtIdPersonality(FRONTIER_BRAIN_OTID, j));
|
||||
j = Random32(); //should just be one while loop, but that doesn't match
|
||||
} while (sFrontierBrainsMons[facility][symbol][i].nature != GetNatureFromPersonality(j));
|
||||
CreateMon(&gEnemyParty[monPartyId],
|
||||
sFrontierBrainsMons[facility][symbol][i].species,
|
||||
@ -2484,6 +2481,8 @@ void CreateFrontierBrainPokemon(void)
|
||||
friendship = 0;
|
||||
}
|
||||
SetMonData(&gEnemyParty[monPartyId], MON_DATA_FRIENDSHIP, &friendship);
|
||||
j = FALSE;
|
||||
SetMonData(&gPlayerParty[MULTI_PARTY_SIZE + i], MON_DATA_IS_SHINY, &j);
|
||||
CalculateMonStats(&gEnemyParty[monPartyId]);
|
||||
monPartyId++;
|
||||
}
|
||||
|
||||
@ -42,7 +42,8 @@ struct HallofFameMon
|
||||
{
|
||||
u32 tid;
|
||||
u32 personality;
|
||||
u16 species;
|
||||
u16 isShiny:1;
|
||||
u16 species:15;
|
||||
u8 lvl;
|
||||
u8 nickname[POKEMON_NAME_LENGTH];
|
||||
};
|
||||
@ -336,6 +337,7 @@ static const struct HallofFameMon sDummyFameMon =
|
||||
{
|
||||
.tid = 0x3EA03EA,
|
||||
.personality = 0,
|
||||
.isShiny = FALSE,
|
||||
.species = SPECIES_NONE,
|
||||
.lvl = 0,
|
||||
.nickname = {0}
|
||||
@ -447,6 +449,7 @@ static void Task_Hof_InitMonData(u8 taskId)
|
||||
{
|
||||
sHofMonPtr->mon[i].species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES_OR_EGG);
|
||||
sHofMonPtr->mon[i].tid = GetMonData(&gPlayerParty[i], MON_DATA_OT_ID);
|
||||
sHofMonPtr->mon[i].isShiny = GetMonData(&gPlayerParty[i], MON_DATA_IS_SHINY);
|
||||
sHofMonPtr->mon[i].personality = GetMonData(&gPlayerParty[i], MON_DATA_PERSONALITY);
|
||||
sHofMonPtr->mon[i].lvl = GetMonData(&gPlayerParty[i], MON_DATA_LEVEL);
|
||||
GetMonData(&gPlayerParty[i], MON_DATA_NICKNAME, nickname);
|
||||
@ -458,6 +461,7 @@ static void Task_Hof_InitMonData(u8 taskId)
|
||||
{
|
||||
sHofMonPtr->mon[i].species = SPECIES_NONE;
|
||||
sHofMonPtr->mon[i].tid = 0;
|
||||
sHofMonPtr->mon[i].isShiny = FALSE;
|
||||
sHofMonPtr->mon[i].personality = 0;
|
||||
sHofMonPtr->mon[i].lvl = 0;
|
||||
sHofMonPtr->mon[i].nickname[0] = EOS;
|
||||
@ -583,7 +587,7 @@ static void Task_Hof_DisplayMon(u8 taskId)
|
||||
if (currMon->species == SPECIES_EGG)
|
||||
destY += 10;
|
||||
|
||||
spriteId = CreateMonPicSprite_Affine(currMon->species, currMon->tid, currMon->personality, MON_PIC_AFFINE_FRONT, startX, startY, currMonId, TAG_NONE);
|
||||
spriteId = CreateMonPicSprite_Affine(currMon->species, currMon->isShiny, currMon->personality, MON_PIC_AFFINE_FRONT, startX, startY, currMonId, TAG_NONE);
|
||||
gSprites[spriteId].tDestinationX = destX;
|
||||
gSprites[spriteId].tDestinationY = destY;
|
||||
gSprites[spriteId].data[0] = 0;
|
||||
@ -929,7 +933,7 @@ static void Task_HofPC_DrawSpritesPrintText(u8 taskId)
|
||||
if (currMon->species == SPECIES_EGG)
|
||||
posY += 10;
|
||||
|
||||
spriteId = CreateMonPicSprite(currMon->species, currMon->tid, currMon->personality, TRUE, posX, posY, i, TAG_NONE);
|
||||
spriteId = CreateMonPicSprite(currMon->species, currMon->isShiny, currMon->personality, TRUE, posX, posY, i, TAG_NONE);
|
||||
gSprites[spriteId].oam.priority = 1;
|
||||
gTasks[taskId].tMonSpriteId(i) = spriteId;
|
||||
}
|
||||
|
||||
@ -878,7 +878,7 @@ const u8 *ItemId_GetName(u16 itemId)
|
||||
return gItems[SanitizeItemId(itemId)].name;
|
||||
}
|
||||
|
||||
u16 ItemId_GetPrice(u16 itemId)
|
||||
u32 ItemId_GetPrice(u16 itemId)
|
||||
{
|
||||
return gItems[SanitizeItemId(itemId)].price;
|
||||
}
|
||||
|
||||
@ -58,6 +58,7 @@ static u8 GetDirectionToHiddenItem(s16, s16);
|
||||
static void PlayerFaceHiddenItem(u8);
|
||||
static void CheckForHiddenItemsInMapConnection(u8);
|
||||
static void Task_OpenRegisteredPokeblockCase(u8);
|
||||
static void Task_AccessPokemonBoxLink(u8);
|
||||
static void ItemUseOnFieldCB_Bike(u8);
|
||||
static void ItemUseOnFieldCB_Rod(u8);
|
||||
static void ItemUseOnFieldCB_Itemfinder(u8);
|
||||
@ -680,6 +681,18 @@ static void Task_OpenRegisteredPokeblockCase(u8 taskId)
|
||||
}
|
||||
}
|
||||
|
||||
void ItemUseOutOfBattle_PokemonBoxLink(u8 taskId)
|
||||
{
|
||||
sItemUseOnFieldCB = Task_AccessPokemonBoxLink;
|
||||
SetUpItemUseOnFieldCallback(taskId);
|
||||
}
|
||||
|
||||
static void Task_AccessPokemonBoxLink(u8 taskId)
|
||||
{
|
||||
ScriptContext_SetupScript(EventScript_AccessPokemonBoxLink);
|
||||
DestroyTask(taskId);
|
||||
}
|
||||
|
||||
void ItemUseOutOfBattle_CoinCase(u8 taskId)
|
||||
{
|
||||
ConvertIntToDecimalStringN(gStringVar1, GetCoins(), STR_CONV_MODE_LEFT_ALIGN, 4);
|
||||
@ -797,6 +810,12 @@ void ItemUseOutOfBattle_AbilityPatch(u8 taskId)
|
||||
SetUpItemUseCallback(taskId);
|
||||
}
|
||||
|
||||
void ItemUseOutOfBattle_Mint(u8 taskId)
|
||||
{
|
||||
gItemUseCB = ItemUseCB_Mint;
|
||||
SetUpItemUseCallback(taskId);
|
||||
}
|
||||
|
||||
void ItemUseOutOfBattle_ResetEVs(u8 taskId)
|
||||
{
|
||||
gItemUseCB = ItemUseCB_ResetEVs;
|
||||
@ -833,6 +852,12 @@ void ItemUseOutOfBattle_RareCandy(u8 taskId)
|
||||
SetUpItemUseCallback(taskId);
|
||||
}
|
||||
|
||||
void ItemUseOutOfBattle_DynamaxCandy(u8 taskId)
|
||||
{
|
||||
gItemUseCB = ItemUseCB_DynamaxCandy;
|
||||
SetUpItemUseCallback(taskId);
|
||||
}
|
||||
|
||||
void ItemUseOutOfBattle_TMHM(u8 taskId)
|
||||
{
|
||||
if (gSpecialVar_ItemId >= ITEM_HM01)
|
||||
|
||||
@ -175,7 +175,17 @@ void LoadPlayerParty(void)
|
||||
gPlayerPartyCount = gSaveBlock1Ptr->playerPartyCount;
|
||||
|
||||
for (i = 0; i < PARTY_SIZE; i++)
|
||||
{
|
||||
u32 data;
|
||||
gPlayerParty[i] = gSaveBlock1Ptr->playerParty[i];
|
||||
|
||||
// TODO: Turn this into a save migration once those are available.
|
||||
// At which point we can remove hp and status from Pokemon entirely.
|
||||
data = gPlayerParty[i].maxHP - gPlayerParty[i].hp;
|
||||
SetBoxMonData(&gPlayerParty[i].box, MON_DATA_HP_LOST, &data);
|
||||
data = gPlayerParty[i].status;
|
||||
SetBoxMonData(&gPlayerParty[i].box, MON_DATA_STATUS, &data);
|
||||
}
|
||||
}
|
||||
|
||||
void SaveObjectEvents(void)
|
||||
|
||||
@ -1876,7 +1876,7 @@ static void SpriteCB_MovePlayerDownWhileShrinking(struct Sprite *sprite)
|
||||
|
||||
static u8 NewGameBirchSpeech_CreateLotadSprite(u8 x, u8 y)
|
||||
{
|
||||
return CreateMonPicSprite_Affine(SPECIES_LOTAD, SHINY_ODDS, 0, MON_PIC_AFFINE_FRONT, x, y, 14, TAG_NONE);
|
||||
return CreateMonPicSprite_Affine(SPECIES_LOTAD, FALSE, 0, MON_PIC_AFFINE_FRONT, x, y, 14, TAG_NONE);
|
||||
}
|
||||
|
||||
static void AddBirchSpeechObjects(u8 taskId)
|
||||
|
||||
@ -320,11 +320,7 @@ static void InitGiddyTaleList(void)
|
||||
// Shuffle question list
|
||||
for (i = 0; i < GIDDY_MAX_QUESTIONS; i++)
|
||||
giddy->questionList[i] = i;
|
||||
for (i = 0; i < GIDDY_MAX_QUESTIONS; i++)
|
||||
{
|
||||
var = Random() % (i + 1);
|
||||
SWAP(giddy->questionList[i], giddy->questionList[var], temp);
|
||||
}
|
||||
Shuffle(giddy->questionList, GIDDY_MAX_QUESTIONS, sizeof(giddy->questionList[0]));
|
||||
|
||||
// Count total number of words in above word groups
|
||||
totalWords = 0;
|
||||
@ -1265,27 +1261,12 @@ static void StorytellerRecordNewStat(u32 player, u32 stat)
|
||||
sStorytellerPtr->language[player] = gGameLanguage;
|
||||
}
|
||||
|
||||
static void ScrambleStatList(u8 *arr, s32 count)
|
||||
{
|
||||
s32 i;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
arr[i] = i;
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
u32 a = Random() % count;
|
||||
u32 b = Random() % count;
|
||||
u8 temp;
|
||||
SWAP(arr[a], arr[b], temp);
|
||||
}
|
||||
}
|
||||
|
||||
static bool8 StorytellerInitializeRandomStat(void)
|
||||
{
|
||||
u8 storyIds[sNumStories];
|
||||
s32 i, j;
|
||||
|
||||
ScrambleStatList(storyIds, sNumStories);
|
||||
Shuffle(storyIds, sNumStories, sizeof(storyIds[0]));
|
||||
for (i = 0; i < sNumStories; i++)
|
||||
{
|
||||
u8 stat = sStorytellerStories[storyIds[i]].stat;
|
||||
@ -1427,4 +1408,3 @@ bool8 Script_StorytellerInitializeRandomStat(void)
|
||||
sStorytellerPtr = &gSaveBlock1Ptr->oldMan.storyteller;
|
||||
return StorytellerInitializeRandomStat();
|
||||
}
|
||||
|
||||
|
||||
@ -1075,11 +1075,11 @@ void GetConditionMenuMonGfx(void *tilesDst, void *palDst, u16 boxId, u16 monId,
|
||||
if (partyId != numMons)
|
||||
{
|
||||
u16 species = GetBoxOrPartyMonData(boxId, monId, MON_DATA_SPECIES_OR_EGG, NULL);
|
||||
u32 trainerId = GetBoxOrPartyMonData(boxId, monId, MON_DATA_OT_ID, NULL);
|
||||
bool8 isShiny = GetBoxOrPartyMonData(boxId, monId, MON_DATA_IS_SHINY, NULL);
|
||||
u32 personality = GetBoxOrPartyMonData(boxId, monId, MON_DATA_PERSONALITY, NULL);
|
||||
|
||||
LoadSpecialPokePic(tilesDst, species, personality, TRUE);
|
||||
LZ77UnCompWram(GetMonSpritePalFromSpeciesAndPersonality(species, trainerId, personality), palDst);
|
||||
LZ77UnCompWram(GetMonSpritePalFromSpeciesAndPersonality(species, isShiny, personality), palDst);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -598,13 +598,9 @@ static void DoMirageTowerDisintegration(u8 taskId)
|
||||
sFallingTower[index].disintegrateRand[i] = i;
|
||||
|
||||
// Randomize disintegration pattern
|
||||
for (i = 0; i <= (INNER_BUFFER_LENGTH - 1); i++)
|
||||
{
|
||||
u16 rand1, rand2, temp;
|
||||
rand1 = Random() % INNER_BUFFER_LENGTH;
|
||||
rand2 = Random() % INNER_BUFFER_LENGTH;
|
||||
SWAP(sFallingTower[index].disintegrateRand[rand2], sFallingTower[index].disintegrateRand[rand1], temp);
|
||||
}
|
||||
Shuffle(sFallingTower[index].disintegrateRand, INNER_BUFFER_LENGTH,
|
||||
sizeof(sFallingTower[index].disintegrateRand[0]));
|
||||
|
||||
if (gTasks[taskId].data[3] <= (OUTER_BUFFER_LENGTH - 1))
|
||||
gTasks[taskId].data[3]++;
|
||||
gTasks[taskId].data[1] = 0;
|
||||
@ -702,13 +698,8 @@ static void Task_FossilFallAndSink(u8 taskId)
|
||||
break;
|
||||
case 6:
|
||||
// Randomize disintegration pattern
|
||||
for (i = 0; i < FOSSIL_DISINTEGRATE_LENGTH * sizeof(u16); i++)
|
||||
{
|
||||
u16 rand1, rand2, temp;
|
||||
rand1 = Random() % FOSSIL_DISINTEGRATE_LENGTH;
|
||||
rand2 = Random() % FOSSIL_DISINTEGRATE_LENGTH;
|
||||
SWAP(sFallingFossil->disintegrateRand[rand2], sFallingFossil->disintegrateRand[rand1], temp);
|
||||
}
|
||||
Shuffle(sFallingFossil->disintegrateRand, FOSSIL_DISINTEGRATE_LENGTH,
|
||||
sizeof(sFallingFossil->disintegrateRand[0]));
|
||||
gSprites[sFallingFossil->spriteId].callback = SpriteCB_FallingFossil;
|
||||
break;
|
||||
case 7:
|
||||
|
||||
166
src/party_menu.c
166
src/party_menu.c
@ -4691,7 +4691,7 @@ void Task_AbilityCapsule(u8 taskId)
|
||||
}
|
||||
gPartyMenuUseExitCallback = TRUE;
|
||||
GetMonNickname(&gPlayerParty[tMonId], gStringVar1);
|
||||
StringCopy(gStringVar2, gAbilityNames[GetAbilityBySpecies(tSpecies, tAbilityNum)]);
|
||||
StringCopy(gStringVar2, gAbilities[GetAbilityBySpecies(tSpecies, tAbilityNum)].name);
|
||||
StringExpandPlaceholders(gStringVar4, askText);
|
||||
PlaySE(SE_SELECT);
|
||||
DisplayPartyMenuMessage(gStringVar4, 1);
|
||||
@ -4778,7 +4778,7 @@ void Task_AbilityPatch(u8 taskId)
|
||||
}
|
||||
gPartyMenuUseExitCallback = TRUE;
|
||||
GetMonNickname(&gPlayerParty[tMonId], gStringVar1);
|
||||
StringCopy(gStringVar2, gAbilityNames[GetAbilityBySpecies(tSpecies, tAbilityNum)]);
|
||||
StringCopy(gStringVar2, gAbilities[GetAbilityBySpecies(tSpecies, tAbilityNum)].name);
|
||||
StringExpandPlaceholders(gStringVar4, askText);
|
||||
PlaySE(SE_SELECT);
|
||||
DisplayPartyMenuMessage(gStringVar4, 1);
|
||||
@ -4851,6 +4851,104 @@ void ItemUseCB_AbilityPatch(u8 taskId, TaskFunc task)
|
||||
#undef tMonId
|
||||
#undef tOldFunc
|
||||
|
||||
#define tState data[0]
|
||||
#define tMonId data[1]
|
||||
#define tOldNature data[2]
|
||||
#define tNewNature data[3]
|
||||
#define tOldFunc 4
|
||||
|
||||
void Task_Mint(u8 taskId)
|
||||
{
|
||||
static const u8 askText[] = _("It might affect {STR_VAR_1}'s stats.\nAre you sure you want to use it?");
|
||||
static const u8 doneText[] = _("{STR_VAR_1}'s stats may have changed due\nto the effects of the {STR_VAR_2}!{PAUSE_UNTIL_PRESS}");
|
||||
s16 *data = gTasks[taskId].data;
|
||||
|
||||
switch (tState)
|
||||
{
|
||||
case 0:
|
||||
// Can't use.
|
||||
if (tOldNature == tNewNature)
|
||||
{
|
||||
gPartyMenuUseExitCallback = FALSE;
|
||||
PlaySE(SE_SELECT);
|
||||
DisplayPartyMenuMessage(gText_WontHaveEffect, 1);
|
||||
ScheduleBgCopyTilemapToVram(2);
|
||||
gTasks[taskId].func = Task_ClosePartyMenuAfterText;
|
||||
return;
|
||||
}
|
||||
gPartyMenuUseExitCallback = TRUE;
|
||||
GetMonNickname(&gPlayerParty[tMonId], gStringVar1);
|
||||
CopyItemName(gSpecialVar_ItemId, gStringVar2);
|
||||
StringExpandPlaceholders(gStringVar4, askText);
|
||||
PlaySE(SE_SELECT);
|
||||
DisplayPartyMenuMessage(gStringVar4, 1);
|
||||
ScheduleBgCopyTilemapToVram(2);
|
||||
tState++;
|
||||
break;
|
||||
case 1:
|
||||
if (!IsPartyMenuTextPrinterActive())
|
||||
{
|
||||
PartyMenuDisplayYesNoMenu();
|
||||
tState++;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
switch (Menu_ProcessInputNoWrapClearOnChoose())
|
||||
{
|
||||
case 0:
|
||||
tState++;
|
||||
break;
|
||||
case 1:
|
||||
case MENU_B_PRESSED:
|
||||
gPartyMenuUseExitCallback = FALSE;
|
||||
PlaySE(SE_SELECT);
|
||||
ScheduleBgCopyTilemapToVram(2);
|
||||
// Don't exit party selections screen, return to choosing a mon.
|
||||
ClearStdWindowAndFrameToTransparent(6, 0);
|
||||
ClearWindowTilemap(6);
|
||||
DisplayPartyMenuStdMessage(5);
|
||||
gTasks[taskId].func = (void *)GetWordTaskArg(taskId, tOldFunc);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
PlaySE(SE_USE_ITEM);
|
||||
StringExpandPlaceholders(gStringVar4, doneText);
|
||||
DisplayPartyMenuMessage(gStringVar4, 1);
|
||||
ScheduleBgCopyTilemapToVram(2);
|
||||
tState++;
|
||||
break;
|
||||
case 4:
|
||||
if (!IsPartyMenuTextPrinterActive())
|
||||
tState++;
|
||||
break;
|
||||
case 5:
|
||||
SetMonData(&gPlayerParty[tMonId], MON_DATA_HIDDEN_NATURE, &tNewNature);
|
||||
CalculateMonStats(&gPlayerParty[tMonId]);
|
||||
RemoveBagItem(gSpecialVar_ItemId, 1);
|
||||
gTasks[taskId].func = Task_ClosePartyMenu;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ItemUseCB_Mint(u8 taskId, TaskFunc task)
|
||||
{
|
||||
s16 *data = gTasks[taskId].data;
|
||||
|
||||
tState = 0;
|
||||
tMonId = gPartyMenu.slotId;
|
||||
tOldNature = GetMonData(&gPlayerParty[tMonId], MON_DATA_HIDDEN_NATURE);
|
||||
tNewNature = ItemId_GetSecondaryId(gSpecialVar_ItemId);
|
||||
SetWordTaskArg(taskId, tOldFunc, (uintptr_t)(gTasks[taskId].func));
|
||||
gTasks[taskId].func = Task_Mint;
|
||||
}
|
||||
|
||||
#undef tState
|
||||
#undef tMonId
|
||||
#undef tOldNature
|
||||
#undef tNewNature
|
||||
#undef tOldFunc
|
||||
|
||||
static void Task_DisplayHPRestoredMessage(u8 taskId)
|
||||
{
|
||||
GetMonNickname(&gPlayerParty[gPartyMenu.slotId], gStringVar1);
|
||||
@ -5672,6 +5770,70 @@ static void BufferMonStatsToTaskData(struct Pokemon *mon, s16 *data)
|
||||
data[3] = GetMonData(mon, MON_DATA_SPEED);
|
||||
}
|
||||
|
||||
#define tState data[0]
|
||||
#define tMonId data[1]
|
||||
#define tDynamaxLevel data[2]
|
||||
#define tOldFunc 4
|
||||
|
||||
void Task_DynamaxCandy(u8 taskId)
|
||||
{
|
||||
static const u8 doneText[] = _("{STR_VAR_1}'s Dynamax Level\nincreased by 1!{PAUSE_UNTIL_PRESS}");
|
||||
s16 *data = gTasks[taskId].data;
|
||||
|
||||
switch (tState)
|
||||
{
|
||||
case 0:
|
||||
// Can't use.
|
||||
if (tDynamaxLevel == MAX_DYNAMAX_LEVEL)
|
||||
{
|
||||
gPartyMenuUseExitCallback = FALSE;
|
||||
PlaySE(SE_SELECT);
|
||||
DisplayPartyMenuMessage(gText_WontHaveEffect, 1);
|
||||
ScheduleBgCopyTilemapToVram(2);
|
||||
gTasks[taskId].func = Task_ClosePartyMenuAfterText;
|
||||
return;
|
||||
}
|
||||
gPartyMenuUseExitCallback = TRUE;
|
||||
GetMonNickname(&gPlayerParty[tMonId], gStringVar1);
|
||||
CopyItemName(gSpecialVar_ItemId, gStringVar2);
|
||||
tState++;
|
||||
break;
|
||||
case 1:
|
||||
PlaySE(SE_USE_ITEM);
|
||||
StringExpandPlaceholders(gStringVar4, doneText);
|
||||
DisplayPartyMenuMessage(gStringVar4, 1);
|
||||
ScheduleBgCopyTilemapToVram(2);
|
||||
tState++;
|
||||
break;
|
||||
case 2:
|
||||
if (!IsPartyMenuTextPrinterActive())
|
||||
tState++;
|
||||
break;
|
||||
case 3:
|
||||
tDynamaxLevel++;
|
||||
SetMonData(&gPlayerParty[tMonId], MON_DATA_DYNAMAX_LEVEL, &tDynamaxLevel);
|
||||
RemoveBagItem(gSpecialVar_ItemId, 1);
|
||||
gTasks[taskId].func = Task_ClosePartyMenu;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ItemUseCB_DynamaxCandy(u8 taskId, TaskFunc task)
|
||||
{
|
||||
s16 *data = gTasks[taskId].data;
|
||||
|
||||
tState = 0;
|
||||
tMonId = gPartyMenu.slotId;
|
||||
tDynamaxLevel = GetMonData(&gPlayerParty[tMonId], MON_DATA_DYNAMAX_LEVEL);
|
||||
SetWordTaskArg(taskId, tOldFunc, (uintptr_t)(gTasks[taskId].func));
|
||||
gTasks[taskId].func = Task_DynamaxCandy;
|
||||
}
|
||||
|
||||
#undef tState
|
||||
#undef tMonId
|
||||
#undef tDynamaxLevel
|
||||
#undef tOldFunc
|
||||
|
||||
#define tUsedOnSlot data[0]
|
||||
#define tHadEffect data[1]
|
||||
#define tLastSlotUsed data[2]
|
||||
|
||||
@ -718,7 +718,8 @@ static void HandleInitBackgrounds(void)
|
||||
static bool8 LoadMonAndSceneGfx(struct Pokemon *mon)
|
||||
{
|
||||
u16 species;
|
||||
u32 personality, trainerId;
|
||||
u32 personality;
|
||||
bool32 isShiny;
|
||||
|
||||
switch (sPokeblockFeed->loadGfxState)
|
||||
{
|
||||
@ -733,8 +734,8 @@ static bool8 LoadMonAndSceneGfx(struct Pokemon *mon)
|
||||
// Load mon palette
|
||||
species = GetMonData(mon, MON_DATA_SPECIES_OR_EGG);
|
||||
personality = GetMonData(mon, MON_DATA_PERSONALITY);
|
||||
trainerId = GetMonData(mon, MON_DATA_OT_ID);
|
||||
LoadCompressedSpritePaletteWithTag(GetMonSpritePalFromSpeciesAndPersonality(species, trainerId, personality), species);
|
||||
isShiny = GetMonData(mon, MON_DATA_IS_SHINY);
|
||||
LoadCompressedSpritePaletteWithTag(GetMonSpritePalFromSpeciesAndPersonality(species, isShiny, personality), species);
|
||||
SetMultiuseSpriteTemplateToPokemon(species, B_POSITION_OPPONENT_LEFT);
|
||||
sPokeblockFeed->loadGfxState++;
|
||||
break;
|
||||
|
||||
@ -3971,12 +3971,11 @@ static void HighlightSubmenuScreenSelectBarItem(u8 a, u16 b)
|
||||
#define tSpecies data[1]
|
||||
#define tPalTimer data[2]
|
||||
#define tMonSpriteId data[3]
|
||||
#define tOtIdLo data[12]
|
||||
#define tOtIdHi data[13]
|
||||
#define tIsShiny data[13]
|
||||
#define tPersonalityLo data[14]
|
||||
#define tPersonalityHi data[15]
|
||||
|
||||
u8 DisplayCaughtMonDexPage(u16 species, u32 otId, u32 personality)
|
||||
u8 DisplayCaughtMonDexPage(u16 species, bool32 isShiny, u32 personality)
|
||||
{
|
||||
u8 taskId = 0;
|
||||
if (POKEDEX_PLUS_HGSS)
|
||||
@ -3986,8 +3985,7 @@ u8 DisplayCaughtMonDexPage(u16 species, u32 otId, u32 personality)
|
||||
|
||||
gTasks[taskId].tState = 0;
|
||||
gTasks[taskId].tSpecies = species;
|
||||
gTasks[taskId].tOtIdLo = otId;
|
||||
gTasks[taskId].tOtIdHi = otId >> 16;
|
||||
gTasks[taskId].tIsShiny = isShiny;
|
||||
gTasks[taskId].tPersonalityLo = personality;
|
||||
gTasks[taskId].tPersonalityHi = personality >> 16;
|
||||
return taskId;
|
||||
@ -4039,7 +4037,7 @@ static void Task_DisplayCaughtMonDexPage(u8 taskId)
|
||||
gTasks[taskId].tState++;
|
||||
break;
|
||||
case 4:
|
||||
spriteId = CreateMonPicSprite(NationalPokedexNumToSpecies(dexNum), 0, ((u16)gTasks[taskId].tPersonalityHi << 16) | (u16)gTasks[taskId].tPersonalityLo, TRUE, MON_PAGE_X, MON_PAGE_Y, 0, TAG_NONE);
|
||||
spriteId = CreateMonPicSprite(NationalPokedexNumToSpecies(dexNum), FALSE, ((u16)gTasks[taskId].tPersonalityHi << 16) | (u16)gTasks[taskId].tPersonalityLo, TRUE, MON_PAGE_X, MON_PAGE_Y, 0, TAG_NONE);
|
||||
gSprites[spriteId].oam.priority = 0;
|
||||
BeginNormalPaletteFade(PALETTES_ALL, 0, 0x10, 0, RGB_BLACK);
|
||||
SetVBlankCallback(gPokedexVBlankCB);
|
||||
@ -4089,7 +4087,7 @@ static void Task_ExitCaughtMonPage(u8 taskId)
|
||||
{
|
||||
if (!gPaletteFade.active)
|
||||
{
|
||||
u32 otId;
|
||||
bool32 isShiny;
|
||||
u32 personality;
|
||||
u8 paletteNum;
|
||||
const u32 *lzPaletteData;
|
||||
@ -4104,10 +4102,10 @@ static void Task_ExitCaughtMonPage(u8 taskId)
|
||||
if (buffer)
|
||||
Free(buffer);
|
||||
|
||||
otId = ((u16)gTasks[taskId].tOtIdHi << 16) | (u16)gTasks[taskId].tOtIdLo;
|
||||
isShiny = (bool8)gTasks[taskId].tIsShiny;
|
||||
personality = ((u16)gTasks[taskId].tPersonalityHi << 16) | (u16)gTasks[taskId].tPersonalityLo;
|
||||
paletteNum = gSprites[gTasks[taskId].tMonSpriteId].oam.paletteNum;
|
||||
lzPaletteData = GetMonSpritePalFromSpeciesAndPersonality(gTasks[taskId].tSpecies, otId, personality);
|
||||
lzPaletteData = GetMonSpritePalFromSpeciesAndPersonality(gTasks[taskId].tSpecies, isShiny, personality);
|
||||
LoadCompressedPalette(lzPaletteData, OBJ_PLTT_ID(paletteNum), PLTT_SIZE_4BPP);
|
||||
DestroyTask(taskId);
|
||||
}
|
||||
@ -4654,7 +4652,7 @@ static u32 GetPokedexMonPersonality(u16 species)
|
||||
u16 CreateMonSpriteFromNationalDexNumber(u16 nationalNum, s16 x, s16 y, u16 paletteSlot)
|
||||
{
|
||||
nationalNum = NationalPokedexNumToSpecies(nationalNum);
|
||||
return CreateMonPicSprite(nationalNum, SHINY_ODDS, GetPokedexMonPersonality(nationalNum), TRUE, x, y, paletteSlot, TAG_NONE);
|
||||
return CreateMonPicSprite(nationalNum, FALSE, GetPokedexMonPersonality(nationalNum), TRUE, x, y, paletteSlot, TAG_NONE);
|
||||
}
|
||||
|
||||
static u16 GetPokemonScaleFromNationalDexNumber(u16 nationalNum)
|
||||
|
||||
@ -4738,7 +4738,7 @@ static u32 GetPokedexMonPersonality(u16 species)
|
||||
static u16 CreateMonSpriteFromNationalDexNumberHGSS(u16 nationalNum, s16 x, s16 y, u16 paletteSlot)
|
||||
{
|
||||
nationalNum = NationalPokedexNumToSpeciesHGSS(nationalNum);
|
||||
return CreateMonPicSprite(nationalNum, SHINY_ODDS, GetPokedexMonPersonality(nationalNum), TRUE, x, y, paletteSlot, TAG_NONE);
|
||||
return CreateMonPicSprite(nationalNum, FALSE, GetPokedexMonPersonality(nationalNum), TRUE, x, y, paletteSlot, TAG_NONE);
|
||||
}
|
||||
|
||||
static u16 GetPokemonScaleFromNationalDexNumber(u16 nationalNum)
|
||||
@ -6043,21 +6043,21 @@ static void PrintStatsScreen_Abilities(u8 taskId)
|
||||
if (gTasks[taskId].data[5] == 0)
|
||||
{
|
||||
ability0 = sPokedexView->sPokemonStats.ability0;
|
||||
PrintStatsScreenTextSmallWhite(WIN_STATS_ABILITIES, gAbilityNames[ability0], abilities_x, abilities_y);
|
||||
PrintStatsScreenTextSmall(WIN_STATS_ABILITIES, gAbilityDescriptionPointers[ability0], abilities_x, abilities_y + 14);
|
||||
PrintStatsScreenTextSmallWhite(WIN_STATS_ABILITIES, gAbilities[ability0].name, abilities_x, abilities_y);
|
||||
PrintStatsScreenTextSmall(WIN_STATS_ABILITIES, gAbilities[ability0].description, abilities_x, abilities_y + 14);
|
||||
|
||||
ability1 = sPokedexView->sPokemonStats.ability1;
|
||||
if (ability1 != ABILITY_NONE && ability1 != ability0)
|
||||
{
|
||||
PrintStatsScreenTextSmallWhite(WIN_STATS_ABILITIES, gAbilityNames[ability1], abilities_x, abilities_y + 30);
|
||||
PrintStatsScreenTextSmall(WIN_STATS_ABILITIES, gAbilityDescriptionPointers[ability1], abilities_x, abilities_y + 44);
|
||||
PrintStatsScreenTextSmallWhite(WIN_STATS_ABILITIES, gAbilities[ability1].name, abilities_x, abilities_y + 30);
|
||||
PrintStatsScreenTextSmall(WIN_STATS_ABILITIES, gAbilities[ability1].description, abilities_x, abilities_y + 44);
|
||||
}
|
||||
}
|
||||
else //Hidden abilities
|
||||
{
|
||||
abilityHidden = sPokedexView->sPokemonStats.abilityHidden;
|
||||
PrintStatsScreenTextSmallWhite(WIN_STATS_ABILITIES, gAbilityNames[abilityHidden], abilities_x, abilities_y);
|
||||
PrintStatsScreenTextSmall(WIN_STATS_ABILITIES, gAbilityDescriptionPointers[abilityHidden], abilities_x, abilities_y + 14);
|
||||
PrintStatsScreenTextSmallWhite(WIN_STATS_ABILITIES, gAbilities[abilityHidden].name, abilities_x, abilities_y);
|
||||
PrintStatsScreenTextSmall(WIN_STATS_ABILITIES, gAbilities[abilityHidden].description, abilities_x, abilities_y + 14);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
524
src/pokemon.c
524
src/pokemon.c
@ -87,6 +87,7 @@ EWRAM_DATA static struct MonSpritesGfxManager *sMonSpritesGfxManagers[MON_SPR_GF
|
||||
EWRAM_DATA static u8 sTriedEvolving = 0;
|
||||
|
||||
#include "data/battle_moves.h"
|
||||
#include "data/abilities.h"
|
||||
|
||||
// Used in an unreferenced function in RS.
|
||||
// Unreferenced here and in FRLG.
|
||||
@ -673,6 +674,63 @@ static const struct SpriteTemplate sSpriteTemplate_64x64 =
|
||||
.callback = SpriteCallbackDummy,
|
||||
};
|
||||
|
||||
// NOTE: Reordering this array will break compatibility with existing
|
||||
// saves.
|
||||
static const u32 sCompressedStatuses[] =
|
||||
{
|
||||
STATUS1_NONE,
|
||||
STATUS1_SLEEP_TURN(1),
|
||||
STATUS1_SLEEP_TURN(2),
|
||||
STATUS1_SLEEP_TURN(3),
|
||||
STATUS1_SLEEP_TURN(4),
|
||||
STATUS1_SLEEP_TURN(5),
|
||||
STATUS1_POISON,
|
||||
STATUS1_BURN,
|
||||
STATUS1_FREEZE,
|
||||
STATUS1_PARALYSIS,
|
||||
STATUS1_TOXIC_POISON,
|
||||
STATUS1_FROSTBITE,
|
||||
};
|
||||
|
||||
// Attempt to detect situations where the BoxPokemon struct is unable to
|
||||
// contain all the values.
|
||||
// TODO: Is it possible to compute:
|
||||
// - The maximum experience.
|
||||
// - The maximum PP.
|
||||
// - The maximum HP.
|
||||
// - The maximum form countdown.
|
||||
STATIC_ASSERT(NUM_SPECIES < (1 << 11), PokemonSubstruct0_species_TooSmall);
|
||||
STATIC_ASSERT(NUMBER_OF_MON_TYPES + 1 <= (1 << 5), PokemonSubstruct0_teraType_TooSmall);
|
||||
STATIC_ASSERT(ITEMS_COUNT < (1 << 10), PokemonSubstruct0_heldItem_TooSmall);
|
||||
STATIC_ASSERT(MAX_LEVEL <= 100, PokemonSubstruct0_experience_PotentiallTooSmall); // Maximum of ~2 million exp.
|
||||
STATIC_ASSERT(LAST_BALL < (1 << 6), PokemonSubstruct0_pokeball_TooSmall);
|
||||
STATIC_ASSERT(MOVES_COUNT_ALL < (1 << 11), PokemonSubstruct1_moves_TooSmall);
|
||||
STATIC_ASSERT(ARRAY_COUNT(sCompressedStatuses) <= (1 << 4), PokemonSubstruct3_compressedStatus_TooSmall);
|
||||
STATIC_ASSERT(MAX_LEVEL < (1 << 7), PokemonSubstruct3_metLevel_TooSmall);
|
||||
STATIC_ASSERT(NUM_VERSIONS < (1 << 4), PokemonSubstruct3_metGame_TooSmall);
|
||||
STATIC_ASSERT(MAX_DYNAMAX_LEVEL < (1 << 4), PokemonSubstruct3_dynamaxLevel_TooSmall);
|
||||
STATIC_ASSERT(MAX_PER_STAT_IVS < (1 << 5), PokemonSubstruct3_ivs_TooSmall);
|
||||
STATIC_ASSERT(NUM_NATURES <= (1 << 5), BoxPokemon_hiddenNatureModifier_TooSmall);
|
||||
|
||||
static u32 CompressStatus(u32 status)
|
||||
{
|
||||
s32 i;
|
||||
for (i = 0; i < ARRAY_COUNT(sCompressedStatuses); i++)
|
||||
{
|
||||
if (sCompressedStatuses[i] == status)
|
||||
return i;
|
||||
}
|
||||
return 0; // STATUS1_NONE
|
||||
}
|
||||
|
||||
static u32 UncompressStatus(u32 compressedStatus)
|
||||
{
|
||||
if (compressedStatus < ARRAY_COUNT(sCompressedStatuses))
|
||||
return sCompressedStatuses[compressedStatus];
|
||||
else
|
||||
return STATUS1_NONE;
|
||||
}
|
||||
|
||||
void ZeroBoxMonData(struct BoxPokemon *boxMon)
|
||||
{
|
||||
u8 *raw = (u8 *)boxMon;
|
||||
@ -733,6 +791,7 @@ void CreateBoxMon(struct BoxPokemon *boxMon, u16 species, u8 level, u8 fixedIV,
|
||||
u8 i;
|
||||
u8 availableIVs[NUM_STATS];
|
||||
u8 selectedIvs[LEGENDARY_PERFECT_IV_COUNT];
|
||||
bool32 isShiny;
|
||||
|
||||
ZeroBoxMonData(boxMon);
|
||||
|
||||
@ -744,17 +803,13 @@ void CreateBoxMon(struct BoxPokemon *boxMon, u16 species, u8 level, u8 fixedIV,
|
||||
// Determine original trainer ID
|
||||
if (otIdType == OT_ID_RANDOM_NO_SHINY)
|
||||
{
|
||||
u32 shinyValue;
|
||||
do
|
||||
{
|
||||
// Choose random OT IDs until one that results in a non-shiny Pokémon
|
||||
value = Random32();
|
||||
shinyValue = GET_SHINY_VALUE(value, personality);
|
||||
} while (shinyValue < SHINY_ODDS);
|
||||
value = Random32();
|
||||
isShiny = FALSE;
|
||||
}
|
||||
else if (otIdType == OT_ID_PRESET)
|
||||
{
|
||||
value = fixedOtId;
|
||||
isShiny = GET_SHINY_VALUE(value, personality) < SHINY_ODDS;
|
||||
}
|
||||
else // Player is the OT
|
||||
{
|
||||
@ -763,26 +818,15 @@ void CreateBoxMon(struct BoxPokemon *boxMon, u16 species, u8 level, u8 fixedIV,
|
||||
| (gSaveBlock2Ptr->playerTrainerId[2] << 16)
|
||||
| (gSaveBlock2Ptr->playerTrainerId[3] << 24);
|
||||
|
||||
#if P_FLAG_FORCE_NO_SHINY != 0
|
||||
if (FlagGet(P_FLAG_FORCE_NO_SHINY))
|
||||
if (P_FLAG_FORCE_NO_SHINY != 0 && FlagGet(P_FLAG_FORCE_NO_SHINY))
|
||||
{
|
||||
while (GET_SHINY_VALUE(value, personality) < SHINY_ODDS)
|
||||
personality = Random32();
|
||||
isShiny = FALSE;
|
||||
}
|
||||
#endif
|
||||
#if P_FLAG_FORCE_SHINY != 0
|
||||
#if P_FLAG_FORCE_NO_SHINY != 0
|
||||
else
|
||||
#endif
|
||||
if (FlagGet(P_FLAG_FORCE_SHINY))
|
||||
else if (P_FLAG_FORCE_SHINY != 0 && FlagGet(P_FLAG_FORCE_SHINY))
|
||||
{
|
||||
while (GET_SHINY_VALUE(value, personality) >= SHINY_ODDS)
|
||||
personality = Random32();
|
||||
isShiny = TRUE;
|
||||
}
|
||||
#endif
|
||||
#if P_FLAG_FORCE_SHINY != 0 || P_FLAG_FORCE_NO_SHINY != 0
|
||||
else
|
||||
#endif
|
||||
{
|
||||
u32 totalRerolls = 0;
|
||||
if (CheckBagHasItem(ITEM_SHINY_CHARM, 1))
|
||||
@ -795,6 +839,8 @@ void CreateBoxMon(struct BoxPokemon *boxMon, u16 species, u8 level, u8 fixedIV,
|
||||
personality = Random32();
|
||||
totalRerolls--;
|
||||
}
|
||||
|
||||
isShiny = GET_SHINY_VALUE(value, personality) < SHINY_ODDS;
|
||||
}
|
||||
}
|
||||
|
||||
@ -804,6 +850,7 @@ void CreateBoxMon(struct BoxPokemon *boxMon, u16 species, u8 level, u8 fixedIV,
|
||||
checksum = CalculateBoxMonChecksum(boxMon);
|
||||
SetBoxMonData(boxMon, MON_DATA_CHECKSUM, &checksum);
|
||||
EncryptBoxMon(boxMon);
|
||||
SetBoxMonData(boxMon, MON_DATA_IS_SHINY, &isShiny);
|
||||
StringCopy(speciesName, GetSpeciesName(species));
|
||||
SetBoxMonData(boxMon, MON_DATA_NICKNAME, speciesName);
|
||||
SetBoxMonData(boxMon, MON_DATA_LANGUAGE, &gGameLanguage);
|
||||
@ -1382,7 +1429,6 @@ static u16 CalculateBoxMonChecksum(struct BoxPokemon *boxMon)
|
||||
{ \
|
||||
u8 baseStat = gSpeciesInfo[species].base; \
|
||||
s32 n = (((2 * baseStat + iv + ev / 4) * level) / 100) + 5; \
|
||||
u8 nature = GetNature(mon); \
|
||||
n = ModifyStatByNature(nature, n, statIndex); \
|
||||
if (B_FRIENDSHIP_BOOST == TRUE) \
|
||||
n = n + ((n * 10 * friendship) / (MAX_FRIENDSHIP * 100));\
|
||||
@ -1393,23 +1439,25 @@ void CalculateMonStats(struct Pokemon *mon)
|
||||
{
|
||||
s32 oldMaxHP = GetMonData(mon, MON_DATA_MAX_HP, NULL);
|
||||
s32 currentHP = GetMonData(mon, MON_DATA_HP, NULL);
|
||||
s32 hpIV = GetMonData(mon, MON_DATA_HP_IV, NULL);
|
||||
s32 hpIV = GetMonData(mon, MON_DATA_HYPER_TRAINED_HP) ? MAX_PER_STAT_IVS : GetMonData(mon, MON_DATA_HP_IV, NULL);
|
||||
s32 hpEV = GetMonData(mon, MON_DATA_HP_EV, NULL);
|
||||
s32 attackIV = GetMonData(mon, MON_DATA_ATK_IV, NULL);
|
||||
s32 attackIV = GetMonData(mon, MON_DATA_HYPER_TRAINED_ATK) ? MAX_PER_STAT_IVS : GetMonData(mon, MON_DATA_ATK_IV, NULL);
|
||||
s32 attackEV = GetMonData(mon, MON_DATA_ATK_EV, NULL);
|
||||
s32 defenseIV = GetMonData(mon, MON_DATA_DEF_IV, NULL);
|
||||
s32 defenseIV = GetMonData(mon, MON_DATA_HYPER_TRAINED_DEF) ? MAX_PER_STAT_IVS : GetMonData(mon, MON_DATA_DEF_IV, NULL);
|
||||
s32 defenseEV = GetMonData(mon, MON_DATA_DEF_EV, NULL);
|
||||
s32 speedIV = GetMonData(mon, MON_DATA_SPEED_IV, NULL);
|
||||
s32 speedIV = GetMonData(mon, MON_DATA_HYPER_TRAINED_SPEED) ? MAX_PER_STAT_IVS : GetMonData(mon, MON_DATA_SPEED_IV, NULL);
|
||||
s32 speedEV = GetMonData(mon, MON_DATA_SPEED_EV, NULL);
|
||||
s32 spAttackIV = GetMonData(mon, MON_DATA_SPATK_IV, NULL);
|
||||
s32 spAttackIV = GetMonData(mon, MON_DATA_HYPER_TRAINED_SPATK) ? MAX_PER_STAT_IVS : GetMonData(mon, MON_DATA_SPATK_IV, NULL);
|
||||
s32 spAttackEV = GetMonData(mon, MON_DATA_SPATK_EV, NULL);
|
||||
s32 spDefenseIV = GetMonData(mon, MON_DATA_SPDEF_IV, NULL);
|
||||
s32 spDefenseIV = GetMonData(mon, MON_DATA_HYPER_TRAINED_SPDEF) ? MAX_PER_STAT_IVS : GetMonData(mon, MON_DATA_SPDEF_IV, NULL);
|
||||
s32 spDefenseEV = GetMonData(mon, MON_DATA_SPDEF_EV, NULL);
|
||||
u16 species = GetMonData(mon, MON_DATA_SPECIES, NULL);
|
||||
u8 friendship = GetMonData(mon, MON_DATA_FRIENDSHIP, NULL);
|
||||
s32 level = GetLevelFromMonExp(mon);
|
||||
s32 newMaxHP;
|
||||
|
||||
u8 nature = GetMonData(mon, MON_DATA_HIDDEN_NATURE, NULL);
|
||||
|
||||
SetMonData(mon, MON_DATA_LEVEL, &level);
|
||||
|
||||
if (species == SPECIES_SHEDINJA)
|
||||
@ -1465,12 +1513,15 @@ void BoxMonToMon(const struct BoxPokemon *src, struct Pokemon *dest)
|
||||
{
|
||||
u32 value = 0;
|
||||
dest->box = *src;
|
||||
SetMonData(dest, MON_DATA_STATUS, &value);
|
||||
SetMonData(dest, MON_DATA_HP, &value);
|
||||
SetMonData(dest, MON_DATA_MAX_HP, &value);
|
||||
dest->status = GetBoxMonData(&dest->box, MON_DATA_STATUS, NULL);
|
||||
dest->hp = 0;
|
||||
dest->maxHP = 0;
|
||||
value = MAIL_NONE;
|
||||
SetMonData(dest, MON_DATA_MAIL, &value);
|
||||
value = GetBoxMonData(&dest->box, MON_DATA_HP_LOST);
|
||||
CalculateMonStats(dest);
|
||||
value = GetMonData(dest, MON_DATA_MAX_HP) - value;
|
||||
SetMonData(dest, MON_DATA_HP, &value);
|
||||
}
|
||||
|
||||
u8 GetLevelFromMonExp(struct Pokemon *mon)
|
||||
@ -2044,6 +2095,76 @@ u32 GetBoxMonData3(struct BoxPokemon *boxMon, s32 field, u8 *data)
|
||||
|
||||
switch (field)
|
||||
{
|
||||
case MON_DATA_NICKNAME:
|
||||
{
|
||||
if (boxMon->isBadEgg)
|
||||
{
|
||||
for (retVal = 0;
|
||||
retVal < POKEMON_NAME_LENGTH && gText_BadEgg[retVal] != EOS;
|
||||
data[retVal] = gText_BadEgg[retVal], retVal++) {}
|
||||
|
||||
data[retVal] = EOS;
|
||||
}
|
||||
else if (boxMon->isEgg)
|
||||
{
|
||||
StringCopy(data, gText_EggNickname);
|
||||
retVal = StringLength(data);
|
||||
}
|
||||
else if (boxMon->language == LANGUAGE_JAPANESE)
|
||||
{
|
||||
data[0] = EXT_CTRL_CODE_BEGIN;
|
||||
data[1] = EXT_CTRL_CODE_JPN;
|
||||
|
||||
for (retVal = 2, i = 0;
|
||||
i < 5 && boxMon->nickname[i] != EOS;
|
||||
data[retVal] = boxMon->nickname[i], retVal++, i++) {}
|
||||
|
||||
data[retVal++] = EXT_CTRL_CODE_BEGIN;
|
||||
data[retVal++] = EXT_CTRL_CODE_ENG;
|
||||
data[retVal] = EOS;
|
||||
}
|
||||
else
|
||||
{
|
||||
retVal = 0;
|
||||
while (retVal < min(sizeof(boxMon->nickname), POKEMON_NAME_LENGTH))
|
||||
{
|
||||
data[retVal] = boxMon->nickname[retVal];
|
||||
retVal++;
|
||||
}
|
||||
|
||||
// Vanilla Pokémon have 0s in nickname11 and nickname12
|
||||
// so if both are 0 we assume that this is a vanilla
|
||||
// Pokémon and replace them with EOS. This means that
|
||||
// two CHAR_SPACE at the end of a nickname are trimmed.
|
||||
if (POKEMON_NAME_LENGTH >= 12)
|
||||
{
|
||||
if (substruct0->nickname11 == 0 && substruct0->nickname12 == 0)
|
||||
{
|
||||
data[retVal++] = EOS;
|
||||
data[retVal++] = EOS;
|
||||
}
|
||||
else
|
||||
{
|
||||
data[retVal++] = substruct0->nickname11;
|
||||
data[retVal++] = substruct0->nickname12;
|
||||
}
|
||||
}
|
||||
else if (POKEMON_NAME_LENGTH >= 11)
|
||||
{
|
||||
if (substruct0->nickname11 == 0)
|
||||
{
|
||||
data[retVal++] = EOS;
|
||||
}
|
||||
else
|
||||
{
|
||||
data[retVal++] = substruct0->nickname11;
|
||||
}
|
||||
}
|
||||
|
||||
data[retVal] = EOS;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MON_DATA_SPECIES:
|
||||
retVal = boxMon->isBadEgg ? SPECIES_EGG : substruct0->species;
|
||||
break;
|
||||
@ -2060,16 +2181,28 @@ u32 GetBoxMonData3(struct BoxPokemon *boxMon, s32 field, u8 *data)
|
||||
retVal = substruct0->friendship;
|
||||
break;
|
||||
case MON_DATA_MOVE1:
|
||||
retVal = substruct1->move1;
|
||||
break;
|
||||
case MON_DATA_MOVE2:
|
||||
retVal = substruct1->move2;
|
||||
break;
|
||||
case MON_DATA_MOVE3:
|
||||
retVal = substruct1->move3;
|
||||
break;
|
||||
case MON_DATA_MOVE4:
|
||||
retVal = substruct1->moves[field - MON_DATA_MOVE1];
|
||||
retVal = substruct1->move4;
|
||||
break;
|
||||
case MON_DATA_PP1:
|
||||
retVal = substruct1->pp1;
|
||||
break;
|
||||
case MON_DATA_PP2:
|
||||
retVal = substruct1->pp2;
|
||||
break;
|
||||
case MON_DATA_PP3:
|
||||
retVal = substruct1->pp3;
|
||||
break;
|
||||
case MON_DATA_PP4:
|
||||
retVal = substruct1->pp[field - MON_DATA_PP1];
|
||||
retVal = substruct1->pp4;
|
||||
break;
|
||||
case MON_DATA_HP_EV:
|
||||
retVal = substruct2->hpEV;
|
||||
@ -2200,9 +2333,6 @@ u32 GetBoxMonData3(struct BoxPokemon *boxMon, s32 field, u8 *data)
|
||||
case MON_DATA_WORLD_RIBBON:
|
||||
retVal = substruct3->worldRibbon;
|
||||
break;
|
||||
case MON_DATA_UNUSED_RIBBONS:
|
||||
retVal = substruct3->unusedRibbons;
|
||||
break;
|
||||
case MON_DATA_MODERN_FATEFUL_ENCOUNTER:
|
||||
retVal = substruct3->modernFatefulEncounter;
|
||||
break;
|
||||
@ -2228,10 +2358,10 @@ u32 GetBoxMonData3(struct BoxPokemon *boxMon, s32 field, u8 *data)
|
||||
while (moves[i] != MOVES_COUNT)
|
||||
{
|
||||
u16 move = moves[i];
|
||||
if (substruct1->moves[0] == move
|
||||
|| substruct1->moves[1] == move
|
||||
|| substruct1->moves[2] == move
|
||||
|| substruct1->moves[3] == move)
|
||||
if (substruct1->move1 == move
|
||||
|| substruct1->move2 == move
|
||||
|| substruct1->move3 == move
|
||||
|| substruct1->move4 == move)
|
||||
retVal |= gBitTable[i];
|
||||
i++;
|
||||
}
|
||||
@ -2283,6 +2413,46 @@ u32 GetBoxMonData3(struct BoxPokemon *boxMon, s32 field, u8 *data)
|
||||
| (substruct3->worldRibbon << 26);
|
||||
}
|
||||
break;
|
||||
case MON_DATA_HYPER_TRAINED_HP:
|
||||
retVal = substruct1->hyperTrainedHP;
|
||||
break;
|
||||
case MON_DATA_HYPER_TRAINED_ATK:
|
||||
retVal = substruct1->hyperTrainedAttack;
|
||||
break;
|
||||
case MON_DATA_HYPER_TRAINED_DEF:
|
||||
retVal = substruct1->hyperTrainedDefense;
|
||||
break;
|
||||
case MON_DATA_HYPER_TRAINED_SPEED:
|
||||
retVal = substruct1->hyperTrainedSpeed;
|
||||
break;
|
||||
case MON_DATA_HYPER_TRAINED_SPATK:
|
||||
retVal = substruct1->hyperTrainedSpAttack;
|
||||
break;
|
||||
case MON_DATA_HYPER_TRAINED_SPDEF:
|
||||
retVal = substruct1->hyperTrainedSpDefense;
|
||||
break;
|
||||
case MON_DATA_IS_SHADOW:
|
||||
retVal = substruct3->isShadow;
|
||||
break;
|
||||
case MON_DATA_DYNAMAX_LEVEL:
|
||||
retVal = substruct3->dynamaxLevel;
|
||||
break;
|
||||
case MON_DATA_GIGANTAMAX_FACTOR:
|
||||
retVal = substruct3->gigantamaxFactor;
|
||||
break;
|
||||
case MON_DATA_TERA_TYPE:
|
||||
{
|
||||
if (substruct0->teraType == 0)
|
||||
{
|
||||
const u8 *types = gSpeciesInfo[substruct0->species].types;
|
||||
retVal = (boxMon->personality & 0x1) == 0 ? types[0] : types[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
retVal = substruct0->teraType - 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -2291,50 +2461,18 @@ u32 GetBoxMonData3(struct BoxPokemon *boxMon, s32 field, u8 *data)
|
||||
{
|
||||
switch (field)
|
||||
{
|
||||
case MON_DATA_STATUS:
|
||||
retVal = UncompressStatus(boxMon->compressedStatus);
|
||||
break;
|
||||
case MON_DATA_HP_LOST:
|
||||
retVal = boxMon->hpLost;
|
||||
break;
|
||||
case MON_DATA_PERSONALITY:
|
||||
retVal = boxMon->personality;
|
||||
break;
|
||||
case MON_DATA_OT_ID:
|
||||
retVal = boxMon->otId;
|
||||
break;
|
||||
case MON_DATA_NICKNAME:
|
||||
{
|
||||
if (boxMon->isBadEgg)
|
||||
{
|
||||
for (retVal = 0;
|
||||
retVal < POKEMON_NAME_LENGTH && gText_BadEgg[retVal] != EOS;
|
||||
data[retVal] = gText_BadEgg[retVal], retVal++) {}
|
||||
|
||||
data[retVal] = EOS;
|
||||
}
|
||||
else if (boxMon->isEgg)
|
||||
{
|
||||
StringCopy(data, gText_EggNickname);
|
||||
retVal = StringLength(data);
|
||||
}
|
||||
else if (boxMon->language == LANGUAGE_JAPANESE)
|
||||
{
|
||||
data[0] = EXT_CTRL_CODE_BEGIN;
|
||||
data[1] = EXT_CTRL_CODE_JPN;
|
||||
|
||||
for (retVal = 2, i = 0;
|
||||
i < 5 && boxMon->nickname[i] != EOS;
|
||||
data[retVal] = boxMon->nickname[i], retVal++, i++) {}
|
||||
|
||||
data[retVal++] = EXT_CTRL_CODE_BEGIN;
|
||||
data[retVal++] = EXT_CTRL_CODE_ENG;
|
||||
data[retVal] = EOS;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (retVal = 0;
|
||||
retVal < POKEMON_NAME_LENGTH;
|
||||
data[retVal] = boxMon->nickname[retVal], retVal++){}
|
||||
|
||||
data[retVal] = EOS;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MON_DATA_LANGUAGE:
|
||||
retVal = boxMon->language;
|
||||
break;
|
||||
@ -2366,9 +2504,18 @@ u32 GetBoxMonData3(struct BoxPokemon *boxMon, s32 field, u8 *data)
|
||||
case MON_DATA_CHECKSUM:
|
||||
retVal = boxMon->checksum;
|
||||
break;
|
||||
case MON_DATA_ENCRYPT_SEPARATOR:
|
||||
retVal = boxMon->unknown;
|
||||
case MON_DATA_IS_SHINY:
|
||||
{
|
||||
u32 shinyValue = GET_SHINY_VALUE(boxMon->otId, boxMon->personality);
|
||||
retVal = (shinyValue < SHINY_ODDS) ^ boxMon->shinyModifier;
|
||||
break;
|
||||
}
|
||||
case MON_DATA_HIDDEN_NATURE:
|
||||
{
|
||||
u32 nature = GetNatureFromPersonality(boxMon->personality);
|
||||
retVal = nature ^ boxMon->hiddenNatureModifier;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -2397,13 +2544,27 @@ void SetMonData(struct Pokemon *mon, s32 field, const void *dataArg)
|
||||
{
|
||||
case MON_DATA_STATUS:
|
||||
SET32(mon->status);
|
||||
SetBoxMonData(&mon->box, MON_DATA_STATUS, dataArg);
|
||||
break;
|
||||
case MON_DATA_LEVEL:
|
||||
SET8(mon->level);
|
||||
break;
|
||||
case MON_DATA_HP:
|
||||
{
|
||||
u32 hpLost;
|
||||
SET16(mon->hp);
|
||||
hpLost = mon->maxHP - mon->hp;
|
||||
SetBoxMonData(&mon->box, MON_DATA_HP_LOST, &hpLost);
|
||||
break;
|
||||
}
|
||||
case MON_DATA_HP_LOST:
|
||||
{
|
||||
u32 hpLost;
|
||||
SET16(hpLost);
|
||||
mon->hp = mon->maxHP - hpLost;
|
||||
SetBoxMonData(&mon->box, MON_DATA_HP_LOST, &hpLost);
|
||||
break;
|
||||
}
|
||||
case MON_DATA_MAX_HP:
|
||||
SET16(mon->maxHP);
|
||||
break;
|
||||
@ -2462,6 +2623,17 @@ void SetBoxMonData(struct BoxPokemon *boxMon, s32 field, const void *dataArg)
|
||||
|
||||
switch (field)
|
||||
{
|
||||
case MON_DATA_NICKNAME:
|
||||
{
|
||||
s32 i;
|
||||
for (i = 0; i < min(sizeof(boxMon->nickname), POKEMON_NAME_LENGTH); i++)
|
||||
boxMon->nickname[i] = data[i];
|
||||
if (POKEMON_NAME_LENGTH >= 11)
|
||||
substruct0->nickname11 = data[10];
|
||||
if (POKEMON_NAME_LENGTH >= 12)
|
||||
substruct0->nickname12 = data[11];
|
||||
break;
|
||||
}
|
||||
case MON_DATA_SPECIES:
|
||||
{
|
||||
SET16(substruct0->species);
|
||||
@ -2484,16 +2656,28 @@ void SetBoxMonData(struct BoxPokemon *boxMon, s32 field, const void *dataArg)
|
||||
SET8(substruct0->friendship);
|
||||
break;
|
||||
case MON_DATA_MOVE1:
|
||||
SET16(substruct1->move1);
|
||||
break;
|
||||
case MON_DATA_MOVE2:
|
||||
SET16(substruct1->move2);
|
||||
break;
|
||||
case MON_DATA_MOVE3:
|
||||
SET16(substruct1->move3);
|
||||
break;
|
||||
case MON_DATA_MOVE4:
|
||||
SET16(substruct1->moves[field - MON_DATA_MOVE1]);
|
||||
SET16(substruct1->move4);
|
||||
break;
|
||||
case MON_DATA_PP1:
|
||||
SET8(substruct1->pp1);
|
||||
break;
|
||||
case MON_DATA_PP2:
|
||||
SET8(substruct1->pp2);
|
||||
break;
|
||||
case MON_DATA_PP3:
|
||||
SET8(substruct1->pp3);
|
||||
break;
|
||||
case MON_DATA_PP4:
|
||||
SET8(substruct1->pp[field - MON_DATA_PP1]);
|
||||
SET8(substruct1->pp4);
|
||||
break;
|
||||
case MON_DATA_HP_EV:
|
||||
SET8(substruct2->hpEV);
|
||||
@ -2634,9 +2818,6 @@ void SetBoxMonData(struct BoxPokemon *boxMon, s32 field, const void *dataArg)
|
||||
case MON_DATA_WORLD_RIBBON:
|
||||
SET8(substruct3->worldRibbon);
|
||||
break;
|
||||
case MON_DATA_UNUSED_RIBBONS:
|
||||
SET8(substruct3->unusedRibbons);
|
||||
break;
|
||||
case MON_DATA_MODERN_FATEFUL_ENCOUNTER:
|
||||
SET8(substruct3->modernFatefulEncounter);
|
||||
break;
|
||||
@ -2651,6 +2832,40 @@ void SetBoxMonData(struct BoxPokemon *boxMon, s32 field, const void *dataArg)
|
||||
substruct3->spDefenseIV = (ivs >> 25) & MAX_IV_MASK;
|
||||
break;
|
||||
}
|
||||
case MON_DATA_HYPER_TRAINED_HP:
|
||||
SET8(substruct1->hyperTrainedHP);
|
||||
break;
|
||||
case MON_DATA_HYPER_TRAINED_ATK:
|
||||
SET8(substruct1->hyperTrainedAttack);
|
||||
break;
|
||||
case MON_DATA_HYPER_TRAINED_DEF:
|
||||
SET8(substruct1->hyperTrainedDefense);
|
||||
break;
|
||||
case MON_DATA_HYPER_TRAINED_SPEED:
|
||||
SET8(substruct1->hyperTrainedSpeed);
|
||||
break;
|
||||
case MON_DATA_HYPER_TRAINED_SPATK:
|
||||
SET8(substruct1->hyperTrainedSpAttack);
|
||||
break;
|
||||
case MON_DATA_HYPER_TRAINED_SPDEF:
|
||||
SET8(substruct1->hyperTrainedSpDefense);
|
||||
break;
|
||||
case MON_DATA_IS_SHADOW:
|
||||
SET8(substruct3->isShadow);
|
||||
break;
|
||||
case MON_DATA_DYNAMAX_LEVEL:
|
||||
SET8(substruct3->dynamaxLevel);
|
||||
break;
|
||||
case MON_DATA_GIGANTAMAX_FACTOR:
|
||||
SET8(substruct3->gigantamaxFactor);
|
||||
break;
|
||||
case MON_DATA_TERA_TYPE:
|
||||
{
|
||||
u32 teraType;
|
||||
SET8(teraType);
|
||||
substruct0->teraType = 1 + teraType;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -2659,19 +2874,22 @@ void SetBoxMonData(struct BoxPokemon *boxMon, s32 field, const void *dataArg)
|
||||
{
|
||||
switch (field)
|
||||
{
|
||||
case MON_DATA_STATUS:
|
||||
{
|
||||
u32 status;
|
||||
SET32(status);
|
||||
boxMon->compressedStatus = CompressStatus(status);
|
||||
break;
|
||||
}
|
||||
case MON_DATA_HP_LOST:
|
||||
SET16(boxMon->hpLost);
|
||||
break;
|
||||
case MON_DATA_PERSONALITY:
|
||||
SET32(boxMon->personality);
|
||||
break;
|
||||
case MON_DATA_OT_ID:
|
||||
SET32(boxMon->otId);
|
||||
break;
|
||||
case MON_DATA_NICKNAME:
|
||||
{
|
||||
s32 i;
|
||||
for (i = 0; i < POKEMON_NAME_LENGTH; i++)
|
||||
boxMon->nickname[i] = data[i];
|
||||
break;
|
||||
}
|
||||
case MON_DATA_LANGUAGE:
|
||||
SET8(boxMon->language);
|
||||
break;
|
||||
@ -2697,10 +2915,23 @@ void SetBoxMonData(struct BoxPokemon *boxMon, s32 field, const void *dataArg)
|
||||
case MON_DATA_CHECKSUM:
|
||||
SET16(boxMon->checksum);
|
||||
break;
|
||||
case MON_DATA_ENCRYPT_SEPARATOR:
|
||||
SET16(boxMon->unknown);
|
||||
case MON_DATA_IS_SHINY:
|
||||
{
|
||||
u32 shinyValue = GET_SHINY_VALUE(boxMon->otId, boxMon->personality);
|
||||
bool32 isShiny;
|
||||
SET8(isShiny);
|
||||
boxMon->shinyModifier = (shinyValue < SHINY_ODDS) ^ isShiny;
|
||||
break;
|
||||
}
|
||||
case MON_DATA_HIDDEN_NATURE:
|
||||
{
|
||||
u32 nature = GetNatureFromPersonality(boxMon->personality);
|
||||
u32 hiddenNature;
|
||||
SET8(hiddenNature);
|
||||
boxMon->hiddenNatureModifier = nature ^ hiddenNature;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (field > MON_DATA_ENCRYPT_SEPARATOR)
|
||||
@ -3764,6 +3995,18 @@ u8 GetNatureFromPersonality(u32 personality)
|
||||
return personality % NUM_NATURES;
|
||||
}
|
||||
|
||||
static u32 GetGMaxTargetSpecies(u32 species)
|
||||
{
|
||||
const struct FormChange *formChanges = GetSpeciesFormChanges(species);
|
||||
u32 i;
|
||||
for (i = 0; formChanges[i].method != FORM_CHANGE_TERMINATOR; i++)
|
||||
{
|
||||
if (formChanges[i].method == FORM_CHANGE_BATTLE_GIGANTAMAX)
|
||||
return formChanges[i].targetSpecies;
|
||||
}
|
||||
return SPECIES_NONE;
|
||||
}
|
||||
|
||||
u16 GetEvolutionTargetSpecies(struct Pokemon *mon, u8 mode, u16 evolutionItem, struct Pokemon *tradePartner)
|
||||
{
|
||||
int i, j;
|
||||
@ -3776,6 +4019,7 @@ u16 GetEvolutionTargetSpecies(struct Pokemon *mon, u8 mode, u16 evolutionItem, s
|
||||
u8 beauty = GetMonData(mon, MON_DATA_BEAUTY, 0);
|
||||
u16 upperPersonality = personality >> 16;
|
||||
u32 holdEffect, currentMap, partnerSpecies, partnerHeldItem, partnerHoldEffect;
|
||||
bool32 consumeItem = FALSE;
|
||||
const struct Evolution *evolutions = GetSpeciesEvolutions(species);
|
||||
|
||||
if (evolutions == NULL)
|
||||
@ -3848,17 +4092,15 @@ u16 GetEvolutionTargetSpecies(struct Pokemon *mon, u8 mode, u16 evolutionItem, s
|
||||
case EVO_ITEM_HOLD_NIGHT:
|
||||
if (GetTimeOfDay() == TIME_NIGHT && heldItem == evolutions[i].param)
|
||||
{
|
||||
heldItem = ITEM_NONE;
|
||||
SetMonData(mon, MON_DATA_HELD_ITEM, &heldItem);
|
||||
targetSpecies = evolutions[i].targetSpecies;
|
||||
consumeItem = TRUE;
|
||||
}
|
||||
break;
|
||||
case EVO_ITEM_HOLD_DAY:
|
||||
if (GetTimeOfDay() != TIME_NIGHT && heldItem == evolutions[i].param)
|
||||
{
|
||||
heldItem = ITEM_NONE;
|
||||
SetMonData(mon, MON_DATA_HELD_ITEM, &heldItem);
|
||||
targetSpecies = evolutions[i].targetSpecies;
|
||||
consumeItem = TRUE;
|
||||
}
|
||||
break;
|
||||
case EVO_LEVEL_DUSK:
|
||||
@ -4037,9 +4279,8 @@ u16 GetEvolutionTargetSpecies(struct Pokemon *mon, u8 mode, u16 evolutionItem, s
|
||||
case EVO_ITEM_HOLD:
|
||||
if (heldItem == evolutions[i].param)
|
||||
{
|
||||
heldItem = 0;
|
||||
SetMonData(mon, MON_DATA_HELD_ITEM, &heldItem);
|
||||
targetSpecies = evolutions[i].targetSpecies;
|
||||
consumeItem = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -4059,9 +4300,8 @@ u16 GetEvolutionTargetSpecies(struct Pokemon *mon, u8 mode, u16 evolutionItem, s
|
||||
case EVO_TRADE_ITEM:
|
||||
if (evolutions[i].param == heldItem)
|
||||
{
|
||||
heldItem = ITEM_NONE;
|
||||
SetMonData(mon, MON_DATA_HELD_ITEM, &heldItem);
|
||||
targetSpecies = evolutions[i].targetSpecies;
|
||||
consumeItem = TRUE;
|
||||
}
|
||||
break;
|
||||
case EVO_TRADE_SPECIFIC_MON:
|
||||
@ -4150,6 +4390,22 @@ u16 GetEvolutionTargetSpecies(struct Pokemon *mon, u8 mode, u16 evolutionItem, s
|
||||
break;
|
||||
}
|
||||
|
||||
// Pikachu, Meowth, and Eevee cannot evolve if they have the
|
||||
// Gigantamax Factor. We assume that is because their evolutions
|
||||
// do not have a Gigantamax Form.
|
||||
if (GetMonData(mon, MON_DATA_GIGANTAMAX_FACTOR, NULL)
|
||||
&& GetGMaxTargetSpecies(species) != SPECIES_NONE
|
||||
&& GetGMaxTargetSpecies(targetSpecies) == SPECIES_NONE)
|
||||
{
|
||||
return SPECIES_NONE;
|
||||
}
|
||||
|
||||
if (consumeItem)
|
||||
{
|
||||
heldItem = ITEM_NONE;
|
||||
SetMonData(mon, MON_DATA_HELD_ITEM, &heldItem);
|
||||
}
|
||||
|
||||
return targetSpecies;
|
||||
}
|
||||
|
||||
@ -5067,20 +5323,17 @@ static void Task_PlayMapChosenOrBattleBGM(u8 taskId)
|
||||
|
||||
const u32 *GetMonFrontSpritePal(struct Pokemon *mon)
|
||||
{
|
||||
u16 species = GetMonData(mon, MON_DATA_SPECIES_OR_EGG, 0);
|
||||
u32 otId = GetMonData(mon, MON_DATA_OT_ID, 0);
|
||||
u32 personality = GetMonData(mon, MON_DATA_PERSONALITY, 0);
|
||||
return GetMonSpritePalFromSpeciesAndPersonality(species, otId, personality);
|
||||
u16 species = GetMonData(mon, MON_DATA_SPECIES_OR_EGG, NULL);
|
||||
bool32 isShiny = GetMonData(mon, MON_DATA_IS_SHINY, NULL);
|
||||
u32 personality = GetMonData(mon, MON_DATA_PERSONALITY, NULL);
|
||||
return GetMonSpritePalFromSpeciesAndPersonality(species, isShiny, personality);
|
||||
}
|
||||
|
||||
const u32 *GetMonSpritePalFromSpeciesAndPersonality(u16 species, u32 otId, u32 personality)
|
||||
const u32 *GetMonSpritePalFromSpeciesAndPersonality(u16 species, bool32 isShiny, u32 personality)
|
||||
{
|
||||
u32 shinyValue;
|
||||
|
||||
species = SanitizeSpeciesId(species);
|
||||
|
||||
shinyValue = GET_SHINY_VALUE(otId, personality);
|
||||
if (shinyValue < SHINY_ODDS)
|
||||
if (isShiny)
|
||||
{
|
||||
if (gSpeciesInfo[species].shinyPaletteFemale != NULL && IsPersonalityFemale(species, personality))
|
||||
return gSpeciesInfo[species].shinyPaletteFemale;
|
||||
@ -5278,18 +5531,7 @@ void SetWildMonHeldItem(void)
|
||||
|
||||
bool8 IsMonShiny(struct Pokemon *mon)
|
||||
{
|
||||
u32 otId = GetMonData(mon, MON_DATA_OT_ID, 0);
|
||||
u32 personality = GetMonData(mon, MON_DATA_PERSONALITY, 0);
|
||||
return IsShinyOtIdPersonality(otId, personality);
|
||||
}
|
||||
|
||||
bool8 IsShinyOtIdPersonality(u32 otId, u32 personality)
|
||||
{
|
||||
bool8 retVal = FALSE;
|
||||
u32 shinyValue = GET_SHINY_VALUE(otId, personality);
|
||||
if (shinyValue < SHINY_ODDS)
|
||||
retVal = TRUE;
|
||||
return retVal;
|
||||
return GetMonData(mon, MON_DATA_IS_SHINY, NULL);
|
||||
}
|
||||
|
||||
const u8 *GetTrainerPartnerName(void)
|
||||
@ -6072,6 +6314,10 @@ void UpdateMonPersonality(struct BoxPokemon *boxMon, u32 personality)
|
||||
struct PokemonSubstruct3 *old3, *new3;
|
||||
struct BoxPokemon old;
|
||||
|
||||
bool32 isShiny = GetBoxMonData(boxMon, MON_DATA_IS_SHINY, NULL);
|
||||
u32 hiddenNature = GetBoxMonData(boxMon, MON_DATA_HIDDEN_NATURE, NULL);
|
||||
u32 teraType = GetBoxMonData(boxMon, MON_DATA_TERA_TYPE, NULL);
|
||||
|
||||
old = *boxMon;
|
||||
old0 = &(GetSubstruct(&old, old.personality, 0)->type0);
|
||||
old1 = &(GetSubstruct(&old, old.personality, 1)->type1);
|
||||
@ -6091,6 +6337,36 @@ void UpdateMonPersonality(struct BoxPokemon *boxMon, u32 personality)
|
||||
*new3 = *old3;
|
||||
boxMon->checksum = CalculateBoxMonChecksum(boxMon);
|
||||
EncryptBoxMon(boxMon);
|
||||
|
||||
SetBoxMonData(boxMon, MON_DATA_IS_SHINY, &isShiny);
|
||||
SetBoxMonData(boxMon, MON_DATA_HIDDEN_NATURE, &hiddenNature);
|
||||
SetBoxMonData(boxMon, MON_DATA_TERA_TYPE, &teraType);
|
||||
}
|
||||
|
||||
void HealPokemon(struct Pokemon *mon)
|
||||
{
|
||||
u32 data;
|
||||
|
||||
data = GetMonData(mon, MON_DATA_MAX_HP);
|
||||
SetMonData(mon, MON_DATA_HP, &data);
|
||||
|
||||
data = STATUS1_NONE;
|
||||
SetMonData(mon, MON_DATA_STATUS, &data);
|
||||
|
||||
MonRestorePP(mon);
|
||||
}
|
||||
|
||||
void HealBoxPokemon(struct BoxPokemon *boxMon)
|
||||
{
|
||||
u32 data;
|
||||
|
||||
data = 0;
|
||||
SetBoxMonData(boxMon, MON_DATA_HP_LOST, &data);
|
||||
|
||||
data = STATUS1_NONE;
|
||||
SetBoxMonData(boxMon, MON_DATA_STATUS, &data);
|
||||
|
||||
BoxMonRestorePP(boxMon);
|
||||
}
|
||||
|
||||
u16 GetCryIdBySpecies(u16 species)
|
||||
|
||||
@ -157,7 +157,8 @@ enum {
|
||||
|
||||
struct PokemonJump_MonInfo
|
||||
{
|
||||
u16 species;
|
||||
u16 isShiny:1;
|
||||
u16 species:15;
|
||||
u32 otId;
|
||||
u32 personality;
|
||||
};
|
||||
@ -894,6 +895,7 @@ static void InitJumpMonInfo(struct PokemonJump_MonInfo *monInfo, struct Pokemon
|
||||
{
|
||||
monInfo->species = GetMonData(mon, MON_DATA_SPECIES);
|
||||
monInfo->otId = GetMonData(mon, MON_DATA_OT_ID);
|
||||
monInfo->isShiny = GetMonData(mon, MON_DATA_IS_SHINY);
|
||||
monInfo->personality = GetMonData(mon, MON_DATA_PERSONALITY);
|
||||
}
|
||||
|
||||
@ -2970,7 +2972,7 @@ static void CreateJumpMonSprite(struct PokemonJumpGfx *jumpGfx, struct PokemonJu
|
||||
spriteSheet.size = MON_PIC_SIZE;
|
||||
LoadSpriteSheet(&spriteSheet);
|
||||
|
||||
spritePalette.data = GetMonSpritePalFromSpeciesAndPersonality(monInfo->species, monInfo->otId, monInfo->personality);
|
||||
spritePalette.data = GetMonSpritePalFromSpeciesAndPersonality(monInfo->species, monInfo->isShiny, monInfo->personality);
|
||||
spritePalette.tag = multiplayerId;
|
||||
LoadCompressedSpritePalette(&spritePalette);
|
||||
|
||||
@ -4161,7 +4163,8 @@ static void Task_UpdateBonus(u8 taskId)
|
||||
struct MonInfoPacket
|
||||
{
|
||||
u8 id;
|
||||
u16 species;
|
||||
u16 isShiny:1;
|
||||
u16 species:15;
|
||||
u32 personality;
|
||||
u32 otId;
|
||||
};
|
||||
@ -4170,6 +4173,7 @@ static void SendPacket_MonInfo(struct PokemonJump_MonInfo *monInfo)
|
||||
{
|
||||
struct MonInfoPacket packet;
|
||||
packet.id = PACKET_MON_INFO,
|
||||
packet.isShiny = monInfo->isShiny,
|
||||
packet.species = monInfo->species,
|
||||
packet.otId = monInfo->otId,
|
||||
packet.personality = monInfo->personality,
|
||||
@ -4187,6 +4191,7 @@ static bool32 RecvPacket_MonInfo(int multiplayerId, struct PokemonJump_MonInfo *
|
||||
if (packet.id == PACKET_MON_INFO)
|
||||
{
|
||||
monInfo->species = packet.species;
|
||||
monInfo->isShiny = packet.isShiny;
|
||||
monInfo->otId = packet.otId;
|
||||
monInfo->personality = packet.personality;
|
||||
return TRUE;
|
||||
|
||||
@ -6414,15 +6414,13 @@ static void SetMovingMonData(u8 boxId, u8 position)
|
||||
|
||||
static void SetPlacedMonData(u8 boxId, u8 position)
|
||||
{
|
||||
if (OW_PC_HEAL <= GEN_7)
|
||||
HealPokemon(&sStorage->movingMon);
|
||||
|
||||
if (boxId == TOTAL_BOXES_COUNT)
|
||||
{
|
||||
gPlayerParty[position] = sStorage->movingMon;
|
||||
}
|
||||
else
|
||||
{
|
||||
BoxMonRestorePP(&sStorage->movingMon.box);
|
||||
SetBoxMonAt(boxId, position, &sStorage->movingMon.box);
|
||||
}
|
||||
}
|
||||
|
||||
static void PurgeMonOrBoxMon(u8 boxId, u8 position)
|
||||
@ -6964,7 +6962,7 @@ static void SetDisplayMonData(void *pokemon, u8 mode)
|
||||
sStorage->displayMonSpecies = GetBoxMonData(pokemon, MON_DATA_SPECIES_OR_EGG);
|
||||
if (sStorage->displayMonSpecies != SPECIES_NONE)
|
||||
{
|
||||
u32 otId = GetBoxMonData(boxMon, MON_DATA_OT_ID);
|
||||
bool8 isShiny = GetBoxMonData(boxMon, MON_DATA_IS_SHINY);
|
||||
sanityIsBadEgg = GetBoxMonData(boxMon, MON_DATA_SANITY_IS_BAD_EGG);
|
||||
if (sanityIsBadEgg)
|
||||
sStorage->displayMonIsEgg = TRUE;
|
||||
@ -6977,7 +6975,7 @@ static void SetDisplayMonData(void *pokemon, u8 mode)
|
||||
sStorage->displayMonLevel = GetLevelFromBoxMonExp(boxMon);
|
||||
sStorage->displayMonMarkings = GetBoxMonData(boxMon, MON_DATA_MARKINGS);
|
||||
sStorage->displayMonPersonality = GetBoxMonData(boxMon, MON_DATA_PERSONALITY);
|
||||
sStorage->displayMonPalette = GetMonSpritePalFromSpeciesAndPersonality(sStorage->displayMonSpecies, otId, sStorage->displayMonPersonality);
|
||||
sStorage->displayMonPalette = GetMonSpritePalFromSpeciesAndPersonality(sStorage->displayMonSpecies, isShiny, sStorage->displayMonPersonality);
|
||||
gender = GetGenderFromSpeciesAndPersonality(sStorage->displayMonSpecies, sStorage->displayMonPersonality);
|
||||
sStorage->displayMonItemId = GetBoxMonData(boxMon, MON_DATA_HELD_ITEM);
|
||||
}
|
||||
@ -8653,6 +8651,8 @@ static void MultiMove_SetPlacedMonData(void)
|
||||
u8 boxPosition = (IN_BOX_COLUMNS * i) + sMultiMove->minColumn;
|
||||
for (j = sMultiMove->minColumn; j < columnCount; j++)
|
||||
{
|
||||
if (OW_PC_HEAL <= GEN_7)
|
||||
HealBoxPokemon(&sMultiMove->boxMons[monArrayId]);
|
||||
if (GetBoxMonData(&sMultiMove->boxMons[monArrayId], MON_DATA_SANITY_HAS_SPECIES))
|
||||
SetBoxMonAt(boxId, boxPosition, &sMultiMove->boxMons[monArrayId]);
|
||||
boxPosition++;
|
||||
@ -10147,12 +10147,12 @@ static void UnkUtil_DmaRun(struct UnkUtilData *data)
|
||||
void UpdateSpeciesSpritePSS(struct BoxPokemon *boxMon)
|
||||
{
|
||||
u16 species = GetBoxMonData(boxMon, MON_DATA_SPECIES);
|
||||
u32 otId = GetBoxMonData(boxMon, MON_DATA_OT_ID);
|
||||
bool8 isShiny = GetBoxMonData(boxMon, MON_DATA_IS_SHINY);
|
||||
u32 pid = GetBoxMonData(boxMon, MON_DATA_PERSONALITY);
|
||||
|
||||
// Update front sprite
|
||||
sStorage->displayMonSpecies = species;
|
||||
sStorage->displayMonPalette = GetMonSpritePalFromSpeciesAndPersonality(species, otId, pid);
|
||||
sStorage->displayMonPalette = GetMonSpritePalFromSpeciesAndPersonality(species, isShiny, pid);
|
||||
if (!sJustOpenedBag)
|
||||
{
|
||||
LoadDisplayMonGfx(species, pid);
|
||||
|
||||
@ -141,7 +141,9 @@ static EWRAM_DATA struct PokemonSummaryScreenData
|
||||
{
|
||||
u16 species; // 0x0
|
||||
u16 species2; // 0x2
|
||||
u8 isEgg; // 0x4
|
||||
u8 isEgg:1; // 0x4
|
||||
u8 isShiny:1;
|
||||
u8 padding:6;
|
||||
u8 level; // 0x5
|
||||
u8 ribbonCount; // 0x6
|
||||
u8 ailment; // 0x7
|
||||
@ -168,6 +170,7 @@ static EWRAM_DATA struct PokemonSummaryScreenData
|
||||
u8 sanity; // 0x35
|
||||
u8 OTName[17]; // 0x36
|
||||
u32 OTID; // 0x48
|
||||
u8 teraType;
|
||||
} summary;
|
||||
u16 bgTilemapBuffers[PSS_PAGE_COUNT][2][0x400];
|
||||
u8 mode;
|
||||
@ -1541,6 +1544,8 @@ static bool8 ExtractMonDataToSummaryStruct(struct Pokemon *mon)
|
||||
break;
|
||||
default:
|
||||
sum->ribbonCount = GetMonData(mon, MON_DATA_RIBBON_COUNT);
|
||||
sum->teraType = GetMonData(mon, MON_DATA_TERA_TYPE);
|
||||
sum->isShiny = GetMonData(mon, MON_DATA_IS_SHINY);
|
||||
return TRUE;
|
||||
}
|
||||
sMonSummaryScreen->switchCounter++;
|
||||
@ -3188,13 +3193,13 @@ static void PrintMonOTID(void)
|
||||
static void PrintMonAbilityName(void)
|
||||
{
|
||||
u16 ability = GetAbilityBySpecies(sMonSummaryScreen->summary.species, sMonSummaryScreen->summary.abilityNum);
|
||||
PrintTextOnWindow(AddWindowFromTemplateList(sPageInfoTemplate, PSS_DATA_WINDOW_INFO_ABILITY), gAbilityNames[ability], 0, 1, 0, 1);
|
||||
PrintTextOnWindow(AddWindowFromTemplateList(sPageInfoTemplate, PSS_DATA_WINDOW_INFO_ABILITY), gAbilities[ability].name, 0, 1, 0, 1);
|
||||
}
|
||||
|
||||
static void PrintMonAbilityDescription(void)
|
||||
{
|
||||
u16 ability = GetAbilityBySpecies(sMonSummaryScreen->summary.species, sMonSummaryScreen->summary.abilityNum);
|
||||
PrintTextOnWindow(AddWindowFromTemplateList(sPageInfoTemplate, PSS_DATA_WINDOW_INFO_ABILITY), gAbilityDescriptionPointers[ability], 0, 17, 0, 0);
|
||||
PrintTextOnWindow(AddWindowFromTemplateList(sPageInfoTemplate, PSS_DATA_WINDOW_INFO_ABILITY), gAbilities[ability].description, 0, 17, 0, 0);
|
||||
}
|
||||
|
||||
static void BufferMonTrainerMemo(void)
|
||||
@ -3938,6 +3943,10 @@ static void SetMonTypeIcons(void)
|
||||
{
|
||||
SetSpriteInvisibility(SPRITE_ARR_ID_TYPE + 1, TRUE);
|
||||
}
|
||||
if (P_SHOW_TERA_TYPE >= GEN_9)
|
||||
{
|
||||
SetTypeSpritePosAndPal(summary->teraType, 200, 48, SPRITE_ARR_ID_TYPE + 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -4042,7 +4051,7 @@ static u8 LoadMonGfxAndSprite(struct Pokemon *mon, s16 *state)
|
||||
(*state)++;
|
||||
return 0xFF;
|
||||
case 1:
|
||||
LoadCompressedSpritePaletteWithTag(GetMonSpritePalFromSpeciesAndPersonality(summary->species2, summary->OTID, summary->pid), summary->species2);
|
||||
LoadCompressedSpritePaletteWithTag(GetMonSpritePalFromSpeciesAndPersonality(summary->species2, summary->isShiny, summary->pid), summary->species2);
|
||||
SetMultiuseSpriteTemplateToPokemon(summary->species2, B_POSITION_OPPONENT_LEFT);
|
||||
(*state)++;
|
||||
return 0xFF;
|
||||
|
||||
@ -522,7 +522,8 @@ static void GetMonConditionGraphData(s16 listId, u8 loadId)
|
||||
static void ConditionGraphDrawMonPic(s16 listId, u8 loadId)
|
||||
{
|
||||
u16 boxId, monId, species;
|
||||
u32 personality, tid;
|
||||
u32 personality;
|
||||
bool8 isShiny;
|
||||
struct Pokenav_ConditionMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU);
|
||||
struct PokenavMonList *monListPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_MON_LIST);
|
||||
|
||||
@ -532,10 +533,10 @@ static void ConditionGraphDrawMonPic(s16 listId, u8 loadId)
|
||||
boxId = monListPtr->monData[listId].boxId;
|
||||
monId = monListPtr->monData[listId].monId;
|
||||
species = GetBoxOrPartyMonData(boxId, monId, MON_DATA_SPECIES_OR_EGG, NULL);
|
||||
tid = GetBoxOrPartyMonData(boxId, monId, MON_DATA_OT_ID, NULL);
|
||||
isShiny = GetBoxOrPartyMonData(boxId, monId, MON_DATA_IS_SHINY, NULL);
|
||||
personality = GetBoxOrPartyMonData(boxId, monId, MON_DATA_PERSONALITY, NULL);
|
||||
LoadSpecialPokePic(menu->monPicGfx[loadId], species, personality, TRUE);
|
||||
LZ77UnCompWram(GetMonSpritePalFromSpeciesAndPersonality(species, tid, personality), menu->monPal[loadId]);
|
||||
LZ77UnCompWram(GetMonSpritePalFromSpeciesAndPersonality(species, isShiny, personality), menu->monPal[loadId]);
|
||||
}
|
||||
|
||||
u16 GetMonListCount(void)
|
||||
|
||||
@ -401,7 +401,7 @@ static void GetMonNicknameLevelGender(u8 *nick, u8 *level, u8 *gender)
|
||||
StringGet_Nickname(nick);
|
||||
}
|
||||
|
||||
static void GetMonSpeciesPersonalityOtId(u16 *species, u32 *personality, u32 *otId)
|
||||
static void GetMonSpeciesPersonalityShiny(u16 *species, u32 *personality, bool8 *isShiny)
|
||||
{
|
||||
struct Pokenav_RibbonsSummaryList *list = GetSubstructPtr(POKENAV_SUBSTRUCT_RIBBONS_SUMMARY_LIST);
|
||||
struct PokenavMonList *mons = list->monList;
|
||||
@ -413,7 +413,7 @@ static void GetMonSpeciesPersonalityOtId(u16 *species, u32 *personality, u32 *ot
|
||||
struct Pokemon *mon = &gPlayerParty[monInfo->monId];
|
||||
*species = GetMonData(mon, MON_DATA_SPECIES);
|
||||
*personality = GetMonData(mon, MON_DATA_PERSONALITY);
|
||||
*otId = GetMonData(mon, MON_DATA_OT_ID);
|
||||
*isShiny = GetMonData(mon, MON_DATA_IS_SHINY);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -421,7 +421,7 @@ static void GetMonSpeciesPersonalityOtId(u16 *species, u32 *personality, u32 *ot
|
||||
struct BoxPokemon *boxMon = GetBoxedMonPtr(monInfo->boxId, monInfo->monId);
|
||||
*species = GetBoxMonData(boxMon, MON_DATA_SPECIES);
|
||||
*personality = GetBoxMonData(boxMon, MON_DATA_PERSONALITY);
|
||||
*otId = GetBoxMonData(boxMon, MON_DATA_OT_ID);
|
||||
*isShiny = GetBoxMonData(boxMon, MON_DATA_IS_SHINY);
|
||||
}
|
||||
}
|
||||
|
||||
@ -941,9 +941,10 @@ static void PrintRibbonsMonListIndex(struct Pokenav_RibbonsSummaryMenu *menu)
|
||||
static void ResetSpritesAndDrawMonFrontPic(struct Pokenav_RibbonsSummaryMenu *menu)
|
||||
{
|
||||
u16 species;
|
||||
u32 personality, otId;
|
||||
u32 personality;
|
||||
bool8 isShiny;
|
||||
|
||||
GetMonSpeciesPersonalityOtId(&species, &personality, &otId);
|
||||
GetMonSpeciesPersonalityShiny(&species, &personality, &isShiny);
|
||||
ResetAllPicSprites();
|
||||
menu->monSpriteId = DrawRibbonsMonFrontPic(MON_SPRITE_X_ON, MON_SPRITE_Y);
|
||||
PokenavFillPalette(15, 0);
|
||||
@ -960,10 +961,11 @@ static void DestroyRibbonsMonFrontPic(struct Pokenav_RibbonsSummaryMenu *menu)
|
||||
static u16 DrawRibbonsMonFrontPic(s32 x, s32 y)
|
||||
{
|
||||
u16 species, spriteId;
|
||||
u32 personality, otId;
|
||||
u32 personality;
|
||||
bool8 isShiny;
|
||||
|
||||
GetMonSpeciesPersonalityOtId(&species, &personality, &otId);
|
||||
spriteId = CreateMonPicSprite(species, otId, personality, TRUE, MON_SPRITE_X_ON, MON_SPRITE_Y, 15, TAG_NONE);
|
||||
GetMonSpeciesPersonalityShiny(&species, &personality, &isShiny);
|
||||
spriteId = CreateMonPicSprite(species, isShiny, personality, TRUE, MON_SPRITE_X_ON, MON_SPRITE_Y, 15, TAG_NONE);
|
||||
gSprites[spriteId].oam.priority = 0;
|
||||
return spriteId;
|
||||
}
|
||||
|
||||
@ -151,8 +151,8 @@ static const struct GFRomHeader sGFRomHeader = {
|
||||
.externalEventDataOffset = offsetof(struct SaveBlock1, externalEventData),
|
||||
.unk18 = 0x00000000,
|
||||
.speciesInfo = gSpeciesInfo,
|
||||
.abilityNames = gAbilityNames,
|
||||
.abilityDescriptions = gAbilityDescriptionPointers,
|
||||
//.abilityNames = gAbilityNames, //handled in gAbilities
|
||||
//.abilityDescriptions = gAbilityDescriptionPointers, //handled in gAbilities
|
||||
.items = gItems,
|
||||
.moves = gBattleMoves,
|
||||
.ballGfx = gBallSpriteSheets,
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
#include "global.h"
|
||||
#include "constants/abilities.h"
|
||||
#include "constants/expansion.h"
|
||||
#include "constants/moves.h"
|
||||
#include "constants/species.h"
|
||||
|
||||
// Similar to the GF ROM header, this struct allows external programs to
|
||||
// detect details about Expansion.
|
||||
@ -14,6 +17,10 @@ struct RHHRomHeader
|
||||
/*0x07*/ u8 expansionVersionMinor;
|
||||
/*0x08*/ u8 expansionVersionPatch;
|
||||
/*0x09*/ u8 expansionVersionFlags;
|
||||
/*0x0C*/ u32 movesCount;
|
||||
/*0x10*/ u32 numSpecies;
|
||||
/*0x14*/ u32 abilitiesCount;
|
||||
/*0x18*/ const struct Ability *abilities;
|
||||
};
|
||||
|
||||
static const struct RHHRomHeader sRHHRomHeader =
|
||||
@ -23,4 +30,8 @@ static const struct RHHRomHeader sRHHRomHeader =
|
||||
.expansionVersionMinor = EXPANSION_VERSION_MINOR,
|
||||
.expansionVersionPatch = EXPANSION_VERSION_PATCH,
|
||||
.expansionVersionFlags = (EXPANSION_TAGGED_RELEASE << 0),
|
||||
.movesCount = MOVES_COUNT,
|
||||
.numSpecies = NUM_SPECIES,
|
||||
.abilitiesCount = ABILITIES_COUNT,
|
||||
.abilities = gAbilities,
|
||||
};
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
#include "party_menu.h"
|
||||
#include "pokedex.h"
|
||||
#include "pokemon.h"
|
||||
#include "pokemon_storage_system.h"
|
||||
#include "random.h"
|
||||
#include "script.h"
|
||||
#include "sprite.h"
|
||||
@ -27,35 +28,30 @@
|
||||
|
||||
static void CB2_ReturnFromChooseHalfParty(void);
|
||||
static void CB2_ReturnFromChooseBattleFrontierParty(void);
|
||||
static void HealPlayerBoxes(void);
|
||||
|
||||
void HealPlayerParty(void)
|
||||
{
|
||||
u8 i, j;
|
||||
u8 ppBonuses;
|
||||
u8 arg[4];
|
||||
u32 i;
|
||||
for (i = 0; i < gPlayerPartyCount; i++)
|
||||
HealPokemon(&gPlayerParty[i]);
|
||||
if (OW_PC_HEAL >= GEN_8)
|
||||
HealPlayerBoxes();
|
||||
}
|
||||
|
||||
// restore HP.
|
||||
for(i = 0; i < gPlayerPartyCount; i++)
|
||||
static void HealPlayerBoxes(void)
|
||||
{
|
||||
int boxId, boxPosition;
|
||||
struct BoxPokemon *boxMon;
|
||||
|
||||
for (boxId = 0; boxId < TOTAL_BOXES_COUNT; boxId++)
|
||||
{
|
||||
u16 maxHP = GetMonData(&gPlayerParty[i], MON_DATA_MAX_HP);
|
||||
arg[0] = maxHP;
|
||||
arg[1] = maxHP >> 8;
|
||||
SetMonData(&gPlayerParty[i], MON_DATA_HP, arg);
|
||||
ppBonuses = GetMonData(&gPlayerParty[i], MON_DATA_PP_BONUSES);
|
||||
|
||||
// restore PP.
|
||||
for(j = 0; j < MAX_MON_MOVES; j++)
|
||||
for (boxPosition = 0; boxPosition < IN_BOX_COUNT; boxPosition++)
|
||||
{
|
||||
arg[0] = CalculatePPWithBonus(GetMonData(&gPlayerParty[i], MON_DATA_MOVE1 + j), ppBonuses, j);
|
||||
SetMonData(&gPlayerParty[i], MON_DATA_PP1 + j, arg);
|
||||
boxMon = &gPokemonStoragePtr->boxes[boxId][boxPosition];
|
||||
if (GetBoxMonData(boxMon, MON_DATA_SANITY_HAS_SPECIES))
|
||||
HealBoxPokemon(boxMon);
|
||||
}
|
||||
|
||||
// since status is u32, the four 0 assignments here are probably for safety to prevent undefined data from reaching SetMonData.
|
||||
arg[0] = 0;
|
||||
arg[1] = 0;
|
||||
arg[2] = 0;
|
||||
arg[3] = 0;
|
||||
SetMonData(&gPlayerParty[i], MON_DATA_STATUS, arg);
|
||||
}
|
||||
}
|
||||
|
||||
@ -273,3 +269,72 @@ void ReducePlayerPartyToSelectedMons(void)
|
||||
|
||||
CalculatePlayerPartyCount();
|
||||
}
|
||||
|
||||
void CanHyperTrain(struct ScriptContext *ctx)
|
||||
{
|
||||
u32 stat = ScriptReadByte(ctx);
|
||||
u32 partyIndex = VarGet(ScriptReadHalfword(ctx));
|
||||
if (stat < NUM_STATS
|
||||
&& partyIndex < PARTY_SIZE
|
||||
&& !GetMonData(&gPlayerParty[partyIndex], MON_DATA_HYPER_TRAINED_HP + stat)
|
||||
&& GetMonData(&gPlayerParty[partyIndex], MON_DATA_HP_IV + stat) < MAX_PER_STAT_IVS)
|
||||
{
|
||||
gSpecialVar_Result = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
gSpecialVar_Result = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
void HyperTrain(struct ScriptContext *ctx)
|
||||
{
|
||||
u32 stat = ScriptReadByte(ctx);
|
||||
u32 partyIndex = VarGet(ScriptReadHalfword(ctx));
|
||||
if (stat < NUM_STATS && partyIndex < PARTY_SIZE)
|
||||
{
|
||||
bool32 data = TRUE;
|
||||
SetMonData(&gPlayerParty[partyIndex], MON_DATA_HYPER_TRAINED_HP + stat, &data);
|
||||
CalculateMonStats(&gPlayerParty[partyIndex]);
|
||||
}
|
||||
}
|
||||
|
||||
void HasGigantamaxFactor(struct ScriptContext *ctx)
|
||||
{
|
||||
u32 partyIndex = VarGet(ScriptReadHalfword(ctx));
|
||||
if (partyIndex < PARTY_SIZE)
|
||||
gSpecialVar_Result = GetMonData(&gPlayerParty[partyIndex], MON_DATA_GIGANTAMAX_FACTOR);
|
||||
else
|
||||
gSpecialVar_Result = FALSE;
|
||||
}
|
||||
|
||||
static const u16 sGigantaxFactorLockedSpecies[] =
|
||||
{
|
||||
SPECIES_MELMETAL,
|
||||
};
|
||||
|
||||
void ToggleGigantamaxFactor(struct ScriptContext *ctx)
|
||||
{
|
||||
u32 i;
|
||||
u32 partyIndex = VarGet(ScriptReadHalfword(ctx));
|
||||
u32 species;
|
||||
|
||||
gSpecialVar_Result = FALSE;
|
||||
|
||||
if (partyIndex < PARTY_SIZE)
|
||||
{
|
||||
bool32 gigantamaxFactor;
|
||||
|
||||
species = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPECIES);
|
||||
for (i = 0; i < ARRAY_COUNT(sGigantaxFactorLockedSpecies); i++)
|
||||
{
|
||||
if (species == sGigantaxFactorLockedSpecies[i])
|
||||
return;
|
||||
}
|
||||
|
||||
gigantamaxFactor = GetMonData(&gPlayerParty[partyIndex], MON_DATA_GIGANTAMAX_FACTOR);
|
||||
gigantamaxFactor = !gigantamaxFactor;
|
||||
SetMonData(&gPlayerParty[partyIndex], MON_DATA_GIGANTAMAX_FACTOR, &gigantamaxFactor);
|
||||
gSpecialVar_Result = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
@ -630,7 +630,7 @@ static u8 CreatePokemonFrontSprite(u16 species, u8 x, u8 y)
|
||||
{
|
||||
u8 spriteId;
|
||||
|
||||
spriteId = CreateMonPicSprite_Affine(species, SHINY_ODDS, 0, MON_PIC_AFFINE_FRONT, x, y, 14, TAG_NONE);
|
||||
spriteId = CreateMonPicSprite_Affine(species, FALSE, 0, MON_PIC_AFFINE_FRONT, x, y, 14, TAG_NONE);
|
||||
gSprites[spriteId].oam.priority = 0;
|
||||
return spriteId;
|
||||
}
|
||||
|
||||
@ -4842,7 +4842,7 @@ static void CheckPartnersMonForRibbons(void)
|
||||
{
|
||||
u8 i;
|
||||
u8 numRibbons = 0;
|
||||
for (i = 0; i < (MON_DATA_UNUSED_RIBBONS - MON_DATA_CHAMPION_RIBBON); i++)
|
||||
for (i = 0; i < (MON_DATA_WORLD_RIBBON - MON_DATA_CHAMPION_RIBBON + 1); i++)
|
||||
numRibbons += GetMonData(&gEnemyParty[gSelectedTradeMonPositions[TRADE_PARTNER] % PARTY_SIZE], MON_DATA_CHAMPION_RIBBON + i);
|
||||
|
||||
if (numRibbons != 0)
|
||||
|
||||
@ -73,19 +73,19 @@ static bool16 DecompressPic(u16 species, u32 personality, bool8 isFrontPic, u8 *
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void LoadPicPaletteByTagOrSlot(u16 species, u32 otId, u32 personality, u8 paletteSlot, u16 paletteTag, bool8 isTrainer)
|
||||
static void LoadPicPaletteByTagOrSlot(u16 species, bool8 isShiny, u32 personality, u8 paletteSlot, u16 paletteTag, bool8 isTrainer)
|
||||
{
|
||||
if (!isTrainer)
|
||||
{
|
||||
if (paletteTag == TAG_NONE)
|
||||
{
|
||||
sCreatingSpriteTemplate.paletteTag = TAG_NONE;
|
||||
LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(species, otId, personality), OBJ_PLTT_ID(paletteSlot), PLTT_SIZE_4BPP);
|
||||
LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(species, isShiny, personality), OBJ_PLTT_ID(paletteSlot), PLTT_SIZE_4BPP);
|
||||
}
|
||||
else
|
||||
{
|
||||
sCreatingSpriteTemplate.paletteTag = paletteTag;
|
||||
LoadCompressedSpritePaletteWithTag(GetMonSpritePalFromSpeciesAndPersonality(species, otId, personality), species);
|
||||
LoadCompressedSpritePaletteWithTag(GetMonSpritePalFromSpeciesAndPersonality(species, isShiny, personality), species);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -103,10 +103,10 @@ static void LoadPicPaletteByTagOrSlot(u16 species, u32 otId, u32 personality, u8
|
||||
}
|
||||
}
|
||||
|
||||
static void LoadPicPaletteBySlot(u16 species, u32 otId, u32 personality, u8 paletteSlot, bool8 isTrainer)
|
||||
static void LoadPicPaletteBySlot(u16 species, bool8 isShiny, u32 personality, u8 paletteSlot, bool8 isTrainer)
|
||||
{
|
||||
if (!isTrainer)
|
||||
LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(species, otId, personality), PLTT_ID(paletteSlot), PLTT_SIZE_4BPP);
|
||||
LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(species, isShiny, personality), PLTT_ID(paletteSlot), PLTT_SIZE_4BPP);
|
||||
else
|
||||
LoadCompressedPalette(gTrainerSprites[species].palette.data, PLTT_ID(paletteSlot), PLTT_SIZE_4BPP);
|
||||
}
|
||||
@ -119,7 +119,7 @@ static void AssignSpriteAnimsTable(bool8 isTrainer)
|
||||
sCreatingSpriteTemplate.anims = gTrainerSprites[0].animation;
|
||||
}
|
||||
|
||||
static u16 CreatePicSprite(u16 species, u32 otId, u32 personality, bool8 isFrontPic, s16 x, s16 y, u8 paletteSlot, u16 paletteTag, bool8 isTrainer)
|
||||
static u16 CreatePicSprite(u16 species, bool8 isShiny, u32 personality, bool8 isFrontPic, s16 x, s16 y, u8 paletteSlot, u16 paletteTag, bool8 isTrainer)
|
||||
{
|
||||
u8 i;
|
||||
u8 *framePics;
|
||||
@ -161,7 +161,7 @@ static u16 CreatePicSprite(u16 species, u32 otId, u32 personality, bool8 isFront
|
||||
sCreatingSpriteTemplate.images = images;
|
||||
sCreatingSpriteTemplate.affineAnims = gDummySpriteAffineAnimTable;
|
||||
sCreatingSpriteTemplate.callback = DummyPicSpriteCallback;
|
||||
LoadPicPaletteByTagOrSlot(species, otId, personality, paletteSlot, paletteTag, isTrainer);
|
||||
LoadPicPaletteByTagOrSlot(species, isShiny, personality, paletteSlot, paletteTag, isTrainer);
|
||||
spriteId = CreateSprite(&sCreatingSpriteTemplate, x, y, 0);
|
||||
if (paletteTag == TAG_NONE)
|
||||
gSprites[spriteId].oam.paletteNum = paletteSlot;
|
||||
@ -173,7 +173,7 @@ static u16 CreatePicSprite(u16 species, u32 otId, u32 personality, bool8 isFront
|
||||
return spriteId;
|
||||
}
|
||||
|
||||
u16 CreateMonPicSprite_Affine(u16 species, u32 otId, u32 personality, u8 flags, s16 x, s16 y, u8 paletteSlot, u16 paletteTag)
|
||||
u16 CreateMonPicSprite_Affine(u16 species, bool8 isShiny, u32 personality, u8 flags, s16 x, s16 y, u8 paletteSlot, u16 paletteTag)
|
||||
{
|
||||
u8 *framePics;
|
||||
struct SpriteFrameImage *images;
|
||||
@ -239,7 +239,7 @@ u16 CreateMonPicSprite_Affine(u16 species, u32 otId, u32 personality, u8 flags,
|
||||
sCreatingSpriteTemplate.affineAnims = gDummySpriteAffineAnimTable;
|
||||
}
|
||||
sCreatingSpriteTemplate.callback = DummyPicSpriteCallback;
|
||||
LoadPicPaletteByTagOrSlot(species, otId, personality, paletteSlot, paletteTag, FALSE);
|
||||
LoadPicPaletteByTagOrSlot(species, isShiny, personality, paletteSlot, paletteTag, FALSE);
|
||||
spriteId = CreateSprite(&sCreatingSpriteTemplate, x, y, 0);
|
||||
if (paletteTag == TAG_NONE)
|
||||
gSprites[spriteId].oam.paletteNum = paletteSlot;
|
||||
@ -276,16 +276,16 @@ static u16 FreeAndDestroyPicSpriteInternal(u16 spriteId)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u16 LoadPicSpriteInWindow(u16 species, u32 otId, u32 personality, bool8 isFrontPic, u8 paletteSlot, u8 windowId, bool8 isTrainer)
|
||||
static u16 LoadPicSpriteInWindow(u16 species, bool8 isShiny, u32 personality, bool8 isFrontPic, u8 paletteSlot, u8 windowId, bool8 isTrainer)
|
||||
{
|
||||
if (DecompressPic(species, personality, isFrontPic, (u8 *)GetWindowAttribute(windowId, WINDOW_TILE_DATA), FALSE))
|
||||
return 0xFFFF;
|
||||
|
||||
LoadPicPaletteBySlot(species, otId, personality, paletteSlot, isTrainer);
|
||||
LoadPicPaletteBySlot(species, isShiny, personality, paletteSlot, isTrainer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u16 CreateTrainerCardSprite(u16 species, u32 otId, u32 personality, bool8 isFrontPic, u16 destX, u16 destY, u8 paletteSlot, u8 windowId, bool8 isTrainer)
|
||||
static u16 CreateTrainerCardSprite(u16 species, bool8 isShiny, u32 personality, bool8 isFrontPic, u16 destX, u16 destY, u8 paletteSlot, u8 windowId, bool8 isTrainer)
|
||||
{
|
||||
u8 *framePics;
|
||||
|
||||
@ -293,16 +293,16 @@ static u16 CreateTrainerCardSprite(u16 species, u32 otId, u32 personality, bool8
|
||||
if (framePics && !DecompressPic(species, personality, isFrontPic, framePics, isTrainer))
|
||||
{
|
||||
BlitBitmapRectToWindow(windowId, framePics, 0, 0, TRAINER_PIC_WIDTH, TRAINER_PIC_HEIGHT, destX, destY, TRAINER_PIC_WIDTH, TRAINER_PIC_HEIGHT);
|
||||
LoadPicPaletteBySlot(species, otId, personality, paletteSlot, isTrainer);
|
||||
LoadPicPaletteBySlot(species, isShiny, personality, paletteSlot, isTrainer);
|
||||
Free(framePics);
|
||||
return 0;
|
||||
}
|
||||
return 0xFFFF;
|
||||
}
|
||||
|
||||
u16 CreateMonPicSprite(u16 species, u32 otId, u32 personality, bool8 isFrontPic, s16 x, s16 y, u8 paletteSlot, u16 paletteTag)
|
||||
u16 CreateMonPicSprite(u16 species, bool8 isShiny, u32 personality, bool8 isFrontPic, s16 x, s16 y, u8 paletteSlot, u16 paletteTag)
|
||||
{
|
||||
return CreatePicSprite(species, otId, personality, isFrontPic, x, y, paletteSlot, paletteTag, FALSE);
|
||||
return CreatePicSprite(species, isShiny, personality, isFrontPic, x, y, paletteSlot, paletteTag, FALSE);
|
||||
}
|
||||
|
||||
u16 FreeAndDestroyMonPicSprite(u16 spriteId)
|
||||
@ -310,20 +310,20 @@ u16 FreeAndDestroyMonPicSprite(u16 spriteId)
|
||||
return FreeAndDestroyPicSpriteInternal(spriteId);
|
||||
}
|
||||
|
||||
static u16 UNUSED LoadMonPicInWindow(u16 species, u32 otId, u32 personality, bool8 isFrontPic, u8 paletteSlot, u8 windowId)
|
||||
static u16 UNUSED LoadMonPicInWindow(u16 species, bool8 isShiny, u32 personality, bool8 isFrontPic, u8 paletteSlot, u8 windowId)
|
||||
{
|
||||
return LoadPicSpriteInWindow(species, otId, personality, isFrontPic, paletteSlot, windowId, FALSE);
|
||||
return LoadPicSpriteInWindow(species, isShiny, personality, isFrontPic, paletteSlot, windowId, FALSE);
|
||||
}
|
||||
|
||||
// Unused, FRLG only
|
||||
u16 CreateTrainerCardMonIconSprite(u16 species, u32 otId, u32 personality, bool8 isFrontPic, u16 destX, u16 destY, u8 paletteSlot, u8 windowId)
|
||||
u16 CreateTrainerCardMonIconSprite(u16 species, bool8 isShiny, u32 personality, bool8 isFrontPic, u16 destX, u16 destY, u8 paletteSlot, u8 windowId)
|
||||
{
|
||||
return CreateTrainerCardSprite(species, otId, personality, isFrontPic, destX, destY, paletteSlot, windowId, FALSE);
|
||||
return CreateTrainerCardSprite(species, isShiny, personality, isFrontPic, destX, destY, paletteSlot, windowId, FALSE);
|
||||
}
|
||||
|
||||
u16 CreateTrainerPicSprite(u16 species, bool8 isFrontPic, s16 x, s16 y, u8 paletteSlot, u16 paletteTag)
|
||||
{
|
||||
return CreatePicSprite(species, 0, 0, isFrontPic, x, y, paletteSlot, paletteTag, TRUE);
|
||||
return CreatePicSprite(species, FALSE, 0, isFrontPic, x, y, paletteSlot, paletteTag, TRUE);
|
||||
}
|
||||
|
||||
u16 FreeAndDestroyTrainerPicSprite(u16 spriteId)
|
||||
@ -333,12 +333,12 @@ u16 FreeAndDestroyTrainerPicSprite(u16 spriteId)
|
||||
|
||||
static u16 UNUSED LoadTrainerPicInWindow(u16 species, bool8 isFrontPic, u8 paletteSlot, u8 windowId)
|
||||
{
|
||||
return LoadPicSpriteInWindow(species, 0, 0, isFrontPic, paletteSlot, windowId, TRUE);
|
||||
return LoadPicSpriteInWindow(species, FALSE, 0, isFrontPic, paletteSlot, windowId, TRUE);
|
||||
}
|
||||
|
||||
u16 CreateTrainerCardTrainerPicSprite(u16 species, bool8 isFrontPic, u16 destX, u16 destY, u8 paletteSlot, u8 windowId)
|
||||
{
|
||||
return CreateTrainerCardSprite(species, 0, 0, isFrontPic, destX, destY, paletteSlot, windowId, TRUE);
|
||||
return CreateTrainerCardSprite(species, FALSE, 0, isFrontPic, destX, destY, paletteSlot, windowId, TRUE);
|
||||
}
|
||||
|
||||
u16 PlayerGenderToFrontTrainerPicId_Debug(u8 gender, bool8 getClass)
|
||||
|
||||
8
src/tv.c
8
src/tv.c
@ -1956,7 +1956,6 @@ void AlertTVThatPlayerPlayedRoulette(u16 nCoinsSpent)
|
||||
static void SecretBaseVisit_CalculateDecorationData(TVShow *show)
|
||||
{
|
||||
u8 i, j;
|
||||
u16 k;
|
||||
u8 n;
|
||||
u8 decoration;
|
||||
|
||||
@ -2002,12 +2001,7 @@ static void SecretBaseVisit_CalculateDecorationData(TVShow *show)
|
||||
break;
|
||||
default:
|
||||
// More than 1 decoration, randomize the full list
|
||||
for (k = 0; k < n * n; k++)
|
||||
{
|
||||
decoration = Random() % n;
|
||||
j = Random() % n;
|
||||
SWAP(sTV_DecorationsBuffer[decoration], sTV_DecorationsBuffer[j], i);
|
||||
}
|
||||
Shuffle(sTV_DecorationsBuffer, n, sizeof(sTV_DecorationsBuffer[0]));
|
||||
|
||||
// Pick the first decorations in the randomized list to talk about on the show
|
||||
for (i = 0; i < show->secretBaseVisit.numDecorations; i++)
|
||||
|
||||
@ -385,7 +385,6 @@ static u16 GetCurrentMapWildMonHeaderId(void)
|
||||
u8 PickWildMonNature(void)
|
||||
{
|
||||
u8 i;
|
||||
u8 j;
|
||||
struct Pokeblock *safariPokeblock;
|
||||
u8 natures[NUM_NATURES];
|
||||
|
||||
@ -396,17 +395,7 @@ u8 PickWildMonNature(void)
|
||||
{
|
||||
for (i = 0; i < NUM_NATURES; i++)
|
||||
natures[i] = i;
|
||||
for (i = 0; i < NUM_NATURES - 1; i++)
|
||||
{
|
||||
for (j = i + 1; j < NUM_NATURES; j++)
|
||||
{
|
||||
if (Random() & 1)
|
||||
{
|
||||
u8 temp;
|
||||
SWAP(natures[i], natures[j], temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
Shuffle(natures, NUM_NATURES, sizeof(natures[0]));
|
||||
for (i = 0; i < NUM_NATURES; i++)
|
||||
{
|
||||
if (PokeblockGetGain(natures[i], safariPokeblock) > 0)
|
||||
|
||||
@ -187,3 +187,37 @@ SINGLE_BATTLE_TEST("Contrary raises a stat after using a move which would normal
|
||||
EXPECT_MUL_EQ(results[1].damage, Q_4_12(2.125), results[0].damage);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Contrary lowers a stat after using a move which would normally raise it: Belly Drum", s16 damageBefore, s16 damageAfter)
|
||||
{
|
||||
u32 ability;
|
||||
PARAMETRIZE { ability = ABILITY_CONTRARY; }
|
||||
PARAMETRIZE { ability = ABILITY_TANGLED_FEET; }
|
||||
GIVEN {
|
||||
ASSUME(gBattleMoves[MOVE_BELLY_DRUM].effect == EFFECT_BELLY_DRUM);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_SPINDA) { Ability(ability); }
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_TACKLE); }
|
||||
TURN { MOVE(opponent, MOVE_BELLY_DRUM); }
|
||||
TURN { MOVE(opponent, MOVE_TACKLE); }
|
||||
} SCENE {
|
||||
MESSAGE("Foe Spinda used Tackle!");
|
||||
HP_BAR(player, captureDamage: &results[i].damageBefore);
|
||||
|
||||
if (ability == ABILITY_CONTRARY) {
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent);
|
||||
MESSAGE("Foe Spinda cut its own HP and maximized ATTACK!"); //Message stays the same
|
||||
}
|
||||
else {
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent);
|
||||
MESSAGE("Foe Spinda cut its own HP and maximized ATTACK!");
|
||||
}
|
||||
|
||||
HP_BAR(player, captureDamage: &results[i].damageAfter);
|
||||
}
|
||||
FINALLY {
|
||||
EXPECT_MUL_EQ(results[0].damageBefore, UQ_4_12(0.25), results[0].damageAfter);
|
||||
EXPECT_MUL_EQ(results[1].damageBefore, UQ_4_12(4.0), results[1].damageAfter);
|
||||
}
|
||||
}
|
||||
|
||||
@ -177,15 +177,15 @@ AI_SINGLE_BATTLE_TEST("AI chooses moves with secondary effect that have a 100% c
|
||||
AI_LOG;
|
||||
ASSUME(gBattleMoves[MOVE_SHADOW_BALL].effect == EFFECT_SPECIAL_DEFENSE_DOWN_HIT);
|
||||
ASSUME(gBattleMoves[MOVE_SHADOW_BALL].secondaryEffectChance == 20);
|
||||
ASSUME(gBattleMoves[MOVE_LUSTER_PURGE].effect == EFFECT_SPECIAL_DEFENSE_DOWN_HIT);
|
||||
ASSUME(gBattleMoves[MOVE_LUSTER_PURGE].secondaryEffectChance == 50);
|
||||
ASSUME(gBattleMoves[MOVE_OCTAZOOKA].effect == EFFECT_ACCURACY_DOWN_HIT);
|
||||
ASSUME(gBattleMoves[MOVE_OCTAZOOKA].secondaryEffectChance == 50);
|
||||
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
|
||||
PLAYER(SPECIES_REGICE);
|
||||
OPPONENT(SPECIES_REGIROCK) { Ability(ability); Moves(MOVE_SHADOW_BALL, MOVE_LUSTER_PURGE); }
|
||||
OPPONENT(SPECIES_REGIROCK) { Ability(ability); Moves(MOVE_SHADOW_BALL, MOVE_OCTAZOOKA); }
|
||||
} WHEN {
|
||||
if (ability == ABILITY_NONE)
|
||||
TURN { EXPECT_MOVE(opponent, MOVE_SHADOW_BALL); }
|
||||
else
|
||||
TURN { EXPECT_MOVES(opponent, MOVE_LUSTER_PURGE); }
|
||||
TURN { EXPECT_MOVES(opponent, MOVE_OCTAZOOKA); }
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user