Skip to content

Commit

Permalink
Add a calculateBaseDamage func
Browse files Browse the repository at this point in the history
  • Loading branch information
thejetou committed Sep 27, 2023
1 parent 69c5854 commit cbdfc16
Show file tree
Hide file tree
Showing 2 changed files with 149 additions and 91 deletions.
99 changes: 69 additions & 30 deletions calc/src/mechanics/gen56.ts
Original file line number Diff line number Diff line change
Expand Up @@ -740,34 +740,17 @@ export function calculateBWXY(
// #endregion
// #region Damage

let baseDamage = getBaseDamage(attacker.level, basePower, attack, defense);

const isSpread = field.gameType !== 'Singles' &&
['allAdjacent', 'allAdjacentFoes'].includes(move.target);
if (isSpread) {
baseDamage = pokeRound(OF32(baseDamage * 3072) / 4096);
}

if (attacker.hasAbility('Parental Bond (Child)')) {
baseDamage = pokeRound(OF32(baseDamage * 2048) / 4096);
}

if ((field.hasWeather('Sun', 'Harsh Sunshine') && move.hasType('Fire')) ||
(field.hasWeather('Rain', 'Heavy Rain') && move.hasType('Water'))) {
baseDamage = pokeRound(OF32(baseDamage * 6144) / 4096);
desc.weather = field.weather;
} else if (
(field.hasWeather('Sun') && move.hasType('Water')) ||
(field.hasWeather('Rain') && move.hasType('Fire'))
) {
baseDamage = pokeRound(OF32(baseDamage * 2048) / 4096);
desc.weather = field.weather;
}

if (isCritical) {
baseDamage = Math.floor(OF32(baseDamage * (gen.num > 5 ? 1.5 : 2)));
desc.isCritical = isCritical;
}
const baseDamage = calculateBaseDamageBWXY(
gen,
attacker,
basePower,
attack,
defense,
move,
field,
desc,
isCritical
);

// the random factor is applied between the crit mod and the stab mod, so don't apply anything
// below this until we're inside the loop
Expand Down Expand Up @@ -803,6 +786,9 @@ export function calculateBWXY(
);
const finalMod = chainMods(finalMods, 41, 131072);

const isSpread = field.gameType !== 'Singles' &&
['allAdjacent', 'allAdjacentFoes'].includes(move.target);

let childDamage: number[] | undefined;
if (attacker.hasAbility('Parental Bond') && move.hits === 1 && !isSpread) {
const child = attacker.clone();
Expand Down Expand Up @@ -870,7 +856,6 @@ export function calculateBWXY(
let damageMultiplier = 0;
damage = damage.map(affectedAmount => {
if (times) {
const newDefense = getModifiedStat(defense, defenderDefBoost);
const newFinalMods = calculateFinalModsBWXY(
gen,
attacker,
Expand All @@ -883,7 +868,18 @@ export function calculateBWXY(
times
);
const newFinalMod = chainMods(newFinalMods, 41, 131072);
const newBaseDamage = getBaseDamage(attacker.level, basePower, attack, newDefense);
const newDefense = getModifiedStat(defense, defenderDefBoost);
const newBaseDamage = calculateBaseDamageBWXY(
gen,
attacker,
basePower,
attack,
newDefense,
move,
field,
desc,
isCritical
);
const newFinalDamage = getFinalDamage(
newBaseDamage,
damageMultiplier,
Expand Down Expand Up @@ -914,6 +910,49 @@ export function calculateBWXY(
return result;
}

function calculateBaseDamageBWXY(
gen: Generation,
attacker: Pokemon,
basePower: number,
attack: number,
defense: number,
move: Move,
field: Field,
desc: RawDesc,
isCritical = false,
) {
let baseDamage = getBaseDamage(attacker.level, basePower, attack, defense);

const isSpread = field.gameType !== 'Singles' &&
['allAdjacent', 'allAdjacentFoes'].includes(move.target);
if (isSpread) {
baseDamage = pokeRound(OF32(baseDamage * 3072) / 4096);
}

if (attacker.hasAbility('Parental Bond (Child)')) {
baseDamage = pokeRound(OF32(baseDamage * 2048) / 4096);
}

if ((field.hasWeather('Sun', 'Harsh Sunshine') && move.hasType('Fire')) ||
(field.hasWeather('Rain', 'Heavy Rain') && move.hasType('Water'))) {
baseDamage = pokeRound(OF32(baseDamage * 6144) / 4096);
desc.weather = field.weather;
} else if (
(field.hasWeather('Sun') && move.hasType('Water')) ||
(field.hasWeather('Rain') && move.hasType('Fire'))
) {
baseDamage = pokeRound(OF32(baseDamage * 2048) / 4096);
desc.weather = field.weather;
}

if (isCritical) {
baseDamage = Math.floor(OF32(baseDamage * (gen.num > 5 ? 1.5 : 2)));
desc.isCritical = isCritical;
}

return baseDamage;
}

function calculateFinalModsBWXY(
gen: Generation,
attacker: Pokemon,
Expand Down
141 changes: 80 additions & 61 deletions calc/src/mechanics/gen789.ts
Original file line number Diff line number Diff line change
Expand Up @@ -469,38 +469,18 @@ export function calculateSMSSSV(
// #endregion
// #region Damage

let baseDamage = getBaseDamage(attacker.level, basePower, attack, defense);

const isSpread = field.gameType !== 'Singles' &&
['allAdjacent', 'allAdjacentFoes'].includes(move.target);
if (isSpread) {
baseDamage = pokeRound(OF32(baseDamage * 3072) / 4096);
}

if (attacker.hasAbility('Parental Bond (Child)')) {
baseDamage = pokeRound(OF32(baseDamage * 1024) / 4096);
}

if (
field.hasWeather('Sun') && move.named('Hydro Steam') && !attacker.hasItem('Utility Umbrella')
) {
baseDamage = pokeRound(OF32(baseDamage * 6144) / 4096);
desc.weather = field.weather;
} else if (!defender.hasItem('Utility Umbrella')) {
if (
(field.hasWeather('Sun', 'Harsh Sunshine') && move.hasType('Fire')) ||
(field.hasWeather('Rain', 'Heavy Rain') && move.hasType('Water'))
) {
baseDamage = pokeRound(OF32(baseDamage * 6144) / 4096);
desc.weather = field.weather;
} else if (
(field.hasWeather('Sun') && move.hasType('Water')) ||
(field.hasWeather('Rain') && move.hasType('Fire'))
) {
baseDamage = pokeRound(OF32(baseDamage * 2048) / 4096);
desc.weather = field.weather;
}
}
const baseDamage = calculateBaseDamageSMSSSV(
gen,
attacker,
defender,
basePower,
attack,
defense,
move,
field,
desc,
isCritical
);

if (hasTerrainSeed(defender) &&
field.hasTerrain(defender.item!.substring(0, defender.item!.indexOf(' ')) as Terrain) &&
Expand All @@ -510,11 +490,6 @@ export function calculateSMSSSV(
desc.defenderItem = defender.item;
}

if (isCritical) {
baseDamage = Math.floor(OF32(baseDamage * 1.5));
desc.isCritical = isCritical;
}

// the random factor is applied between the crit mod and the stab mod, so don't apply anything
// below this until we're inside the loop
let stabMod = 4096;
Expand Down Expand Up @@ -560,6 +535,9 @@ export function calculateSMSSSV(

const finalMod = chainMods(finalMods, 41, 131072);

const isSpread = field.gameType !== 'Singles' &&
['allAdjacent', 'allAdjacentFoes'].includes(move.target);

let childDamage: number[] | undefined;
if (attacker.hasAbility('Parental Bond') && move.hits === 1 && !isSpread) {
const child = attacker.clone();
Expand Down Expand Up @@ -628,7 +606,6 @@ export function calculateSMSSSV(
let damageMultiplier = 0;
damage = damage.map(affectedAmount => {
if (times) {
const newDefense = getModifiedStat(defense, defenderDefBoost);
const newFinalMods = calculateFinalModsSMSSSV(
gen,
attacker,
Expand All @@ -641,29 +618,19 @@ export function calculateSMSSSV(
times
);
const newFinalMod = chainMods(newFinalMods, 41, 131072);
let newBaseDamage = getBaseDamage(attacker.level, basePower, attack, newDefense);
if (isCritical) {
newBaseDamage = Math.floor(OF32(newBaseDamage * 1.5));
}
// TODO probably move these to a common function
const isSpread = field.gameType !== 'Singles' &&
['allAdjacent', 'allAdjacentFoes'].includes(move.target);
if (isSpread) {
newBaseDamage = pokeRound(OF32(newBaseDamage * 3072) / 4096);
}
if (!defender.hasItem('Utility Umbrella')) {
if (
(field.hasWeather('Sun', 'Harsh Sunshine') && move.hasType('Fire')) ||
(field.hasWeather('Rain', 'Heavy Rain') && move.hasType('Water'))
) {
newBaseDamage = pokeRound(OF32(newBaseDamage * 6144) / 4096);
} else if (
(field.hasWeather('Sun') && move.hasType('Water')) ||
(field.hasWeather('Rain') && move.hasType('Fire'))
) {
newBaseDamage = pokeRound(OF32(newBaseDamage * 2048) / 4096);
}
}
const newDefense = getModifiedStat(defense, defenderDefBoost);
const newBaseDamage = calculateBaseDamageSMSSSV(
gen,
attacker,
defender,
basePower,
attack,
newDefense,
move,
field,
desc,
isCritical
);
const newFinalDamage = getFinalDamage(
newBaseDamage,
damageMultiplier,
Expand Down Expand Up @@ -1507,6 +1474,58 @@ export function calculateDfModsSMSSSV(
return dfMods;
}

function calculateBaseDamageSMSSSV(
gen: Generation,
attacker: Pokemon,
defender: Pokemon,
basePower: number,
attack: number,
defense: number,
move: Move,
field: Field,
desc: RawDesc,
isCritical = false,
) {
let baseDamage = getBaseDamage(attacker.level, basePower, attack, defense);
const isSpread = field.gameType !== 'Singles' &&
['allAdjacent', 'allAdjacentFoes'].includes(move.target);
if (isSpread) {
baseDamage = pokeRound(OF32(baseDamage * 3072) / 4096);
}

if (attacker.hasAbility('Parental Bond (Child)')) {
baseDamage = pokeRound(OF32(baseDamage * 1024) / 4096);
}

if (
field.hasWeather('Sun') && move.named('Hydro Steam') && !attacker.hasItem('Utility Umbrella')
) {
baseDamage = pokeRound(OF32(baseDamage * 6144) / 4096);
desc.weather = field.weather;
} else if (!defender.hasItem('Utility Umbrella')) {
if (
(field.hasWeather('Sun', 'Harsh Sunshine') && move.hasType('Fire')) ||
(field.hasWeather('Rain', 'Heavy Rain') && move.hasType('Water'))
) {
baseDamage = pokeRound(OF32(baseDamage * 6144) / 4096);
desc.weather = field.weather;
} else if (
(field.hasWeather('Sun') && move.hasType('Water')) ||
(field.hasWeather('Rain') && move.hasType('Fire'))
) {
baseDamage = pokeRound(OF32(baseDamage * 2048) / 4096);
desc.weather = field.weather;
}
}

if (isCritical) {
baseDamage = Math.floor(OF32(baseDamage * 1.5));
desc.isCritical = isCritical;
}

return baseDamage;
}

export function calculateFinalModsSMSSSV(
gen: Generation,
attacker: Pokemon,
Expand Down

0 comments on commit cbdfc16

Please sign in to comment.