Skip to content

Commit

Permalink
Merge pull request #130 from celias-stupid-team/Final-fixes-2.5
Browse files Browse the repository at this point in the history
Final fixes 2.5
  • Loading branch information
CeliaDawn authored Jan 20, 2025
2 parents 05fcf4c + 0cff0b4 commit 436669e
Show file tree
Hide file tree
Showing 9 changed files with 111 additions and 96 deletions.
4 changes: 2 additions & 2 deletions asm/macros/battle_ai_script.inc
Original file line number Diff line number Diff line change
Expand Up @@ -283,9 +283,9 @@
.byte \battler
.endm

@ unused
.macro get_highest_type_effectiveness
.macro has_target_prio_move battler:req
.byte 0x30
.byte \battler
.endm

.macro if_type_effectiveness effectiveness:req, ptr:req
Expand Down
7 changes: 7 additions & 0 deletions data/battle_ai_scripts.s
Original file line number Diff line number Diff line change
Expand Up @@ -789,6 +789,7 @@ AI_CheckViability::
if_effect EFFECT_DRAGON_DANCE, AI_CV_DragonDance
if_effect EFFECT_SUBSTITUTE_TEACHER, AI_CV_Substitute
if_Effect EFFECT_REVIVAL_BLESSING, AI_CV_RevivalBlessing
if_move MOVE_WATER_SHURIKEN, AI_CV_WaterShuriken
end

AI_CV_Sleep::
Expand Down Expand Up @@ -2785,6 +2786,12 @@ AI_CV_RevivalBlessing::
if_not_equal PARTY_SIZE, Score_Plus3
end

AI_CV_WaterShuriken:: @ special AI behavior for Nugget Bridge Rival
has_target_prio_move AI_TARGET
if_equal 1, Score_Plus5 @ 1 = TRUE
has_target_prio_move AI_TARGET
if_equal 0, Score_Minus12 @ 0 = FALSE

AI_TryToFaint::
if_can_faint AI_TryToFaint_TryToEncourageQuickAttack
get_how_powerful_move_is
Expand Down
1 change: 1 addition & 0 deletions data/maps/CeruleanCity/scripts.pory
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ CeruleanCity_EventScript_Rival::
end

CeruleanCity_EventScript_RivalSquirtle::
setflag FLAG_FORCE_AI_SWITCH_IN_ORDER
trainerbattle_no_intro TRAINER_RIVAL_CERULEAN_SQUIRTLE, CeruleanCity_Text_RivalDefeat
return

Expand Down
2 changes: 1 addition & 1 deletion include/constants/flags.h
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@
#define FLAG_0x0EF 0x0EF
//Celadon City
#define FLAG_CSR_ERIKA_CUTSCENE_SKIP 0x0F0
#define FLAG_0x0F1 0x0F1
#define FLAG_FORCE_AI_SWITCH_IN_ORDER 0x0F1 //resets after each battle
#define FLAG_0x0F2 0x0F2
#define FLAG_0x0F3 0x0F3
#define FLAG_0x0F4 0x0F4
Expand Down
49 changes: 16 additions & 33 deletions src/battle_ai_script_commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ static void Cmd_count_alive_pokemon(void);
static void Cmd_get_fainted_mons(void);
static void Cmd_get_considered_move_effect(void);
static void Cmd_get_ability(void);
static void Cmd_get_highest_type_effectiveness(void);
static void Cmd_has_target_prio_move(void);
static void Cmd_if_type_effectiveness(void);
static void Cmd_nullsub_32(void);
static void Cmd_nullsub_33(void);
Expand Down Expand Up @@ -194,7 +194,7 @@ static const BattleAICmdFunc sBattleAICmdTable[] =
Cmd_get_fainted_mons, // 0x2D
Cmd_get_considered_move_effect, // 0x2E
Cmd_get_ability, // 0x2F
Cmd_get_highest_type_effectiveness, // 0x30
Cmd_has_target_prio_move, // 0x30
Cmd_if_type_effectiveness, // 0x31
Cmd_nullsub_32, // 0x32
Cmd_nullsub_33, // 0x33
Expand Down Expand Up @@ -1215,46 +1215,29 @@ static void Cmd_get_ability(void)
sAIScriptPtr += 2;
}

