Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- static void Cmd_if_type_effectiveness_with_modifiers(void)
- {
- u8 damageVar, moveType, hpThreshhold, hpThreshholdHit, attackStage, defenseStage;
- u16 multiplier, divisor;
- u32 side, targetAbility;
- gDynamicBasePower = 0;
- gBattleStruct->dynamicMoveType = 0;
- gBattleScripting.dmgMultiplier = 1;
- gMoveResultFlags = 0;
- gCritMultiplier = 1;
- damageVar = AI_EFFECTIVENESS_x1;
- gBattleMoveDamage = AI_EFFECTIVENESS_x1;
- gCurrentMove = AI_THINKING_STRUCT->moveConsidered;
- side = GET_BATTLER_SIDE(gBattlerTarget);
- // TypeCalc does not assign to gMoveResultFlags, Cmd_typecalc does
- // This makes the check for gMoveResultFlags below always fail
- // This is how you get the "dual non-immunity" glitch, where AI
- // will use ineffective moves on immune pokémon if the second type
- // has a non-neutral, non-immune effectiveness
- // This bug is fixed in this mod
- gMoveResultFlags = TypeCalc(gCurrentMove, sBattler_AI, gBattlerTarget);
- // Get the move type to perform extra checks
- moveType = gBattleMoves[gCurrentMove].type;
- // Determine if Swarm, Torrent, etc. will activate for the AI User
- hpThreshhold = gBattleMons[sBattler_AI].maxHP * 4 / 3;
- if (gBattleMons[sBattler_AI].hp <= hpThreshhold)
- hpThreshholdHit = TRUE;
- else
- hpThreshholdHit = FALSE;
- // Get the target's ability to perform extra checks
- // This is a modified version of the get_ability command
- if (BATTLE_HISTORY->abilities[gBattlerTarget] != ABILITY_NONE)
- {
- targetAbility = BATTLE_HISTORY->abilities[gBattlerTarget];
- }
- // Abilities that prevent fleeing.
- else if (gBattleMons[gBattlerTarget].ability == ABILITY_SHADOW_TAG
- || gBattleMons[gBattlerTarget].ability == ABILITY_MAGNET_PULL
- || gBattleMons[gBattlerTarget].ability == ABILITY_ARENA_TRAP)
- {
- targetAbility = gBattleMons[gBattlerTarget].ability;
- }
- else
- {
- if (gSpeciesInfo[gBattleMons[gBattlerTarget].species].abilities[1] != ABILITY_NONE)
- {
- u8 abilityDummyVariable = targetAbility; // Needed to match.
- if (gSpeciesInfo[gBattleMons[gBattlerTarget].species].abilities[0] != abilityDummyVariable
- && gSpeciesInfo[gBattleMons[gBattlerTarget].species].abilities[1] != abilityDummyVariable)
- {
- targetAbility = gSpeciesInfo[gBattleMons[gBattlerTarget].species].abilities[0];
- }
- else
- {
- targetAbility = ABILITY_NONE;
- }
- }
- else
- {
- targetAbility = gSpeciesInfo[gBattleMons[gBattlerTarget].species].abilities[0];
- }
- }
- if (targetAbility == ABILITY_WONDER_GUARD)
- {
- if (gBattleMoveDamage >= 120)
- gBattleMoveDamage = AI_EFFECTIVENESS_x2;
- else
- gBattleMoveDamage = AI_EFFECTIVENESS_x0;
- }
- else
- {
- // type-specific modifiers
- switch (moveType)
- {
- case TYPE_BUG:
- if (gBattleMons[sBattler_AI].ability == ABILITY_SWARM && hpThreshholdHit == TRUE)
- gBattleMoveDamage = gBattleMoveDamage * 4 / 3;
- break;
- case TYPE_GRASS:
- if (gBattleMons[sBattler_AI].ability == ABILITY_OVERGROW && hpThreshholdHit == TRUE)
- gBattleMoveDamage = gBattleMoveDamage * 4 / 3;
- break;
- case TYPE_ICE:
- if (targetAbility == ABILITY_THICK_FAT)
- gBattleMoveDamage = gBattleMoveDamage / 2;
- break;
- case TYPE_ELECTRIC:
- if (targetAbility == ABILITY_VOLT_ABSORB)
- gBattleMoveDamage = 0;
- if (gStatuses3[gBattlerTarget] & STATUS3_CHARGED_UP)
- gBattleMoveDamage = gBattleMoveDamage * 2;
- if (gStatuses3[gBattlerTarget] & STATUS3_MUDSPORT)
- gBattleMoveDamage = gBattleMoveDamage / 2;
- break;
- case TYPE_WATER:
- if (targetAbility == ABILITY_WATER_ABSORB)
- gBattleMoveDamage = 0;
- if (gBattleWeather & B_WEATHER_RAIN)
- gBattleMoveDamage = gBattleMoveDamage * 2;
- if (gBattleMons[sBattler_AI].ability == ABILITY_TORRENT && hpThreshholdHit == TRUE)
- gBattleMoveDamage = gBattleMoveDamage * 4 / 3;
- if (gBattleWeather & B_WEATHER_SUN)
- gBattleMoveDamage = gBattleMoveDamage / 2;
- break;
- case TYPE_FIRE:
- if (targetAbility == ABILITY_FLASH_FIRE)
- gBattleMoveDamage = 0;
- if (gBattleWeather & B_WEATHER_SUN)
- gBattleMoveDamage = gBattleMoveDamage * 2;
- if (gBattleMons[sBattler_AI].ability == ABILITY_BLAZE && hpThreshholdHit == TRUE)
- gBattleMoveDamage = gBattleMoveDamage * 4 / 3;
- if (gBattleWeather & B_WEATHER_RAIN)
- gBattleMoveDamage = gBattleMoveDamage / 2;
- if (targetAbility == ABILITY_THICK_FAT)
- gBattleMoveDamage = gBattleMoveDamage / 2;
- if (gStatuses3[gBattlerTarget] & STATUS3_WATERSPORT)
- gBattleMoveDamage = gBattleMoveDamage / 2;
- break;
- default:
- break;
- }
- // physical/special modifiers, and getting stat stages
- switch (moveType)
- {
- case TYPE_BUG:
- case TYPE_FIGHTING:
- case TYPE_FLYING:
- case TYPE_GHOST:
- case TYPE_GROUND:
- case TYPE_NORMAL:
- case TYPE_POISON:
- case TYPE_ROCK:
- case TYPE_STEEL:
- attackStage = gBattleMons[sBattler_AI].statStages[STAT_ATK];
- defenseStage = gBattleMons[sBattler_AI].statStages[STAT_DEF];
- if (gSideStatuses[side] & SIDE_STATUS_REFLECT)
- gBattleMoveDamage = gBattleMoveDamage / 2;
- break;
- case TYPE_DARK:
- case TYPE_DRAGON:
- case TYPE_ELECTRIC:
- case TYPE_FIRE:
- case TYPE_GRASS:
- case TYPE_ICE:
- case TYPE_PSYCHIC:
- case TYPE_WATER:
- attackStage = gBattleMons[sBattler_AI].statStages[STAT_SPATK];
- defenseStage = gBattleMons[sBattler_AI].statStages[STAT_SPDEF];
- if (gSideStatuses[side] & SIDE_STATUS_LIGHTSCREEN)
- gBattleMoveDamage = gBattleMoveDamage / 2;
- break;
- default:
- break;
- }
- switch (attackStage)
- {
- case 0:
- multiplier = 33;
- break;
- case 1:
- multiplier = 36;
- break;
- case 2:
- multiplier = 43;
- break;
- case 3:
- multiplier = 50;
- break;
- case 4:
- multiplier = 60;
- break;
- case 5:
- multiplier = 75;
- break;
- case 6:
- multiplier = 100;
- break;
- case 7:
- multiplier = 133;
- break;
- case 8:
- multiplier = 166;
- break;
- case 9:
- multiplier = 200;
- break;
- case 10:
- multiplier = 250;
- break;
- case 11:
- multiplier = 266;
- break;
- case 12:
- multiplier = 300;
- break;
- default:
- multiplier = 100;
- break;
- }
- switch (defenseStage)
- {
- case 0:
- divisor = 33;
- break;
- case 1:
- divisor = 36;
- break;
- case 2:
- divisor = 43;
- break;
- case 3:
- divisor = 50;
- break;
- case 4:
- divisor = 60;
- break;
- case 5:
- divisor = 75;
- break;
- case 6:
- divisor = 100;
- break;
- case 7:
- divisor = 133;
- break;
- case 8:
- divisor = 166;
- break;
- case 9:
- divisor = 200;
- break;
- case 10:
- divisor = 250;
- break;
- case 11:
- divisor = 266;
- break;
- case 12:
- divisor = 300;
- break;
- default:
- divisor = 100;
- break;
- }
- // Applying stat stage adjustments
- gBattleMoveDamage = gBattleMoveDamage * multiplier / divisor;
- if (gBattleMoveDamage >= 180)
- damageVar = AI_EFFECTIVENESS_x4;
- if (gBattleMoveDamage <= 15)
- damageVar = AI_EFFECTIVENESS_x0_25;
- if (gBattleMoveDamage >= 90)
- damageVar = AI_EFFECTIVENESS_x2;
- if (gBattleMoveDamage <= 30)
- damageVar = AI_EFFECTIVENESS_x0_5;
- }
- if (gMoveResultFlags & MOVE_RESULT_DOESNT_AFFECT_FOE)
- damageVar = AI_EFFECTIVENESS_x0;
- if (damageVar == gAIScriptPtr[1])
- gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2);
- else
- gAIScriptPtr += 6;
- }
Add Comment
Please, Sign In to add comment