Skip to content

Commit

Permalink
Update affection mechanics to gen 8+ (rh-hideout#3495)
Browse files Browse the repository at this point in the history
* Update affection mechanics to gen 8+

* Update battle.h

---------

Co-authored-by: Bassoonian <[email protected]>
  • Loading branch information
kittenchilly and Bassoonian authored Nov 14, 2023
1 parent a8564cf commit 85e75a7
Show file tree
Hide file tree
Showing 9 changed files with 46 additions and 22 deletions.
6 changes: 3 additions & 3 deletions data/battle_anim_scripts.s
Original file line number Diff line number Diff line change
Expand Up @@ -27497,9 +27497,9 @@ General_AffectionHangedOn::
createvisualtask AnimTask_SwayMon, 5, 0, 12, 4096, 4, ANIM_ATTACKER
delay 15
createvisualtask AnimTask_AffectionHangedOn, 0x5
jumpargeq 0x0, FRIENDSHIP_100_TO_149, General_AffectionHangedOn_3Hearts
jumpargeq 0x0, FRIENDSHIP_150_TO_199, General_AffectionHangedOn_4Hearts
jumpargeq 0x0, FRIENDSHIP_200_TO_254, General_AffectionHangedOn_5Hearts
jumpargeq 0x0, AFFECTION_THREE_HEARTS, General_AffectionHangedOn_3Hearts
jumpargeq 0x0, AFFECTION_FOUR_HEARTS, General_AffectionHangedOn_4Hearts
jumpargeq 0x0, AFFECTION_FIVE_HEARTS, General_AffectionHangedOn_5Hearts
createsprite gRedHeartBurstSpriteTemplate, ANIM_ATTACKER, 3, -384, -31
General_AffectionHangedOn_5Hearts:
createsprite gRedHeartBurstSpriteTemplate, ANIM_ATTACKER, 3, -128, -22
Expand Down
2 changes: 1 addition & 1 deletion include/battle_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ bool32 CanBeFrozen(u32 battler);
bool32 CanGetFrostbite(u32 battler);
bool32 CanBeConfused(u32 battler);
bool32 IsBattlerTerrainAffected(u32 battler, u32 terrainFlag);
u32 GetBattlerFriendshipScore(u32 battler);
u32 GetBattlerAffectionHearts(u32 battler);
u32 CountBattlerStatIncreases(u32 battler, bool32 countEvasionAcc);
bool32 IsMyceliumMightOnField(void);
bool32 ChangeTypeBasedOnTerrain(u32 battler);
Expand Down
2 changes: 1 addition & 1 deletion include/config/battle.h
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@
#define B_MULTI_BATTLE_WHITEOUT GEN_LATEST // In Gen4+, multi battles end when the Player and also their Partner don't have any more Pokémon to fight.
#define B_EVOLUTION_AFTER_WHITEOUT GEN_LATEST // In Gen6+, Pokemon that qualify for evolution after battle will evolve even if the player loses.
#define B_WILD_NATURAL_ENEMIES TRUE // If set to TRUE, certain wild mon species will attack other species when partnered in double wild battles (eg. Zangoose vs Seviper)
#define B_AFFECTION_MECHANICS FALSE // In Gen6+, there's a stat called affection that can trigger different effects in battle. From LGPE onwards, those effects use friendship instead.
#define B_AFFECTION_MECHANICS TRUE // In Gen6+, there's a stat called affection that can trigger different effects in battle. From LGPE onwards, those effects use friendship instead.
#define B_TRAINER_CLASS_POKE_BALLS GEN_LATEST // In Gen7+, trainers will use certain types of Poké Balls depending on their trainer class.
#define B_OBEDIENCE_MECHANICS GEN_LATEST // In PLA+ (here Gen8+), obedience restrictions also apply to non-outsider Pokémon, albeit based on their level met rather than actual level
#define B_USE_FROSTBITE FALSE // In PLA, Frostbite replaces Freeze. Enabling this flag does the same here. Moves can still be cherry-picked to either Freeze or Frostbite. Freeze-Dry, Secret Power & Tri Attack depend on this config.
Expand Down
8 changes: 8 additions & 0 deletions include/constants/pokemon.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,14 @@
#define FRIENDSHIP_200_TO_254 5
#define FRIENDSHIP_MAX 6

// Constants for GetBattlerAffectionHearts (based on friendship value)
#define AFFECTION_NO_HEARTS 0 // 0-79 friendship
#define AFFECTION_ONE_HEART 1 // 80-129 friendship
#define AFFECTION_TWO_HEARTS 2 // 130-179 friendship
#define AFFECTION_THREE_HEARTS 3 // 180-219 friendship
#define AFFECTION_FOUR_HEARTS 4 // 220-254 friendship
#define AFFECTION_FIVE_HEARTS 5 // Max friendship

// Friendship value that the majority of species use.
#if P_UPDATED_FRIENDSHIP >= GEN_8
#define STANDARD_FRIENDSHIP 50
Expand Down
1 change: 1 addition & 0 deletions include/pokemon.h
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,7 @@ bool32 SpeciesHasGenderDifferences(u16 species);
bool32 TryFormChange(u32 monId, u32 side, u16 method);
void TryToSetBattleFormChangeMoves(struct Pokemon *mon, u16 method);
u32 GetMonFriendshipScore(struct Pokemon *pokemon);
u32 GetMonAffectionHearts(struct Pokemon *pokemon);
void UpdateMonPersonality(struct BoxPokemon *boxMon, u32 personality);
u8 CalculatePartyCount(struct Pokemon *party);
u16 SanitizeSpeciesId(u16 species);
Expand Down
2 changes: 1 addition & 1 deletion src/battle_anim_new.c
Original file line number Diff line number Diff line change
Expand Up @@ -8630,7 +8630,7 @@ void AnimTask_TerrainPulse(u8 taskId)

void AnimTask_AffectionHangedOn(u8 taskId)
{
gBattleAnimArgs[0] = GetBattlerFriendshipScore(gBattleAnimTarget);
gBattleAnimArgs[0] = GetBattlerAffectionHearts(gBattleAnimTarget);
DestroyAnimVisualTask(taskId);
}

Expand Down
19 changes: 8 additions & 11 deletions src/battle_script_commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -1725,9 +1725,7 @@ u32 GetTotalAccuracy(u32 battlerAtk, u32 battlerDef, u32 move, u32 atkAbility, u
if (gFieldStatuses & STATUS_FIELD_GRAVITY)
calc = (calc * 5) / 3; // 1.66 Gravity acc boost

// With high affection/friendship there's a chance to evade a move by substracting 10% of its accuracy.
// I can't find exact information about that chance, so I'm just gonna write it as a 20% chance for now.
if (B_AFFECTION_MECHANICS == TRUE && GetBattlerFriendshipScore(battlerDef) >= FRIENDSHIP_150_TO_199 && (Random() % 100) <= 20)
if (B_AFFECTION_MECHANICS == TRUE && GetBattlerAffectionHearts(battlerDef) == AFFECTION_FIVE_HEARTS)
calc = (calc * 90) / 100;

return calc;
Expand Down Expand Up @@ -1907,7 +1905,7 @@ s32 CalcCritChanceStageArgs(u32 battlerAtk, u32 battlerDef, u32 move, bool32 rec
+ (holdEffectAtk == HOLD_EFFECT_SCOPE_LENS)
+ 2 * (holdEffectAtk == HOLD_EFFECT_LUCKY_PUNCH && gBattleMons[battlerAtk].species == SPECIES_CHANSEY)
+ 2 * BENEFITS_FROM_LEEK(battlerAtk, holdEffectAtk)
+ 2 * (B_AFFECTION_MECHANICS == TRUE && GetBattlerFriendshipScore(battlerAtk) >= FRIENDSHIP_200_TO_254)
+ 2 * (B_AFFECTION_MECHANICS == TRUE && GetBattlerAffectionHearts(battlerAtk) == AFFECTION_FIVE_HEARTS)
+ (abilityAtk == ABILITY_SUPER_LUCK)
+ gBattleStruct->bonusCritStages[gBattlerAttacker];

Expand Down Expand Up @@ -1994,7 +1992,7 @@ static void Cmd_adjustdamage(void)

u8 holdEffect, param;
u32 moveType;
u32 friendshipScore = GetBattlerFriendshipScore(gBattlerTarget);
u32 affectionScore = GetBattlerAffectionHearts(gBattlerTarget);
u32 rand = Random() % 100;

GET_MOVE_TYPE(gCurrentMove, moveType);
Expand Down Expand Up @@ -2026,12 +2024,11 @@ static void Cmd_adjustdamage(void)
RecordItemEffectBattle(gBattlerTarget, holdEffect);
gSpecialStatuses[gBattlerTarget].focusSashed = TRUE;
}
else if (B_AFFECTION_MECHANICS == TRUE && GetBattlerSide(gBattlerTarget) == B_SIDE_PLAYER && friendshipScore >= FRIENDSHIP_100_TO_149)
else if (B_AFFECTION_MECHANICS == TRUE && GetBattlerSide(gBattlerTarget) == B_SIDE_PLAYER && affectionScore >= AFFECTION_THREE_HEARTS)
{
if ((friendshipScore == FRIENDSHIP_MAX && rand < 25)
|| (friendshipScore == FRIENDSHIP_200_TO_254 && rand < 20)
|| (friendshipScore == FRIENDSHIP_150_TO_199 && rand < 15)
|| (friendshipScore == FRIENDSHIP_100_TO_149 && rand < 10))
if ((affectionScore == AFFECTION_FIVE_HEARTS && rand < 20)
|| (affectionScore == AFFECTION_FOUR_HEARTS && rand < 15)
|| (affectionScore == AFFECTION_THREE_HEARTS && rand < 10))
gSpecialStatuses[gBattlerTarget].affectionEndured = TRUE;
}

Expand Down Expand Up @@ -15847,7 +15844,7 @@ void ApplyExperienceMultipliers(s32 *expAmount, u8 expGetterMonId, u8 faintedBat
*expAmount = (*expAmount * 150) / 100;
if (B_UNEVOLVED_EXP_MULTIPLIER >= GEN_6 && IsMonPastEvolutionLevel(&gPlayerParty[expGetterMonId]))
*expAmount = (*expAmount * 4915) / 4096;
if (B_AFFECTION_MECHANICS == TRUE && GetBattlerFriendshipScore(expGetterMonId) >= FRIENDSHIP_50_TO_99)
if (B_AFFECTION_MECHANICS == TRUE && GetBattlerAffectionHearts(expGetterMonId) >= AFFECTION_FOUR_HEARTS)
*expAmount = (*expAmount * 4915) / 4096;
if (CheckBagHasItem(ITEM_EXP_CHARM, 1)) //is also for other exp boosting Powers if/when implemented
*expAmount = (*expAmount * 150) / 100;
Expand Down
10 changes: 5 additions & 5 deletions src/battle_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -1862,23 +1862,23 @@ u8 GetImprisonedMovesCount(u32 battler, u16 move)
return imprisonedMoves;
}

u32 GetBattlerFriendshipScore(u32 battler)
u32 GetBattlerAffectionHearts(u32 battler)
{
u8 side = GetBattlerSide(battler);
struct Pokemon *party = GetSideParty(side);
u16 species = GetMonData(&party[gBattlerPartyIndexes[battler]], MON_DATA_SPECIES);

if (side != B_SIDE_PLAYER)
return FRIENDSHIP_NONE;
return AFFECTION_NO_HEARTS;
else if (gSpeciesInfo[species].flags & SPECIES_FLAG_MEGA_EVOLUTION
|| (gBattleTypeFlags & (BATTLE_TYPE_EREADER_TRAINER
| BATTLE_TYPE_FRONTIER
| BATTLE_TYPE_LINK
| BATTLE_TYPE_RECORDED_LINK
| BATTLE_TYPE_SECRET_BASE)))
return FRIENDSHIP_NONE;
return AFFECTION_NO_HEARTS;

return GetMonFriendshipScore(&party[gBattlerPartyIndexes[battler]]);
return GetMonAffectionHearts(&party[gBattlerPartyIndexes[battler]]);
}

static void TryToRevertMimicry(void)
Expand Down Expand Up @@ -2421,7 +2421,7 @@ u8 DoFieldEndTurnEffects(void)
{
if (B_AFFECTION_MECHANICS == TRUE
&& GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER
&& GetBattlerFriendshipScore(gBattlerAttacker) >= FRIENDSHIP_150_TO_199
&& GetBattlerAffectionHearts(gBattlerAttacker) >= AFFECTION_FOUR_HEARTS
&& (Random() % 100 < 20))
{
gBattleCommunication[MULTISTRING_CHOOSER] = 1;
Expand Down
18 changes: 18 additions & 0 deletions src/pokemon.c
Original file line number Diff line number Diff line change
Expand Up @@ -9289,6 +9289,24 @@ u32 GetMonFriendshipScore(struct Pokemon *pokemon)
return FRIENDSHIP_NONE;
}

u32 GetMonAffectionHearts(struct Pokemon *pokemon)
{
u32 friendship = GetMonData(pokemon, MON_DATA_FRIENDSHIP, NULL);

if (friendship == MAX_FRIENDSHIP)
return AFFECTION_FIVE_HEARTS;
if (friendship >= 220)
return AFFECTION_FOUR_HEARTS;
if (friendship >= 180)
return AFFECTION_THREE_HEARTS;
if (friendship >= 130)
return AFFECTION_TWO_HEARTS;
if (friendship >= 80)
return AFFECTION_ONE_HEART;

return AFFECTION_NO_HEARTS;
}

void UpdateMonPersonality(struct BoxPokemon *boxMon, u32 personality)
{
struct PokemonSubstruct0 *old0, *new0;
Expand Down

0 comments on commit 85e75a7

Please sign in to comment.