static void Cmd_get_highest_type_effectiveness(void)
static void Cmd_has_target_prio_move(void)
{
s32 i;
u8 *dynamicMoveType;
u8 battlerId;

gDynamicBasePower = 0;
dynamicMoveType = &gBattleStruct->dynamicMoveType;
*dynamicMoveType = 0;
gBattleScripting.dmgMultiplier = 1;
gMoveResultFlags = 0;
gCritMultiplier = 1;
AI_THINKING_STRUCT->funcResult = 0;
if (sAIScriptPtr[1] == AI_USER)
battlerId = gBattlerAttacker;
else
battlerId = gBattlerTarget;

AI_THINKING_STRUCT->funcResult = FALSE;

for (i = 0; i < MAX_MON_MOVES; i++)
{
gBattleMoveDamage = 40;
gCurrentMove = gBattleMons[gBattlerAttacker].moves[i];

if (gCurrentMove != MOVE_NONE)
//check if battler has a damaging prio move
if (gBattleMoves[gBattleMons[battlerId].moves[i]].priority >= 1
&& gBattleMoves[gBattleMons[battlerId].moves[i]].power > 0)
{
TypeCalc(gCurrentMove, gBattlerAttacker, gBattlerTarget);

if (gBattleMoveDamage == 120) // Super effective STAB.
gBattleMoveDamage = AI_EFFECTIVENESS_x2;
if (gBattleMoveDamage == 240)
gBattleMoveDamage = AI_EFFECTIVENESS_x4;
if (gBattleMoveDamage == 30) // Not very effective STAB.
gBattleMoveDamage = AI_EFFECTIVENESS_x0_5;
if (gBattleMoveDamage == 15)
gBattleMoveDamage = AI_EFFECTIVENESS_x0_25;

if (gMoveResultFlags & MOVE_RESULT_DOESNT_AFFECT_FOE)
gBattleMoveDamage = AI_EFFECTIVENESS_x0;

if (AI_THINKING_STRUCT->funcResult < gBattleMoveDamage)
AI_THINKING_STRUCT->funcResult = gBattleMoveDamage;
AI_THINKING_STRUCT->funcResult = TRUE;
}
}

sAIScriptPtr += 1;
sAIScriptPtr += 2;
}

static void Cmd_if_type_effectiveness(void)
Expand Down
19 changes: 18 additions & 1 deletion src/battle_ai_switch_items.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "constants/items.h"
#include "constants/moves.h"
#include "constants/pokemon.h"
#include "event_data.h"

static bool8 HasSuperEffectiveMoveAgainstOpponents(bool8 noRng);
static bool8 FindMonWithFlagsAndSuperEffective(u8 flags, u8 moduloPercent);
Expand Down Expand Up @@ -416,7 +417,7 @@ static void ModulateByTypeEffectiveness(u8 atkType, u8 defType1, u8 defType2, u3
u8 GetMostSuitableMonToSwitchInto(void)
{
u8 opposingBattler;
u32 bestDmg; // Note : should be changed to u32 for obvious reasons.
u32 bestDmg;
u8 bestMonId;
u8 battlerIn1, battlerIn2;
s32 i, j;
Expand Down Expand Up @@ -529,6 +530,22 @@ u8 GetMostSuitableMonToSwitchInto(void)
}
}
}

// for special battles use party order
if (FlagGet(FLAG_FORCE_AI_SWITCH_IN_ORDER))
{
for (i = 0; i < PARTY_SIZE; ++i)
{
if (((GetMonData(&gEnemyParty[i], MON_DATA_SPECIES)) != SPECIES_NONE)
&& (GetMonData(&gEnemyParty[i], MON_DATA_HP) > 0)
&& (GetMonData(&gEnemyParty[i], MON_DATA_SPECIES)) != SPECIES_EGG)
{
bestMonId = i;
break;
}
}
}

return bestMonId;
}

Expand Down
108 changes: 55 additions & 53 deletions src/battle_script_commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -1726,15 +1726,15 @@ static void Cmd_adjustnormaldamage(void)
}

