Piexplode

Cmd_if_type_effectiveness_with_modifiers

Jan 20th, 2024
135
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 9.64 KB | Gaming | 0 0
  1. static void Cmd_if_type_effectiveness_with_modifiers(void)
  2. {
  3.     u8 damageVar, moveType, hpThreshhold, hpThreshholdHit, attackStage, defenseStage;
  4.     u16 multiplier, divisor;
  5.     u32 side, targetAbility;
  6.  
  7.     gDynamicBasePower = 0;
  8.     gBattleStruct->dynamicMoveType = 0;
  9.     gBattleScripting.dmgMultiplier = 1;
  10.     gMoveResultFlags = 0;
  11.     gCritMultiplier = 1;
  12.  
  13.     damageVar = AI_EFFECTIVENESS_x1;
  14.     gBattleMoveDamage = AI_EFFECTIVENESS_x1;
  15.     gCurrentMove = AI_THINKING_STRUCT->moveConsidered;
  16.     side = GET_BATTLER_SIDE(gBattlerTarget);
  17.  
  18.     // TypeCalc does not assign to gMoveResultFlags, Cmd_typecalc does
  19.     // This makes the check for gMoveResultFlags below always fail
  20.     // This is how you get the "dual non-immunity" glitch, where AI
  21.     // will use ineffective moves on immune pokémon if the second type
  22.     // has a non-neutral, non-immune effectiveness
  23.     // This bug is fixed in this mod
  24.     gMoveResultFlags = TypeCalc(gCurrentMove, sBattler_AI, gBattlerTarget);
  25.  
  26.     // Get the move type to perform extra checks
  27.     moveType = gBattleMoves[gCurrentMove].type;
  28.  
  29.     // Determine if Swarm, Torrent, etc. will activate for the AI User
  30.     hpThreshhold = gBattleMons[sBattler_AI].maxHP * 4 / 3;
  31.  
  32.     if (gBattleMons[sBattler_AI].hp <= hpThreshhold)
  33.         hpThreshholdHit = TRUE;
  34.     else
  35.         hpThreshholdHit = FALSE;
  36.  
  37.     // Get the target's ability to perform extra checks
  38.     // This is a modified version of the get_ability command
  39.     if (BATTLE_HISTORY->abilities[gBattlerTarget] != ABILITY_NONE)
  40.     {
  41.         targetAbility = BATTLE_HISTORY->abilities[gBattlerTarget];
  42.     }
  43.     // Abilities that prevent fleeing.
  44.     else if (gBattleMons[gBattlerTarget].ability == ABILITY_SHADOW_TAG
  45.     || gBattleMons[gBattlerTarget].ability == ABILITY_MAGNET_PULL
  46.     || gBattleMons[gBattlerTarget].ability == ABILITY_ARENA_TRAP)
  47.     {
  48.         targetAbility = gBattleMons[gBattlerTarget].ability;
  49.     }
  50.     else
  51.     {
  52.         if (gSpeciesInfo[gBattleMons[gBattlerTarget].species].abilities[1] != ABILITY_NONE)
  53.         {
  54.             u8 abilityDummyVariable = targetAbility; // Needed to match.
  55.             if (gSpeciesInfo[gBattleMons[gBattlerTarget].species].abilities[0] != abilityDummyVariable
  56.             && gSpeciesInfo[gBattleMons[gBattlerTarget].species].abilities[1] != abilityDummyVariable)
  57.             {
  58.                 targetAbility = gSpeciesInfo[gBattleMons[gBattlerTarget].species].abilities[0];
  59.             }
  60.             else
  61.             {
  62.                 targetAbility = ABILITY_NONE;
  63.             }
  64.         }
  65.         else
  66.         {
  67.             targetAbility = gSpeciesInfo[gBattleMons[gBattlerTarget].species].abilities[0];
  68.         }
  69.     }
  70.  
  71.     if (targetAbility == ABILITY_WONDER_GUARD)
  72.     {
  73.         if (gBattleMoveDamage >= 120)
  74.             gBattleMoveDamage = AI_EFFECTIVENESS_x2;
  75.         else
  76.             gBattleMoveDamage = AI_EFFECTIVENESS_x0;
  77.     }
  78.     else
  79.     {
  80.         // type-specific modifiers
  81.         switch (moveType)
  82.         {
  83.             case TYPE_BUG:
  84.                 if (gBattleMons[sBattler_AI].ability == ABILITY_SWARM && hpThreshholdHit == TRUE)
  85.                     gBattleMoveDamage = gBattleMoveDamage * 4 / 3;
  86.                 break;
  87.             case TYPE_GRASS:
  88.                 if (gBattleMons[sBattler_AI].ability == ABILITY_OVERGROW && hpThreshholdHit == TRUE)
  89.                     gBattleMoveDamage = gBattleMoveDamage * 4 / 3;
  90.                 break;
  91.             case TYPE_ICE:
  92.                 if (targetAbility == ABILITY_THICK_FAT)
  93.                     gBattleMoveDamage = gBattleMoveDamage / 2;
  94.                 break;
  95.             case TYPE_ELECTRIC:
  96.                 if (targetAbility == ABILITY_VOLT_ABSORB)
  97.                     gBattleMoveDamage = 0;
  98.  
  99.                 if (gStatuses3[gBattlerTarget] & STATUS3_CHARGED_UP)
  100.                     gBattleMoveDamage = gBattleMoveDamage * 2;
  101.  
  102.                 if (gStatuses3[gBattlerTarget] & STATUS3_MUDSPORT)
  103.                     gBattleMoveDamage = gBattleMoveDamage / 2;
  104.                 break;
  105.             case TYPE_WATER:
  106.                 if (targetAbility == ABILITY_WATER_ABSORB)
  107.                     gBattleMoveDamage = 0;
  108.  
  109.                 if (gBattleWeather & B_WEATHER_RAIN)
  110.                     gBattleMoveDamage = gBattleMoveDamage * 2;
  111.  
  112.                 if (gBattleMons[sBattler_AI].ability == ABILITY_TORRENT && hpThreshholdHit == TRUE)
  113.                     gBattleMoveDamage = gBattleMoveDamage * 4 / 3;
  114.  
  115.                 if (gBattleWeather & B_WEATHER_SUN)
  116.                     gBattleMoveDamage = gBattleMoveDamage / 2;
  117.                 break;
  118.             case TYPE_FIRE:
  119.                 if (targetAbility == ABILITY_FLASH_FIRE)
  120.                     gBattleMoveDamage = 0;
  121.  
  122.                 if (gBattleWeather & B_WEATHER_SUN)
  123.                     gBattleMoveDamage = gBattleMoveDamage * 2;
  124.  
  125.                 if (gBattleMons[sBattler_AI].ability == ABILITY_BLAZE && hpThreshholdHit == TRUE)
  126.                     gBattleMoveDamage = gBattleMoveDamage * 4 / 3;
  127.  
  128.                 if (gBattleWeather & B_WEATHER_RAIN)
  129.                     gBattleMoveDamage = gBattleMoveDamage / 2;
  130.  
  131.                 if (targetAbility == ABILITY_THICK_FAT)
  132.                     gBattleMoveDamage = gBattleMoveDamage / 2;
  133.  
  134.                 if (gStatuses3[gBattlerTarget] & STATUS3_WATERSPORT)
  135.                     gBattleMoveDamage = gBattleMoveDamage / 2;
  136.  
  137.                 break;
  138.             default:
  139.                 break;
  140.         }
  141.  
  142.         // physical/special modifiers, and getting stat stages
  143.         switch (moveType)
  144.         {
  145.             case TYPE_BUG:
  146.             case TYPE_FIGHTING:
  147.             case TYPE_FLYING:
  148.             case TYPE_GHOST:
  149.             case TYPE_GROUND:
  150.             case TYPE_NORMAL:
  151.             case TYPE_POISON:
  152.             case TYPE_ROCK:
  153.             case TYPE_STEEL:
  154.                 attackStage = gBattleMons[sBattler_AI].statStages[STAT_ATK];
  155.                 defenseStage = gBattleMons[sBattler_AI].statStages[STAT_DEF];
  156.  
  157.                 if (gSideStatuses[side] & SIDE_STATUS_REFLECT)
  158.                     gBattleMoveDamage = gBattleMoveDamage / 2;
  159.  
  160.                 break;
  161.             case TYPE_DARK:
  162.             case TYPE_DRAGON:
  163.             case TYPE_ELECTRIC:
  164.             case TYPE_FIRE:
  165.             case TYPE_GRASS:
  166.             case TYPE_ICE:
  167.             case TYPE_PSYCHIC:
  168.             case TYPE_WATER:
  169.                 attackStage = gBattleMons[sBattler_AI].statStages[STAT_SPATK];
  170.                 defenseStage = gBattleMons[sBattler_AI].statStages[STAT_SPDEF];
  171.  
  172.             if (gSideStatuses[side] & SIDE_STATUS_LIGHTSCREEN)
  173.                 gBattleMoveDamage = gBattleMoveDamage / 2;
  174.  
  175.                 break;
  176.             default:
  177.                 break;
  178.         }
  179.  
  180.         switch (attackStage)
  181.         {
  182.             case 0:
  183.                 multiplier = 33;
  184.                 break;
  185.             case 1:
  186.                 multiplier = 36;
  187.                 break;
  188.             case 2:
  189.                 multiplier = 43;
  190.                 break;
  191.             case 3:
  192.                 multiplier = 50;
  193.                 break;
  194.             case 4:
  195.                 multiplier = 60;
  196.                 break;
  197.             case 5:
  198.                 multiplier = 75;
  199.                 break;
  200.             case 6:
  201.                 multiplier = 100;
  202.                 break;
  203.             case 7:
  204.                 multiplier = 133;
  205.                 break;
  206.             case 8:
  207.                 multiplier = 166;
  208.                 break;
  209.             case 9:
  210.                 multiplier = 200;
  211.                 break;
  212.             case 10:
  213.                 multiplier = 250;
  214.                 break;
  215.             case 11:
  216.                 multiplier = 266;
  217.                 break;
  218.             case 12:
  219.                 multiplier = 300;
  220.                 break;
  221.             default:
  222.                 multiplier = 100;
  223.                 break;
  224.         }
  225.  
  226.         switch (defenseStage)
  227.         {
  228.             case 0:
  229.                 divisor = 33;
  230.                 break;
  231.             case 1:
  232.                 divisor = 36;
  233.                 break;
  234.             case 2:
  235.                 divisor = 43;
  236.                 break;
  237.             case 3:
  238.                 divisor = 50;
  239.                 break;
  240.             case 4:
  241.                 divisor = 60;
  242.                 break;
  243.             case 5:
  244.                 divisor = 75;
  245.                 break;
  246.             case 6:
  247.                 divisor = 100;
  248.                 break;
  249.             case 7:
  250.                 divisor = 133;
  251.                 break;
  252.             case 8:
  253.                 divisor = 166;
  254.                 break;
  255.             case 9:
  256.                 divisor = 200;
  257.                 break;
  258.             case 10:
  259.                 divisor = 250;
  260.                 break;
  261.             case 11:
  262.                 divisor = 266;
  263.                 break;
  264.             case 12:
  265.                 divisor = 300;
  266.                 break;
  267.             default:
  268.                 divisor = 100;
  269.                 break;
  270.         }
  271.  
  272.         // Applying stat stage adjustments
  273.         gBattleMoveDamage = gBattleMoveDamage * multiplier / divisor;
  274.  
  275.         if (gBattleMoveDamage >= 180)
  276.             damageVar = AI_EFFECTIVENESS_x4;
  277.         if (gBattleMoveDamage <= 15)
  278.             damageVar = AI_EFFECTIVENESS_x0_25;
  279.         if (gBattleMoveDamage >= 90)
  280.             damageVar = AI_EFFECTIVENESS_x2;
  281.         if (gBattleMoveDamage <= 30)
  282.             damageVar = AI_EFFECTIVENESS_x0_5;
  283.     }
  284.  
  285.     if (gMoveResultFlags & MOVE_RESULT_DOESNT_AFFECT_FOE)
  286.         damageVar = AI_EFFECTIVENESS_x0;
  287.  
  288.     if (damageVar == gAIScriptPtr[1])
  289.         gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2);
  290.     else
  291.         gAIScriptPtr += 6;
  292. }
Add Comment
Please, Sign In to add comment