diff --git a/include/constants/pokemon.h b/include/constants/pokemon.h index 45204d6062..9b02548cdc 100644 --- a/include/constants/pokemon.h +++ b/include/constants/pokemon.h @@ -300,6 +300,17 @@ enum EvolutionMethods { EVO_ITEM_COUNT_999, // Pokémon levels up after trainer has collected 999 of a specific item EVO_DEFEAT_THREE_WITH_ITEM, // Pokémon levels up after having defeat 3 Pokémon of the same species holding the specified item EVO_OVERWORLD_STEPS, // Pokémon levels up after having taken a specific amount of steps in the overworld + + // Alcremie evolutions methods. Different combinations of day, spin rotation and duration. + EVO_ITEM_HOLD_SPIN_DAY_LESS_THAN_5_SECS_CLOCKWISE, + EVO_ITEM_HOLD_SPIN_DAY_LESS_THAN_5_SECS_COUNTER_CLOCKWISE, + EVO_ITEM_HOLD_SPIN_NIGHT_LESS_THAN_5_SECS_CLOCKWISE, + EVO_ITEM_HOLD_SPIN_NIGHT_LESS_THAN_5_SECS_COUNTER_CLOCKWISE, + EVO_ITEM_HOLD_SPIN_DAY_MORE_THAN_5_SECS_CLOCKWISE, + EVO_ITEM_HOLD_SPIN_DAY_MORE_THAN_5_SECS_COUNTER_CLOCKWISE, + EVO_ITEM_HOLD_SPIN_NIGHT_MORE_THAN_5_SECS_CLOCKWISE, + EVO_ITEM_HOLD_SPIN_NIGHT_MORE_THAN_5_SECS_COUNTER_CLOCKWISE, + EVO_ITEM_HOLD_SPIN_DUSK_MORE_THAN_10_SECS, }; enum EvolutionMode { diff --git a/include/field_player_avatar.h b/include/field_player_avatar.h index 12de71be8f..d05ca5eedb 100644 --- a/include/field_player_avatar.h +++ b/include/field_player_avatar.h @@ -68,5 +68,8 @@ bool8 ObjectMovingOnRockStairs(struct ObjectEvent *objectEvent, u8 direction); //sideways stairs u8 GetRightSideStairsDirection(u8 direction); u8 GetLeftSideStairsDirection(u8 direction); +void UpdateSpinData(void); +void ResetSpinTimer(void); +bool32 CanTriggerSpinEvolution(); #endif // GUARD_FIELD_PLAYER_AVATAR_H diff --git a/include/pokemon.h b/include/pokemon.h index c259266da8..dcaf79eada 100644 --- a/include/pokemon.h +++ b/include/pokemon.h @@ -608,6 +608,9 @@ extern u8 gEnemyPartyCount; extern struct Pokemon gEnemyParty[PARTY_SIZE]; extern struct SpriteTemplate gMultiuseSpriteTemplate; extern u16 gFollowerSteps; +extern bool32 consumeItem; +extern u32 removeBagItem; +extern u32 removeBagItemCount; extern const u8 gFacilityClassToPicIndex[]; extern const u8 gFacilityClassToTrainerClass[]; @@ -790,6 +793,7 @@ u32 GetFormChangeTargetSpeciesBoxMon(struct BoxPokemon *boxMon, u16 method, u32 bool32 DoesSpeciesHaveFormChangeMethod(u16 species, u16 method); u16 MonTryLearningNewMoveEvolution(struct Pokemon *mon, bool8 firstMove); void RemoveIVIndexFromList(u8 *ivs, u8 selectedIv); +void TrySpecialOverworldEvo(void); bool32 SpeciesHasGenderDifferences(u16 species); bool32 TryFormChange(u32 monId, u32 side, u16 method); void TryToSetBattleFormChangeMoves(struct Pokemon *mon, u16 method); @@ -809,5 +813,6 @@ u32 CheckDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler); uq4_12_t GetDynamaxLevelHPMultiplier(u32 dynamaxLevel, bool32 inverseMultiplier); u32 GetRegionalFormByRegion(u32 species, u32 region); bool32 IsSpeciesForeignRegionalForm(u32 species, u32 currentRegion); +void DoRemoveItems(struct Pokemon *mon); #endif // GUARD_POKEMON_H diff --git a/src/data/pokemon/species_info/gen_8_families.h b/src/data/pokemon/species_info/gen_8_families.h index f803864cfc..cebabca2b8 100644 --- a/src/data/pokemon/species_info/gen_8_families.h +++ b/src/data/pokemon/species_info/gen_8_families.h @@ -4813,15 +4813,70 @@ const struct SpeciesInfo gSpeciesInfoGen8[] = .levelUpLearnset = sMilceryLevelUpLearnset, .teachableLearnset = sMilceryTeachableLearnset, .eggMoveLearnset = sMilceryEggMoveLearnset, - .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_ALCREMIE_STRAWBERRY_VANILLA_CREAM}, - {EVO_LEVEL, 0, SPECIES_ALCREMIE_STRAWBERRY_RUBY_CREAM}, - {EVO_LEVEL, 0, SPECIES_ALCREMIE_STRAWBERRY_MATCHA_CREAM}, - {EVO_LEVEL, 0, SPECIES_ALCREMIE_STRAWBERRY_MINT_CREAM}, - {EVO_LEVEL, 0, SPECIES_ALCREMIE_STRAWBERRY_LEMON_CREAM}, - {EVO_LEVEL, 0, SPECIES_ALCREMIE_STRAWBERRY_SALTED_CREAM}, - {EVO_LEVEL, 0, SPECIES_ALCREMIE_STRAWBERRY_RUBY_SWIRL}, - {EVO_LEVEL, 0, SPECIES_ALCREMIE_STRAWBERRY_CARAMEL_SWIRL}, - {EVO_LEVEL, 0, SPECIES_ALCREMIE_STRAWBERRY_RAINBOW_SWIRL}), + .evolutions = EVOLUTION({EVO_ITEM_HOLD_SPIN_DAY_LESS_THAN_5_SECS_CLOCKWISE, ITEM_STRAWBERRY_SWEET, SPECIES_ALCREMIE_STRAWBERRY_VANILLA_CREAM}, + {EVO_ITEM_HOLD_SPIN_DAY_LESS_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_STRAWBERRY_SWEET, SPECIES_ALCREMIE_STRAWBERRY_RUBY_CREAM}, + {EVO_ITEM_HOLD_SPIN_NIGHT_LESS_THAN_5_SECS_CLOCKWISE, ITEM_STRAWBERRY_SWEET, SPECIES_ALCREMIE_STRAWBERRY_MATCHA_CREAM}, + {EVO_ITEM_HOLD_SPIN_NIGHT_LESS_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_STRAWBERRY_SWEET, SPECIES_ALCREMIE_STRAWBERRY_MINT_CREAM}, + {EVO_ITEM_HOLD_SPIN_DAY_MORE_THAN_5_SECS_CLOCKWISE, ITEM_STRAWBERRY_SWEET, SPECIES_ALCREMIE_STRAWBERRY_CARAMEL_SWIRL}, + {EVO_ITEM_HOLD_SPIN_DAY_MORE_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_STRAWBERRY_SWEET, SPECIES_ALCREMIE_STRAWBERRY_RUBY_SWIRL}, + {EVO_ITEM_HOLD_SPIN_NIGHT_MORE_THAN_5_SECS_CLOCKWISE, ITEM_STRAWBERRY_SWEET, SPECIES_ALCREMIE_STRAWBERRY_LEMON_CREAM}, + {EVO_ITEM_HOLD_SPIN_NIGHT_MORE_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_STRAWBERRY_SWEET, SPECIES_ALCREMIE_STRAWBERRY_SALTED_CREAM}, + {EVO_ITEM_HOLD_SPIN_DUSK_MORE_THAN_10_SECS, ITEM_STRAWBERRY_SWEET, SPECIES_ALCREMIE_STRAWBERRY_RAINBOW_SWIRL}, + {EVO_ITEM_HOLD_SPIN_DAY_LESS_THAN_5_SECS_CLOCKWISE, ITEM_BERRY_SWEET, SPECIES_ALCREMIE_BERRY_VANILLA_CREAM}, + {EVO_ITEM_HOLD_SPIN_DAY_LESS_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_BERRY_SWEET, SPECIES_ALCREMIE_BERRY_RUBY_CREAM}, + {EVO_ITEM_HOLD_SPIN_NIGHT_LESS_THAN_5_SECS_CLOCKWISE, ITEM_BERRY_SWEET, SPECIES_ALCREMIE_BERRY_MATCHA_CREAM}, + {EVO_ITEM_HOLD_SPIN_NIGHT_LESS_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_BERRY_SWEET, SPECIES_ALCREMIE_BERRY_MINT_CREAM}, + {EVO_ITEM_HOLD_SPIN_DAY_MORE_THAN_5_SECS_CLOCKWISE, ITEM_BERRY_SWEET, SPECIES_ALCREMIE_BERRY_CARAMEL_SWIRL}, + {EVO_ITEM_HOLD_SPIN_DAY_MORE_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_BERRY_SWEET, SPECIES_ALCREMIE_BERRY_RUBY_SWIRL}, + {EVO_ITEM_HOLD_SPIN_NIGHT_MORE_THAN_5_SECS_CLOCKWISE, ITEM_BERRY_SWEET, SPECIES_ALCREMIE_BERRY_LEMON_CREAM}, + {EVO_ITEM_HOLD_SPIN_NIGHT_MORE_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_BERRY_SWEET, SPECIES_ALCREMIE_BERRY_SALTED_CREAM}, + {EVO_ITEM_HOLD_SPIN_DUSK_MORE_THAN_10_SECS, ITEM_BERRY_SWEET, SPECIES_ALCREMIE_BERRY_RAINBOW_SWIRL}, + {EVO_ITEM_HOLD_SPIN_DAY_LESS_THAN_5_SECS_CLOCKWISE, ITEM_LOVE_SWEET, SPECIES_ALCREMIE_LOVE_VANILLA_CREAM}, + {EVO_ITEM_HOLD_SPIN_DAY_LESS_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_LOVE_SWEET, SPECIES_ALCREMIE_LOVE_RUBY_CREAM}, + {EVO_ITEM_HOLD_SPIN_NIGHT_LESS_THAN_5_SECS_CLOCKWISE, ITEM_LOVE_SWEET, SPECIES_ALCREMIE_LOVE_MATCHA_CREAM}, + {EVO_ITEM_HOLD_SPIN_NIGHT_LESS_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_LOVE_SWEET, SPECIES_ALCREMIE_LOVE_MINT_CREAM}, + {EVO_ITEM_HOLD_SPIN_DAY_MORE_THAN_5_SECS_CLOCKWISE, ITEM_LOVE_SWEET, SPECIES_ALCREMIE_LOVE_CARAMEL_SWIRL}, + {EVO_ITEM_HOLD_SPIN_DAY_MORE_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_LOVE_SWEET, SPECIES_ALCREMIE_LOVE_RUBY_SWIRL}, + {EVO_ITEM_HOLD_SPIN_NIGHT_MORE_THAN_5_SECS_CLOCKWISE, ITEM_LOVE_SWEET, SPECIES_ALCREMIE_LOVE_LEMON_CREAM}, + {EVO_ITEM_HOLD_SPIN_NIGHT_MORE_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_LOVE_SWEET, SPECIES_ALCREMIE_LOVE_SALTED_CREAM}, + {EVO_ITEM_HOLD_SPIN_DUSK_MORE_THAN_10_SECS, ITEM_LOVE_SWEET, SPECIES_ALCREMIE_LOVE_RAINBOW_SWIRL}, + {EVO_ITEM_HOLD_SPIN_DAY_LESS_THAN_5_SECS_CLOCKWISE, ITEM_STAR_SWEET, SPECIES_ALCREMIE_STAR_VANILLA_CREAM}, + {EVO_ITEM_HOLD_SPIN_DAY_LESS_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_STAR_SWEET, SPECIES_ALCREMIE_STAR_RUBY_CREAM}, + {EVO_ITEM_HOLD_SPIN_NIGHT_LESS_THAN_5_SECS_CLOCKWISE, ITEM_STAR_SWEET, SPECIES_ALCREMIE_STAR_MATCHA_CREAM}, + {EVO_ITEM_HOLD_SPIN_NIGHT_LESS_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_STAR_SWEET, SPECIES_ALCREMIE_STAR_MINT_CREAM}, + {EVO_ITEM_HOLD_SPIN_DAY_MORE_THAN_5_SECS_CLOCKWISE, ITEM_STAR_SWEET, SPECIES_ALCREMIE_STAR_CARAMEL_SWIRL}, + {EVO_ITEM_HOLD_SPIN_DAY_MORE_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_STAR_SWEET, SPECIES_ALCREMIE_STAR_RUBY_SWIRL}, + {EVO_ITEM_HOLD_SPIN_NIGHT_MORE_THAN_5_SECS_CLOCKWISE, ITEM_STAR_SWEET, SPECIES_ALCREMIE_STAR_LEMON_CREAM}, + {EVO_ITEM_HOLD_SPIN_NIGHT_MORE_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_STAR_SWEET, SPECIES_ALCREMIE_STAR_SALTED_CREAM}, + {EVO_ITEM_HOLD_SPIN_DUSK_MORE_THAN_10_SECS, ITEM_STAR_SWEET, SPECIES_ALCREMIE_STAR_RAINBOW_SWIRL}, + {EVO_ITEM_HOLD_SPIN_DAY_LESS_THAN_5_SECS_CLOCKWISE, ITEM_CLOVER_SWEET, SPECIES_ALCREMIE_CLOVER_VANILLA_CREAM}, + {EVO_ITEM_HOLD_SPIN_DAY_LESS_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_CLOVER_SWEET, SPECIES_ALCREMIE_CLOVER_RUBY_CREAM}, + {EVO_ITEM_HOLD_SPIN_NIGHT_LESS_THAN_5_SECS_CLOCKWISE, ITEM_CLOVER_SWEET, SPECIES_ALCREMIE_CLOVER_MATCHA_CREAM}, + {EVO_ITEM_HOLD_SPIN_NIGHT_LESS_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_CLOVER_SWEET, SPECIES_ALCREMIE_CLOVER_MINT_CREAM}, + {EVO_ITEM_HOLD_SPIN_DAY_MORE_THAN_5_SECS_CLOCKWISE, ITEM_CLOVER_SWEET, SPECIES_ALCREMIE_CLOVER_CARAMEL_SWIRL}, + {EVO_ITEM_HOLD_SPIN_DAY_MORE_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_CLOVER_SWEET, SPECIES_ALCREMIE_CLOVER_RUBY_SWIRL}, + {EVO_ITEM_HOLD_SPIN_NIGHT_MORE_THAN_5_SECS_CLOCKWISE, ITEM_CLOVER_SWEET, SPECIES_ALCREMIE_CLOVER_LEMON_CREAM}, + {EVO_ITEM_HOLD_SPIN_NIGHT_MORE_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_CLOVER_SWEET, SPECIES_ALCREMIE_CLOVER_SALTED_CREAM}, + {EVO_ITEM_HOLD_SPIN_DUSK_MORE_THAN_10_SECS, ITEM_CLOVER_SWEET, SPECIES_ALCREMIE_CLOVER_RAINBOW_SWIRL}, + {EVO_ITEM_HOLD_SPIN_DAY_LESS_THAN_5_SECS_CLOCKWISE, ITEM_FLOWER_SWEET, SPECIES_ALCREMIE_FLOWER_VANILLA_CREAM}, + {EVO_ITEM_HOLD_SPIN_DAY_LESS_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_FLOWER_SWEET, SPECIES_ALCREMIE_FLOWER_RUBY_CREAM}, + {EVO_ITEM_HOLD_SPIN_NIGHT_LESS_THAN_5_SECS_CLOCKWISE, ITEM_FLOWER_SWEET, SPECIES_ALCREMIE_FLOWER_MATCHA_CREAM}, + {EVO_ITEM_HOLD_SPIN_NIGHT_LESS_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_FLOWER_SWEET, SPECIES_ALCREMIE_FLOWER_MINT_CREAM}, + {EVO_ITEM_HOLD_SPIN_DAY_MORE_THAN_5_SECS_CLOCKWISE, ITEM_FLOWER_SWEET, SPECIES_ALCREMIE_FLOWER_CARAMEL_SWIRL}, + {EVO_ITEM_HOLD_SPIN_DAY_MORE_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_FLOWER_SWEET, SPECIES_ALCREMIE_FLOWER_RUBY_SWIRL}, + {EVO_ITEM_HOLD_SPIN_NIGHT_MORE_THAN_5_SECS_CLOCKWISE, ITEM_FLOWER_SWEET, SPECIES_ALCREMIE_FLOWER_LEMON_CREAM}, + {EVO_ITEM_HOLD_SPIN_NIGHT_MORE_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_FLOWER_SWEET, SPECIES_ALCREMIE_FLOWER_SALTED_CREAM}, + {EVO_ITEM_HOLD_SPIN_DUSK_MORE_THAN_10_SECS, ITEM_FLOWER_SWEET, SPECIES_ALCREMIE_FLOWER_RAINBOW_SWIRL}, + {EVO_ITEM_HOLD_SPIN_DAY_LESS_THAN_5_SECS_CLOCKWISE, ITEM_RIBBON_SWEET, SPECIES_ALCREMIE_RIBBON_VANILLA_CREAM}, + {EVO_ITEM_HOLD_SPIN_DAY_LESS_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_RIBBON_SWEET, SPECIES_ALCREMIE_RIBBON_RUBY_CREAM}, + {EVO_ITEM_HOLD_SPIN_NIGHT_LESS_THAN_5_SECS_CLOCKWISE, ITEM_RIBBON_SWEET, SPECIES_ALCREMIE_RIBBON_MATCHA_CREAM}, + {EVO_ITEM_HOLD_SPIN_NIGHT_LESS_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_RIBBON_SWEET, SPECIES_ALCREMIE_RIBBON_MINT_CREAM}, + {EVO_ITEM_HOLD_SPIN_DAY_MORE_THAN_5_SECS_CLOCKWISE, ITEM_RIBBON_SWEET, SPECIES_ALCREMIE_RIBBON_CARAMEL_SWIRL}, + {EVO_ITEM_HOLD_SPIN_DAY_MORE_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_RIBBON_SWEET, SPECIES_ALCREMIE_RIBBON_RUBY_SWIRL}, + {EVO_ITEM_HOLD_SPIN_NIGHT_MORE_THAN_5_SECS_CLOCKWISE, ITEM_RIBBON_SWEET, SPECIES_ALCREMIE_RIBBON_LEMON_CREAM}, + {EVO_ITEM_HOLD_SPIN_NIGHT_MORE_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_RIBBON_SWEET, SPECIES_ALCREMIE_RIBBON_SALTED_CREAM}, + {EVO_ITEM_HOLD_SPIN_DUSK_MORE_THAN_10_SECS, ITEM_RIBBON_SWEET, SPECIES_ALCREMIE_RIBBON_RAINBOW_SWIRL} + ), }, #define ALCREMIE_MISC_INFO(color) \ diff --git a/src/evolution_scene.c b/src/evolution_scene.c index 20eb136f39..39b407f716 100644 --- a/src/evolution_scene.c +++ b/src/evolution_scene.c @@ -820,7 +820,10 @@ static void Task_EvolutionScene(u8 taskId) Overworld_PlaySpecialMapMusic(); } if (!gTasks[taskId].tEvoWasStopped) + { + DoRemoveItems(mon); CreateShedinja(gTasks[taskId].tPreEvoSpecies, mon); + } DestroyTask(taskId); FreeMonSpritesGfx(); diff --git a/src/field_control_avatar.c b/src/field_control_avatar.c index ecf78be0bb..2c4247fe21 100644 --- a/src/field_control_avatar.c +++ b/src/field_control_avatar.c @@ -243,6 +243,13 @@ int ProcessPlayerFieldInput(struct FieldInput *input) return TRUE; } + if (CanTriggerSpinEvolution()) + { + ResetSpinTimer(); + TrySpecialOverworldEvo(); // Special vars set in CanTriggerSpinEvolution. + return TRUE; + } + return FALSE; } diff --git a/src/field_player_avatar.c b/src/field_player_avatar.c index 674fb7eddb..5d27af481f 100644 --- a/src/field_player_avatar.c +++ b/src/field_player_avatar.c @@ -15,6 +15,7 @@ #include "party_menu.h" #include "random.h" #include "rotating_gate.h" +#include "rtc.h" #include "script.h" #include "sound.h" #include "sprite.h" @@ -34,9 +35,29 @@ #define NUM_FORCED_MOVEMENTS 18 #define NUM_ACRO_BIKE_COLLISIONS 5 +enum SpinDirection +{ + SPIN_DIRECTION_NONE, + SPIN_DIRECTION_CLOCKWISE, + SPIN_DIRECTION_COUNTER_CLOCKWISE, +}; + +struct SpinData +{ + u32 triggerEvo:1; + u32 spinDirection:2; + u32 spinTimeout:6; + u32 spinHistory0:3; + u32 spinHistory1:3; + u32 spinHistory2:3; + u32 spinHistory3:3; + u32 VBlanksSpinning:11; //34,1 seconds +}; + static EWRAM_DATA u8 sSpinStartFacingDir = 0; EWRAM_DATA struct ObjectEvent gObjectEvents[OBJECT_EVENTS_COUNT] = {}; EWRAM_DATA struct PlayerAvatar gPlayerAvatar = {}; +EWRAM_DATA struct SpinData gPlayerSpinData = {}; // static declarations @@ -633,8 +654,146 @@ static void PlayerNotOnBikeNotMoving(u8 direction, u16 heldKeys) PlayerFaceDirection(GetPlayerFacingDirection()); } +void UpdateSpinData(void) +{ + if (gPlayerSpinData.spinTimeout != 0) + { + gPlayerSpinData.spinTimeout--; + if (gPlayerSpinData.VBlanksSpinning < 2048) + gPlayerSpinData.VBlanksSpinning++; + if (gPlayerSpinData.spinTimeout == 0 && gPlayerSpinData.spinDirection != SPIN_DIRECTION_NONE) + gPlayerSpinData.triggerEvo = TRUE; + } +} + +void ResetSpinTimer(void) +{ + gPlayerSpinData.spinTimeout = 0; + gPlayerSpinData.VBlanksSpinning = 0; + gPlayerSpinData.spinDirection = SPIN_DIRECTION_NONE; + gPlayerSpinData.spinHistory0 = DIR_NONE; + gPlayerSpinData.spinHistory1 = DIR_NONE; + gPlayerSpinData.spinHistory2 = DIR_NONE; + gPlayerSpinData.spinHistory3 = DIR_NONE; +} + +static const u8 sClockwiseDirections[4][4] = +{ + { DIR_NORTH, DIR_EAST, DIR_SOUTH, DIR_WEST, }, + { DIR_EAST, DIR_SOUTH, DIR_WEST, DIR_NORTH, }, + { DIR_SOUTH, DIR_WEST, DIR_NORTH, DIR_EAST, }, + { DIR_WEST, DIR_NORTH, DIR_EAST, DIR_SOUTH, }, +}; + +static const u8 sCounterClockwiseDirections[4][4] = +{ + { DIR_NORTH, DIR_WEST, DIR_SOUTH, DIR_EAST, }, + { DIR_WEST, DIR_SOUTH, DIR_EAST, DIR_NORTH, }, + { DIR_SOUTH, DIR_EAST, DIR_NORTH, DIR_WEST, }, + { DIR_EAST, DIR_NORTH, DIR_WEST, DIR_SOUTH, }, +}; + +static void WindUpSpinTimer(u32 direction) +{ + gPlayerSpinData.spinTimeout = 60; + gPlayerSpinData.spinHistory0 = gPlayerSpinData.spinHistory1; + gPlayerSpinData.spinHistory1 = gPlayerSpinData.spinHistory2; + gPlayerSpinData.spinHistory2 = gPlayerSpinData.spinHistory3; + gPlayerSpinData.spinHistory3 = direction; + + for (int i = 0; i < ARRAY_COUNT(sClockwiseDirections); i++) + { + if (gPlayerSpinData.spinHistory0 == sClockwiseDirections[i][0] + && gPlayerSpinData.spinHistory1 == sClockwiseDirections[i][1] + && gPlayerSpinData.spinHistory2 == sClockwiseDirections[i][2] + && gPlayerSpinData.spinHistory3 == sClockwiseDirections[i][3]) + { + gPlayerSpinData.spinDirection = SPIN_DIRECTION_CLOCKWISE; + return; + } + } + for (int i = 0; i < ARRAY_COUNT(sCounterClockwiseDirections); i++) + { + if (gPlayerSpinData.spinHistory0 == sCounterClockwiseDirections[i][0] + && gPlayerSpinData.spinHistory1 == sCounterClockwiseDirections[i][1] + && gPlayerSpinData.spinHistory2 == sCounterClockwiseDirections[i][2] + && gPlayerSpinData.spinHistory3 == sCounterClockwiseDirections[i][3]) + { + gPlayerSpinData.spinDirection = SPIN_DIRECTION_COUNTER_CLOCKWISE; + return; + } + } + gPlayerSpinData.spinDirection = SPIN_DIRECTION_NONE; +} + +bool32 CanTriggerSpinEvolution() +{ + gSpecialVar_0x8000 = EVO_NONE; + if (gPlayerSpinData.triggerEvo) + { + u32 timeOfDay = GetTimeOfDay(); + u32 seconds = gPlayerSpinData.VBlanksSpinning / 60; + u32 direction = gPlayerSpinData.spinDirection; + if (timeOfDay == TIME_EVENING && seconds >= 10) + { + gSpecialVar_0x8000 = EVO_ITEM_HOLD_SPIN_DUSK_MORE_THAN_10_SECS; + } + else if (timeOfDay == TIME_NIGHT) + { + if (seconds >= 5) + { + if (direction == SPIN_DIRECTION_CLOCKWISE) + gSpecialVar_0x8000 = EVO_ITEM_HOLD_SPIN_NIGHT_MORE_THAN_5_SECS_CLOCKWISE; + else if (direction == SPIN_DIRECTION_COUNTER_CLOCKWISE) + gSpecialVar_0x8000 = EVO_ITEM_HOLD_SPIN_NIGHT_MORE_THAN_5_SECS_COUNTER_CLOCKWISE; + } + else + { + if (direction == SPIN_DIRECTION_CLOCKWISE) + gSpecialVar_0x8000 = EVO_ITEM_HOLD_SPIN_NIGHT_LESS_THAN_5_SECS_CLOCKWISE; + else if (direction == SPIN_DIRECTION_COUNTER_CLOCKWISE) + gSpecialVar_0x8000 = EVO_ITEM_HOLD_SPIN_NIGHT_LESS_THAN_5_SECS_COUNTER_CLOCKWISE; + } + } + else if (timeOfDay != TIME_NIGHT) + { + if (seconds >= 5) + { + if (direction == SPIN_DIRECTION_CLOCKWISE) + gSpecialVar_0x8000 = EVO_ITEM_HOLD_SPIN_DAY_MORE_THAN_5_SECS_CLOCKWISE; + else if (direction == SPIN_DIRECTION_COUNTER_CLOCKWISE) + gSpecialVar_0x8000 = EVO_ITEM_HOLD_SPIN_DAY_MORE_THAN_5_SECS_COUNTER_CLOCKWISE; + } + else + { + if (direction == SPIN_DIRECTION_CLOCKWISE) + gSpecialVar_0x8000 = EVO_ITEM_HOLD_SPIN_DAY_LESS_THAN_5_SECS_CLOCKWISE; + else if (direction == SPIN_DIRECTION_COUNTER_CLOCKWISE) + gSpecialVar_0x8000 = EVO_ITEM_HOLD_SPIN_DAY_LESS_THAN_5_SECS_COUNTER_CLOCKWISE; + } + } + gSpecialVar_0x8001 = FALSE; //canStopEvo + gSpecialVar_0x8002 = TRUE; //tryMultiple + gPlayerSpinData.triggerEvo = FALSE; + } + if (gSpecialVar_0x8000 != EVO_NONE) + { + for (u32 i = 0; i < PARTY_SIZE; i++) + { + u16 species = GetEvolutionTargetSpecies(&gPlayerParty[i], EVO_MODE_OVERWORLD_SPECIAL, gSpecialVar_0x8000, NULL); + if (species != SPECIES_NONE) + { + return TRUE; + } + } + } + + return FALSE; +} + static void PlayerNotOnBikeTurningInPlace(u8 direction, u16 heldKeys) { + WindUpSpinTimer(direction); PlayerTurnInPlace(direction); } @@ -666,7 +825,8 @@ static void PlayerNotOnBikeMoving(u8 direction, u16 heldKeys) return; } } - + + ResetSpinTimer(); // Everything below will move the player a space, reset the timer. gPlayerAvatar.creeping = FALSE; if (gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_SURFING) { @@ -2605,4 +2765,3 @@ bool8 ObjectMovingOnRockStairs(struct ObjectEvent *objectEvent, u8 direction) return FALSE; #endif } - diff --git a/src/play_time.c b/src/play_time.c index 197b1fbac9..23e953ba15 100644 --- a/src/play_time.c +++ b/src/play_time.c @@ -1,6 +1,7 @@ #include "global.h" #include "play_time.h" #include "fake_rtc.h" +#include "field_player_avatar.h" enum { @@ -40,6 +41,7 @@ void PlayTimeCounter_Update(void) return; gSaveBlock2Ptr->playTimeVBlanks++; + UpdateSpinData(); if (gSaveBlock2Ptr->playTimeVBlanks < 60) return; diff --git a/src/pokemon.c b/src/pokemon.c index ef90f10ba3..86db9764b9 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -90,6 +90,9 @@ EWRAM_DATA struct SpriteTemplate gMultiuseSpriteTemplate = {0}; EWRAM_DATA static struct MonSpritesGfxManager *sMonSpritesGfxManagers[MON_SPR_GFX_MANAGERS_COUNT] = {NULL}; EWRAM_DATA static u8 sTriedEvolving = 0; EWRAM_DATA u16 gFollowerSteps = 0; +EWRAM_DATA bool32 removeHeldItem = 0; +EWRAM_DATA u32 removeBagItem = 0; +EWRAM_DATA u32 removeBagItemCount = 0; #include "data/abilities.h" @@ -4436,6 +4439,18 @@ u8 GetNatureFromPersonality(u32 personality) return personality % NUM_NATURES; } +void DoRemoveItems(struct Pokemon *mon) +{ + if (removeHeldItem) + { + u32 heldItem = ITEM_NONE; + SetMonData(mon, MON_DATA_HELD_ITEM, &heldItem); + } + + if (removeBagItem != ITEM_NONE && removeBagItemCount != 0) + RemoveBagItem(removeBagItem, removeBagItemCount); +} + u32 GetGMaxTargetSpecies(u32 species) { const struct FormChange *formChanges = GetSpeciesFormChanges(species); @@ -4460,7 +4475,7 @@ u16 GetEvolutionTargetSpecies(struct Pokemon *mon, enum EvolutionMode mode, u16 u8 beauty = GetMonData(mon, MON_DATA_BEAUTY, 0); u16 upperPersonality = personality >> 16; u32 holdEffect, currentMap, partnerSpecies, partnerHeldItem, partnerHoldEffect; - bool32 consumeItem = FALSE; + removeHeldItem = FALSE; u16 evolutionTracker = GetMonData(mon, MON_DATA_EVOLUTION_TRACKER, 0); const struct Evolution *evolutions = GetSpeciesEvolutions(species); @@ -4541,14 +4556,14 @@ u16 GetEvolutionTargetSpecies(struct Pokemon *mon, enum EvolutionMode mode, u16 if (GetTimeOfDay() == TIME_NIGHT && heldItem == evolutions[i].param) { targetSpecies = evolutions[i].targetSpecies; - consumeItem = TRUE; + removeHeldItem = TRUE; } break; case EVO_ITEM_HOLD_DAY: if (GetTimeOfDay() != TIME_NIGHT && heldItem == evolutions[i].param) { targetSpecies = evolutions[i].targetSpecies; - consumeItem = TRUE; + removeHeldItem = TRUE; } break; case EVO_LEVEL_DUSK: @@ -4728,7 +4743,7 @@ u16 GetEvolutionTargetSpecies(struct Pokemon *mon, enum EvolutionMode mode, u16 if (heldItem == evolutions[i].param) { targetSpecies = evolutions[i].targetSpecies; - consumeItem = TRUE; + removeHeldItem = TRUE; } break; case EVO_USE_MOVE_TWENTY_TIMES: @@ -4769,7 +4784,8 @@ u16 GetEvolutionTargetSpecies(struct Pokemon *mon, enum EvolutionMode mode, u16 if (CheckBagHasItem(evolutions[i].param, 999)) { targetSpecies = evolutions[i].targetSpecies; - RemoveBagItem(evolutions[i].param, 999); + removeBagItem = evolutions[i].param; + removeBagItemCount = 999; } break; } @@ -4790,7 +4806,7 @@ u16 GetEvolutionTargetSpecies(struct Pokemon *mon, enum EvolutionMode mode, u16 if (evolutions[i].param == heldItem) { targetSpecies = evolutions[i].targetSpecies; - consumeItem = TRUE; + removeHeldItem = TRUE; } break; case EVO_TRADE_SPECIFIC_MON: @@ -4874,6 +4890,22 @@ u16 GetEvolutionTargetSpecies(struct Pokemon *mon, enum EvolutionMode mode, u16 if (evolutionItem == EVO_WATER_SCROLL) targetSpecies = evolutions[i].targetSpecies; break; + case EVO_ITEM_HOLD_SPIN_DAY_LESS_THAN_5_SECS_CLOCKWISE: + case EVO_ITEM_HOLD_SPIN_DAY_LESS_THAN_5_SECS_COUNTER_CLOCKWISE: + case EVO_ITEM_HOLD_SPIN_NIGHT_LESS_THAN_5_SECS_CLOCKWISE: + case EVO_ITEM_HOLD_SPIN_NIGHT_LESS_THAN_5_SECS_COUNTER_CLOCKWISE: + case EVO_ITEM_HOLD_SPIN_DAY_MORE_THAN_5_SECS_CLOCKWISE: + case EVO_ITEM_HOLD_SPIN_DAY_MORE_THAN_5_SECS_COUNTER_CLOCKWISE: + case EVO_ITEM_HOLD_SPIN_NIGHT_MORE_THAN_5_SECS_CLOCKWISE: + case EVO_ITEM_HOLD_SPIN_NIGHT_MORE_THAN_5_SECS_COUNTER_CLOCKWISE: + case EVO_ITEM_HOLD_SPIN_DUSK_MORE_THAN_10_SECS: + if (evolutions[i].param == heldItem && evolutionItem == evolutions[i].method) + { + targetSpecies = evolutions[i].targetSpecies; + removeHeldItem = TRUE; + } + + break; } } break; @@ -4889,12 +4921,6 @@ u16 GetEvolutionTargetSpecies(struct Pokemon *mon, enum EvolutionMode mode, u16 return SPECIES_NONE; } - if (consumeItem) - { - heldItem = ITEM_NONE; - SetMonData(mon, MON_DATA_HELD_ITEM, &heldItem); - } - return targetSpecies; }