if (!(gBattleMons[gBattlerTarget].status2 & STATUS2_SUBSTITUTE)
&& (gBattleMoves[gCurrentMove].effect == EFFECT_FALSE_SWIPE || gProtectStructs[gBattlerTarget].endured || gSpecialStatuses[gBattlerTarget].focusBanded || gSpecialStatuses[gBattlerTarget].focusSashed)
&& (gBattleMoves[gCurrentMove].effect == EFFECT_FALSE_SWIPE || gProtectStructs[gBattlerTarget].endured || gSpecialStatuses[gBattlerTarget].focusBanded)
&& gBattleMons[gBattlerTarget].hp <= gBattleMoveDamage)
{
gBattleMoveDamage = gBattleMons[gBattlerTarget].hp - 1;
if (gProtectStructs[gBattlerTarget].endured)
{
gMoveResultFlags |= MOVE_RESULT_FOE_ENDURED;
}
else if (gSpecialStatuses[gBattlerTarget].focusBanded || gSpecialStatuses[gBattlerTarget].focusSashed)
else if (gSpecialStatuses[gBattlerTarget].focusBanded)
{
gMoveResultFlags |= MOVE_RESULT_FOE_HUNG_ON;
gLastUsedItem = gBattleMons[gBattlerTarget].item;
Expand Down Expand Up @@ -1805,7 +1805,7 @@ static void Cmd_adjustnormaldamage2(void)
{
gMoveResultFlags |= MOVE_RESULT_FOE_ENDURED;
}
else if (gSpecialStatuses[gBattlerTarget].focusBanded || gSpecialStatuses[gBattlerTarget].focusSashed)
else if (gSpecialStatuses[gBattlerTarget].focusBanded)
{
gMoveResultFlags |= MOVE_RESULT_FOE_HUNG_ON;
gLastUsedItem = gBattleMons[gBattlerTarget].item;
Expand Down Expand Up @@ -2148,7 +2148,7 @@ static void Cmd_resultmessage(void)
else
{
gBattleCommunication[MSG_DISPLAY] = 1;
switch (gMoveResultFlags & (u8)(~MOVE_RESULT_MISSED))
switch (gMoveResultFlags & (u16)(~MOVE_RESULT_MISSED))
{
case MOVE_RESULT_SUPER_EFFECTIVE:
stringId = STRINGID_SUPEREFFECTIVE;
Expand Down Expand Up @@ -5874,15 +5874,15 @@ static void Cmd_adjustsetdamage(void)
}

if (!(gBattleMons[gBattlerTarget].status2 & STATUS2_SUBSTITUTE)
&& (gBattleMoves[gCurrentMove].effect == EFFECT_FALSE_SWIPE || gProtectStructs[gBattlerTarget].endured || gSpecialStatuses[gBattlerTarget].focusBanded || gSpecialStatuses[gBattlerTarget].focusSashed)
&& (gBattleMoves[gCurrentMove].effect == EFFECT_FALSE_SWIPE || gProtectStructs[gBattlerTarget].endured || gSpecialStatuses[gBattlerTarget].focusBanded)
&& gBattleMons[gBattlerTarget].hp <= gBattleMoveDamage)
{
gBattleMoveDamage = gBattleMons[gBattlerTarget].hp - 1;
if (gProtectStructs[gBattlerTarget].endured)
{
gMoveResultFlags |= MOVE_RESULT_FOE_ENDURED;
}
else if (gSpecialStatuses[gBattlerTarget].focusBanded || gSpecialStatuses[gBattlerTarget].focusSashed)
else if (gSpecialStatuses[gBattlerTarget].focusBanded)
{
gMoveResultFlags |= MOVE_RESULT_FOE_HUNG_ON;
gLastUsedItem = gBattleMons[gBattlerTarget].item;
Expand Down Expand Up @@ -7401,6 +7401,7 @@ static void Cmd_setlightscreen(void)
static void Cmd_tryKO(void)
{
u8 holdEffect, param;
u16 chance;

//get effect from held items
if (gBattleMons[gBattlerTarget].item == ITEM_ENIGMA_BERRY)
Expand All @@ -7427,66 +7428,61 @@ static void Cmd_tryKO(void)
gSpecialStatuses[gBattlerTarget].focusSashed = TRUE;
}

if (gBattleMons[gBattlerTarget].ability == ABILITY_STURDY)
if (!(gStatuses3[gBattlerTarget] & STATUS3_ALWAYS_HITS))
{
gMoveResultFlags |= MOVE_RESULT_MISSED;
gLastUsedAbility = ABILITY_STURDY;
gBattlescriptCurrInstr = BattleScript_SturdyPreventsOHKO;
RecordAbilityBattle(gBattlerTarget, ABILITY_STURDY);
chance = gBattleMoves[gCurrentMove].accuracy + (gBattleMons[gBattlerAttacker].level - gBattleMons[gBattlerTarget].level);
if (Random() % 100 + 1 < chance && gBattleMons[gBattlerAttacker].level >= gBattleMons[gBattlerTarget].level)
chance = TRUE;
else
chance = FALSE;
}
else if (gDisableStructs[gBattlerTarget].battlerWithSureHit == gBattlerAttacker
&& gBattleMons[gBattlerAttacker].level >= gBattleMons[gBattlerTarget].level)
{
chance = TRUE;
}
else
{
u16 chance;
if (!(gStatuses3[gBattlerTarget] & STATUS3_ALWAYS_HITS))
{
chance = gBattleMoves[gCurrentMove].accuracy + (gBattleMons[gBattlerAttacker].level - gBattleMons[gBattlerTarget].level);
if (Random() % 100 + 1 < chance && gBattleMons[gBattlerAttacker].level >= gBattleMons[gBattlerTarget].level)
chance = TRUE;
else
chance = FALSE;
}
else if (gDisableStructs[gBattlerTarget].battlerWithSureHit == gBattlerAttacker
&& gBattleMons[gBattlerAttacker].level >= gBattleMons[gBattlerTarget].level)
{
chance = gBattleMoves[gCurrentMove].accuracy + (gBattleMons[gBattlerAttacker].level - gBattleMons[gBattlerTarget].level);
if (Random() % 100 + 1 < chance && gBattleMons[gBattlerAttacker].level >= gBattleMons[gBattlerTarget].level)
chance = TRUE;
}
else
chance = FALSE;
}
if (chance)
{
if (gProtectStructs[gBattlerTarget].endured)
{
chance = gBattleMoves[gCurrentMove].accuracy + (gBattleMons[gBattlerAttacker].level - gBattleMons[gBattlerTarget].level);
if (Random() % 100 + 1 < chance && gBattleMons[gBattlerAttacker].level >= gBattleMons[gBattlerTarget].level)
chance = TRUE;
else
chance = FALSE;
gBattleMoveDamage = gBattleMons[gBattlerTarget].hp - 1;
gMoveResultFlags |= MOVE_RESULT_FOE_ENDURED;
}
if (chance)
else if (gSpecialStatuses[gBattlerTarget].sturdied)
{
if (gProtectStructs[gBattlerTarget].endured)
{
gBattleMoveDamage = gBattleMons[gBattlerTarget].hp - 1;
gMoveResultFlags |= MOVE_RESULT_FOE_ENDURED;
}
else if (gSpecialStatuses[gBattlerTarget].focusBanded || gSpecialStatuses[gBattlerTarget].focusSashed)
{
gBattleMoveDamage = gBattleMons[gBattlerTarget].hp - 1;
gMoveResultFlags |= MOVE_RESULT_FOE_HUNG_ON;
gLastUsedItem = gBattleMons[gBattlerTarget].item;
}
else
{
gBattleMoveDamage = gBattleMons[gBattlerTarget].hp;
gMoveResultFlags |= MOVE_RESULT_ONE_HIT_KO;
}
gBattlescriptCurrInstr += 5;
gBattleMoveDamage = gBattleMons[gBattlerTarget].hp - 1;
gMoveResultFlags |= MOVE_RESULT_STURDIED;
gLastUsedAbility = ABILITY_STURDY;
}
else if (gSpecialStatuses[gBattlerTarget].focusBanded || gSpecialStatuses[gBattlerTarget].focusSashed)
{
gBattleMoveDamage = gBattleMons[gBattlerTarget].hp - 1;
gMoveResultFlags |= MOVE_RESULT_FOE_HUNG_ON;
gLastUsedItem = gBattleMons[gBattlerTarget].item;
}
else
{
gMoveResultFlags |= MOVE_RESULT_MISSED;
if (gBattleMons[gBattlerAttacker].level >= gBattleMons[gBattlerTarget].level)
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_KO_MISS;
else
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_KO_UNAFFECTED;
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
gBattleMoveDamage = gBattleMons[gBattlerTarget].hp;
gMoveResultFlags |= MOVE_RESULT_ONE_HIT_KO;
}
gBattlescriptCurrInstr += 5;
}
else
{
gMoveResultFlags |= MOVE_RESULT_MISSED;
if (gBattleMons[gBattlerAttacker].level >= gBattleMons[gBattlerTarget].level)
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_KO_MISS;
else
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_KO_UNAFFECTED;
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
}

Expand Down Expand Up @@ -7528,6 +7524,12 @@ static void Cmd_tryKO_Flash(void)
gBattleMoveDamage = gBattleMons[gBattlerTarget].hp - 1;
gMoveResultFlags |= MOVE_RESULT_FOE_ENDURED;
}
else if (gSpecialStatuses[gBattlerTarget].sturdied)
{
gBattleMoveDamage = gBattleMons[gBattlerTarget].hp - 1;
gMoveResultFlags |= MOVE_RESULT_STURDIED;
gLastUsedAbility = ABILITY_STURDY;
}
//Move never procs Focus Band or Focus Sash
else
{
Expand Down
16 changes: 10 additions & 6 deletions src/battle_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -3051,7 +3051,9 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn)
break;
case HOLD_EFFECT_RESTORE_HP:
//proc healing items
if (gBattleMons[battlerId].hp <= gBattleMons[battlerId].maxHP / 2 && !moveTurn)
if (gBattleMons[battlerId].hp <= gBattleMons[battlerId].maxHP / 2
&& gBattleMons[battlerId].hp > 0
&& !moveTurn)
{
gBattleMoveDamage = battlerHoldEffectParam;
if (gBattleMons[battlerId].hp + battlerHoldEffectParam > gBattleMons[battlerId].maxHP)
Expand All @@ -3065,7 +3067,9 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn)
break;
case HOLD_EFFECT_RESTORE_PCT_HP:
//proc healing items
if (gBattleMons[battlerId].hp <= gBattleMons[battlerId].maxHP / 2 && !moveTurn)
if (gBattleMons[battlerId].hp <= gBattleMons[battlerId].maxHP / 2
&& gBattleMons[battlerId].hp > 0
&& !moveTurn)
{
gBattleMoveDamage = gBattleMons[battlerId].maxHP * battlerHoldEffectParam / 100;
gBattleMoveDamage *= -1;
Expand Down Expand Up @@ -3412,10 +3416,10 @@ s32 GetStealthHazardDamageByTypesAndHP(u8 hazardType, u8 type1, u8 type2, u32 ma

uq4_12_t GetTypeModifier(u32 atkType, u32 defType)
{
DebugPrintf("GetTypeModifier gCurrentMove = %S", gMoveNames[gCurrentMove]);
DebugPrintf("GetTypeModifier atkType = %S", gTypeNames[atkType]);
DebugPrintf("GetTypeModifier defType = %S", gTypeNames[defType]);
DebugPrintf("GetTypeModifier modifier = %d", sTypeEffectivenessTable[atkType][defType]);
// DebugPrintf("GetTypeModifier gCurrentMove = %S", gMoveNames[gCurrentMove]);
// DebugPrintf("GetTypeModifier atkType = %S", gTypeNames[atkType]);
// DebugPrintf("GetTypeModifier defType = %S", gTypeNames[defType]);
// DebugPrintf("GetTypeModifier modifier = %d", sTypeEffectivenessTable[atkType][defType]);

return sTypeEffectivenessTable[atkType][defType];
}
1 change: 1 addition & 0 deletions src/event_data.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ void ClearTempData_CSR(void)
VarSet(VAR_TEMP_START_EVENT_BATTLE, 0); //reset var every time a map loads
FlagClear(FLAG_TEMP_MID_BATTLE_EVENT); //clear flag every time a map loads
FlagClear(FLAG_SHINY_CREATION); //Clear shiny flag on load
FlagClear(FLAG_FORCE_AI_SWITCH_IN_ORDER);
FlagClear(FLAG_SYS_CSR_VICTORY);
RunScriptImmediately(SetPlayerPokedexValues);
}
Expand Down

0 comments on commit 436669e

Please sign in to comment.