Skip to content

Commit

Permalink
Implement Gigantamaxing properly
Browse files Browse the repository at this point in the history
  • Loading branch information
KrisXV committed Jan 4, 2023
1 parent f7259ca commit 7d8e97d
Show file tree
Hide file tree
Showing 13 changed files with 153 additions and 352 deletions.
327 changes: 46 additions & 281 deletions calc/src/data/species.ts

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions calc/src/desc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export interface RawDesc {
rivalry?: 'buffed' | 'nerfed';
terrain?: Terrain;
weather?: Weather;
isDefenderDynamaxed?: boolean;
isDefenderDynamaxed?: 'gmax' | boolean;
}

export function display(
Expand Down Expand Up @@ -914,7 +914,7 @@ function buildDescription(description: RawDesc, attacker: Pokemon, defender: Pok
output += 'protected ';
}
if (description.isDefenderDynamaxed) {
output += 'Dynamax ';
output += description.isDefenderDynamaxed === 'gmax' ? 'Gigantamax ' : 'Dynamax ';
}
if (description.defenderTera) {
output += `Tera ${description.defenderTera} `;
Expand Down
73 changes: 39 additions & 34 deletions calc/src/move.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export class Move implements State.Move {
species?: I.SpeciesName;
useZ?: boolean;
useMax?: boolean;
isGmax?: boolean;
overrides?: Partial<I.Move>;

hits: number;
Expand Down Expand Up @@ -62,7 +63,8 @@ export class Move implements State.Move {
data.type,
options.species,
!!(data.category === 'Status'),
options.ability
options.ability,
options.isGmax
);
const maxMove = gen.moves.get(toID(maxMoveName));
const maxPower = () => {
Expand Down Expand Up @@ -110,6 +112,7 @@ export class Move implements State.Move {
this.item = options.item;
this.useZ = options.useZ;
this.useMax = options.useMax;
this.isGmax = options.useMax;
this.overrides = options.overrides;
this.species = options.species;

Expand Down Expand Up @@ -175,6 +178,7 @@ export class Move implements State.Move {
species: this.species,
useZ: this.useZ,
useMax: this.useMax,
isGmax: this.isGmax,
isCrit: this.isCrit,
hits: this.hits,
timesUsed: this.timesUsed,
Expand Down Expand Up @@ -239,64 +243,65 @@ export function getMaxMoveName(
moveType: I.TypeName,
pokemonSpecies?: string,
isStatus?: boolean,
pokemonAbility?: string
pokemonAbility?: string,
isGmax?: boolean,
) {
if (isStatus) return 'Max Guard';
if (pokemonAbility === 'Normalize') return 'Max Strike';
if (moveType === 'Fire') {
if (pokemonSpecies === 'Charizard-Gmax') return 'G-Max Wildfire';
if (pokemonSpecies === 'Centiskorch-Gmax') return 'G-Max Centiferno';
if (pokemonSpecies === 'Cinderace-Gmax') return 'G-Max Fire Ball';
if (pokemonSpecies === 'Charizard' && isGmax) return 'G-Max Wildfire';
if (pokemonSpecies === 'Centiskorch' && isGmax) return 'G-Max Centiferno';
if (pokemonSpecies === 'Cinderace' && isGmax) return 'G-Max Fireball';
}
if (moveType === 'Normal') {
if (pokemonSpecies === 'Eevee-Gmax') return 'G-Max Cuddle';
if (pokemonSpecies === 'Meowth-Gmax') return 'G-Max Gold Rush';
if (pokemonSpecies === 'Snorlax-Gmax') return 'G-Max Replenish';
if (pokemonSpecies === 'Eevee' && isGmax) return 'G-Max Cuddle';
if (pokemonSpecies === 'Meowth' && isGmax) return 'G-Max Gold Rush';
if (pokemonSpecies === 'Snorlax' && isGmax) return 'G-Max Replenish';
if (pokemonAbility === 'Pixilate') return 'Max Starfall';
if (pokemonAbility === 'Aerilate') return 'Max Airstream';
if (pokemonAbility === 'Refrigerate') return 'Max Hailstorm';
if (pokemonAbility === 'Galvanize') return 'Max Lightning';
}
if (moveType === 'Fairy') {
if (pokemonSpecies === 'Alcremie-Gmax') return 'G-Max Finale';
if (pokemonSpecies === 'Hatterene-Gmax') return 'G-Max Smite';
if (pokemonSpecies === 'Alcremie' && isGmax) return 'G-Max Finale';
if (pokemonSpecies === 'Hatterene' && isGmax) return 'G-Max Smite';
}
if (moveType === 'Steel') {
if (pokemonSpecies === 'Copperajah-Gmax') return 'G-Max Steelsurge';
if (pokemonSpecies === 'Melmetal-Gmax') return 'G-Max Meltdown';
if (pokemonSpecies === 'Copperajah' && isGmax) return 'G-Max Steelsurge';
if (pokemonSpecies === 'Melmetal' && isGmax) return 'G-Max Meltdown';
}
if (moveType === 'Electric') {
if (pokemonSpecies === 'Pikachu-Gmax') return 'G-Max Volt Crash';
if (pokemonSpecies === 'Pikachu' && isGmax) return 'G-Max Volt Crash';
if (pokemonSpecies?.startsWith('Toxtricity') &&
pokemonSpecies?.endsWith('Gmax')) return 'G-Max Stun Shock';
}
if (moveType === 'Grass') {
if (pokemonSpecies === 'Appletun-Gmax') return 'G-Max Sweetness';
if (pokemonSpecies === 'Flapple-Gmax') return 'G-Max Tartness';
if (pokemonSpecies === 'Rillaboom-Gmax') return 'G-Max Drum Solo';
if (pokemonSpecies === 'Venusaur-Gmax') return 'G-Max Vine Lash';
if (pokemonSpecies === 'Appletun' && isGmax) return 'G-Max Sweetness';
if (pokemonSpecies === 'Flapple' && isGmax) return 'G-Max Tartness';
if (pokemonSpecies === 'Rillaboom' && isGmax) return 'G-Max Drum Solo';
if (pokemonSpecies === 'Venusaur' && isGmax) return 'G-Max Vine Lash';
}
if (moveType === 'Water') {
if (pokemonSpecies === 'Blastoise-Gmax') return 'G-Max Cannonade';
if (pokemonSpecies === 'Drednaw-Gmax') return 'G-Max Stonesurge';
if (pokemonSpecies === 'Inteleon-Gmax') return 'G-Max Hydrosnipe';
if (pokemonSpecies === 'Kingler-Gmax') return 'G-Max Foam Burst';
if (pokemonSpecies === 'Urshifu-Rapid-Strike-Gmax') return 'G-Max Rapid Flow';
if (pokemonSpecies === 'Blastoise' && isGmax) return 'G-Max Cannonade';
if (pokemonSpecies === 'Drednaw' && isGmax) return 'G-Max Stonesurge';
if (pokemonSpecies === 'Inteleon' && isGmax) return 'G-Max Hydrosnipe';
if (pokemonSpecies === 'Kingler' && isGmax) return 'G-Max Foam Burst';
if (pokemonSpecies === 'Urshifu-Rapid-Strike' && isGmax) return 'G-Max Rapid Flow';
}
if (moveType === 'Dark') {
if (pokemonSpecies === 'Grimmsnarl-Gmax') return 'G-Max Snooze';
if (pokemonSpecies === 'Urshifu-Gmax') return 'G-Max One Blow';
if (pokemonSpecies === 'Grimmsnarl' && isGmax) return 'G-Max Snooze';
if (pokemonSpecies === 'Urshifu' && isGmax) return 'G-Max One Blow';
}
if (moveType === 'Poison' && pokemonSpecies === 'Garbodor-Gmax') return 'G-Max Malodor';
if (moveType === 'Fighting' && pokemonSpecies === 'Machamp-Gmax') return 'G-Max Chi Strike';
if (moveType === 'Ghost' && pokemonSpecies === 'Gengar-Gmax') return 'G-Max Terror';
if (moveType === 'Ice' && pokemonSpecies === 'Lapras-Gmax') return 'G-Max Resonance';
if (moveType === 'Flying' && pokemonSpecies === 'Corviknight-Gmax') return 'G-Max Wind Rage';
if (moveType === 'Dragon' && pokemonSpecies === 'Duraludon-Gmax') return 'G-Max Depletion';
if (moveType === 'Psychic' && pokemonSpecies === 'Orbeetle-Gmax') return 'G-Max Gravitas';
if (moveType === 'Rock' && pokemonSpecies === 'Coalossal-Gmax') return 'G-Max Volcalith';
if (moveType === 'Ground' && pokemonSpecies === 'Sandaconda-Gmax') return 'G-Max Sandblast';
if (moveType === 'Dark' && pokemonSpecies === 'Grimmsnarl-Gmax') return 'G-Max Snooze';
if (moveType === 'Poison' && pokemonSpecies === 'Garbodor' && isGmax) return 'G-Max Malodor';
if (moveType === 'Fighting' && pokemonSpecies === 'Machamp' && isGmax) return 'G-Max Chi Strike';
if (moveType === 'Ghost' && pokemonSpecies === 'Gengar' && isGmax) return 'G-Max Terror';
if (moveType === 'Ice' && pokemonSpecies === 'Lapras' && isGmax) return 'G-Max Resonance';
if (moveType === 'Flying' && pokemonSpecies === 'Corviknight' && isGmax) return 'G-Max Wind Rage';
if (moveType === 'Dragon' && pokemonSpecies === 'Duraludon' && isGmax) return 'G-Max Depletion';
if (moveType === 'Psychic' && pokemonSpecies === 'Orbeetle' && isGmax) return 'G-Max Gravitas';
if (moveType === 'Rock' && pokemonSpecies === 'Coalossal' && isGmax) return 'G-Max Volcalith';
if (moveType === 'Ground' && pokemonSpecies === 'Sandaconda' && isGmax) return 'G-Max Sandblast';
if (moveType === 'Dark' && pokemonSpecies === 'Grimmsnarl' && isGmax) return 'G-Max Snooze';
return 'Max ' + MAXMOVES_TYPING[moveType];
}

Expand Down
2 changes: 1 addition & 1 deletion calc/src/pokemon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export class Pokemon implements State.Pokemon {
gender?: I.GenderName;
ability?: I.AbilityName;
abilityOn?: boolean;
isDynamaxed?: boolean;
isDynamaxed?: 'gmax' | boolean;
isSaltCure?: boolean;
alliesFainted?: number;
item?: I.ItemName;
Expand Down
3 changes: 2 additions & 1 deletion calc/src/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export namespace State {
level?: number;
ability?: I.AbilityName;
abilityOn?: boolean;
isDynamaxed?: boolean;
isDynamaxed?: 'gmax' | boolean;
isSaltCure?: boolean;
alliesFainted?: number;
item?: I.ItemName;
Expand All @@ -27,6 +27,7 @@ export namespace State {
name: I.MoveName;
useZ?: boolean;
useMax?: boolean;
isGmax?: boolean;
isCrit?: boolean;
hits?: number;
timesUsed?: number;
Expand Down
21 changes: 1 addition & 20 deletions calc/src/test/gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -324,30 +324,11 @@ class Specie implements I.Specie {
} else {
this.baseSpecies = 'Aegislash-Blade' as I.SpeciesName;
}
} else if (species.id === 'toxtricity') {
this.otherFormes = [
'Toxtricity-Gmax', 'Toxtricity-Low-Key', 'Toxtricity-Low-Key-Gmax',
] as I.SpeciesName[];
} else if (species.id === 'toxtricitylowkey') {
this.baseSpecies = 'Toxtricity' as I.SpeciesName;
} else if (species.id === 'urshifu') {
this.otherFormes = [
'Urshifu-Gmax', 'Urshifu-Rapid-Strike', 'Urshifu-Rapid-Strike-Gmax',
] as I.SpeciesName[];
} else if (species.id === 'eternatus') {
this.otherFormes = ['Eternatus-Eternamax'] as I.SpeciesName[];
} else if (formes?.length) {
this.otherFormes = [...formes].sort() as I.SpeciesName[];
} else if (species.baseSpecies !== this.name) {
this.baseSpecies = species.baseSpecies as I.SpeciesName;
}
// TODO: clean this up with proper Gigantamax support
if (dex.gen === 8 && species.canGigantamax &&
!(species.id.startsWith('toxtricity') || species.id.startsWith('urshifu'))) {
const formes = this.otherFormes || [];
const gmax = dex.species.get(`${species.name}-Gmax`);
if (exists(gmax, dex.gen)) this.otherFormes = [...formes, gmax.name].sort();
}

if (dex.gen > 2) this.abilities = {0: species.abilities[0] as I.AbilityName};
}
Expand Down Expand Up @@ -505,7 +486,7 @@ function exists(val: D.Ability| D.Item | D.Move | D.Species | D.Type, gen: I.Gen
}
if (gen >= 6 && ['floetteeternal'].includes(val.id)) return true;
// TODO: clean this up with proper Gigantamax support
if (val.isNonstandard && !['CAP', 'Unobtainable', 'Gigantamax'].includes(val.isNonstandard)) {
if (val.isNonstandard && !['CAP', 'Unobtainable'].includes(val.isNonstandard)) {
return false;
}
return !('tier' in val && ['Illegal', 'Unreleased'].includes(val.tier));
Expand Down
2 changes: 1 addition & 1 deletion calc/src/test/pokemon.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ describe('Pokemon', () => {

test('Gigantamx weights', () => {
expect(new Pokemon(8, 'Venusaur-Gmax').weightkg).toBe(100);
expect(new Pokemon(8, 'Venusaur-Gmax', {isDynamaxed: true}).weightkg).toBe(0);
expect(new Pokemon(8, 'Venusaur', {isDynamaxed: 'gmax'}).weightkg).toBe(0);
expect(new Pokemon(8, 'Venusaur-Gmax', {overrides: {weightkg: 50}}).weightkg).toBe(50);
});
});
2 changes: 0 additions & 2 deletions import/src/sets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,10 +171,8 @@ const FORMES: {[name: string]: string} = {
'Keldeo-Resolute': 'Keldeo',
};

// TODO handle Gmax
function toForme(pokemon: string) {
if (pokemon.endsWith('-Totem')) return pokemon.slice(0, -6);
if (pokemon.endsWith('-Gmax')) return pokemon.slice(0, -5);
return FORMES[pokemon] || pokemon;
}

Expand Down
8 changes: 8 additions & 0 deletions src/honkalculate.template.html
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,15 @@
<label>Current HP</label>
<input class="current-hp" value="341" />/<span class="max-hp">341</span> (
<input class="percent-hp" value="100" />%)
<<<<<<< HEAD
<input class="max calc-trigger btn-input" type="checkbox" id="maxL" /><label class="btn btn-wide gen-specific g8 g9" for="maxL" title="Use the corresponding Max Move?">Dynamax</label>
=======
<br />
<input class="max calc-trigger btn-input" type="checkbox" id="maxL" />
<label class="btn btn-wide gen-specific g8" for="maxL" title="Use the corresponding Max Move?">Dynamax</label>
<input class="gmax calc-trigger btn-input" type="checkbox" id="gmaxL" />
<label class="btn btn-xwide gen-specific g8" for="gmaxL" title="Use the G-Max forme instead?">Gigantamax</label>
>>>>>>> Implement Gigantamaxing properly
<br />
<br />
Health <div class="hpbar"></div>
Expand Down
18 changes: 18 additions & 0 deletions src/index.template.html
Original file line number Diff line number Diff line change
Expand Up @@ -501,10 +501,19 @@
<label for="currentHpL1">Current HP</label>
<input class="current-hp calc-trigger" id="currentHpL1" value="341" />/<span class="max-hp">341</span> (
<input class="percent-hp calc-trigger" value="100" />%)
<<<<<<< HEAD
<input class="visually-hidden max calc-trigger btn-input" type="checkbox" id="maxL" />
<label class="btn btn-xwide gen-specific g8 hide" for="maxL"
title="Use the corresponding Max Move?">Dynamax</label>
<br />
=======
<br />
<input class="visually-hidden max calc-trigger btn-input" type="checkbox" id="maxL" />
<label class="btn btn-wide gen-specific g8" for="maxL" title="Use the corresponding Max Move?">Dynamax</label>
<input class="visually-hidden gmax calc-trigger btn-input" type="checkbox" id="gmaxL" />
<label class="btn btn-xwide gen-specific g8" for="gmaxL" title="Use the G-Max forme instead?">Gigantamax</label>
<br />
>>>>>>> Implement Gigantamaxing properly
<br />
Health <div class="hpbar"></div>
</div>
Expand Down Expand Up @@ -1380,10 +1389,19 @@
<label for="currentHpR1">Current HP</label>
<input class="current-hp calc-trigger" id="currentHpR1" value="341" />/<span class="max-hp">341</span> (
<input class="percent-hp calc-trigger" value="100" />%)
<<<<<<< HEAD
<input class="visually-hidden max calc-trigger btn-input" type="checkbox" id="maxR" />
<label class="btn btn-xwide gen-specific g8 hide" for="maxR"
title="Use the corresponding Max Move?">Dynamax</label>
<br />
=======
<br />
<input class="visually-hidden max calc-trigger btn-input" type="checkbox" id="maxR" />
<label class="btn btn-wide gen-specific g8" for="maxR" title="Use the corresponding Max Move?">Dynamax</label>
<input class="visually-hidden gmax calc-trigger btn-input" type="checkbox" id="gmaxR" />
<label class="btn btn-xwide gen-specific g8" for="gmaxR" title="Use the G-Max forme instead?">Gigantamax</label>
<br />
>>>>>>> Implement Gigantamaxing properly
<br />
Health <div class="hpbar"></div>
</div>
Expand Down
4 changes: 4 additions & 0 deletions src/js/moveset_import.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ function ExportPokemon(pokeInfo) {
finalText += pokemon.nature && gen > 2 ? pokemon.nature + " Nature" + "\n" : "";
finalText += pokemon.teraType && gen > 8 ? "Tera Type: " + pokemon.teraType : "";
finalText += pokemon.ability ? "Ability: " + pokemon.ability + "\n" : "";
finalText += pokemon.isGigantamaxed ? "Gigantamax: Yes\n" : "";
if (gen > 2) {
var EVs_Array = [];
for (var stat in pokemon.evs) {
Expand Down Expand Up @@ -344,6 +345,9 @@ function checkExeptions(poke) {
poke = "Florges";
break;
}
if (poke.endsWith('-Gmax')) {
return poke.slice(0, -5);
}
return poke;

}
Expand Down
23 changes: 13 additions & 10 deletions src/js/shared_controls.js
Original file line number Diff line number Diff line change
Expand Up @@ -838,12 +838,15 @@ function createPokemon(pokeInfo) {
var ability = pokeInfo.find(".ability").val();
var item = pokeInfo.find(".item").val();
var isDynamaxed = pokeInfo.find(".max").prop("checked");
var isGigantamaxed = isDynamaxed && pokeInfo.find(".gmax").prop("checked");
var teraType = pokeInfo.find(".teraToggle").is(":checked") ? pokeInfo.find(".teraType").val() : undefined;
pokeInfo.isDynamaxed = isDynamaxed;
pokeInfo.isGigantamaxed = isGigantamaxed;
if (pokeInfo.isGigantamaxed) pokeInfo.isDynamaxed = true;
calcHP(pokeInfo);
var curHP = ~~pokeInfo.find(".current-hp").val();
// FIXME the Pokemon constructor expects non-dynamaxed HP
if (isDynamaxed) curHP = Math.floor(curHP / 2);
if (isDynamaxed || isGigantamaxed) curHP = Math.floor(curHP / 2);
var types = [pokeInfo.find(".type1").val(), pokeInfo.find(".type2").val()];
return new calc.Pokemon(gen, name, {
level: ~~pokeInfo.find(".level").val(),
Expand All @@ -854,7 +857,7 @@ function createPokemon(pokeInfo) {
nature: pokeInfo.find(".nature").val(),
ivs: ivs,
evs: evs,
isDynamaxed: isDynamaxed,
isDynamaxed: isGigantamaxed ? 'gmax' : !!isDynamaxed,
isSaltCure: pokeInfo.find(".saltcure").is(":checked"),
alliesFainted: parseInt(pokeInfo.find(".alliesFainted").val()),
teraType: teraType,
Expand All @@ -863,10 +866,10 @@ function createPokemon(pokeInfo) {
status: CALC_STATUS[pokeInfo.find(".status").val()],
toxicCounter: status === 'Badly Poisoned' ? ~~pokeInfo.find(".toxic-counter").val() : 0,
moves: [
getMoveDetails(pokeInfo.find(".move1"), name, ability, item, isDynamaxed),
getMoveDetails(pokeInfo.find(".move2"), name, ability, item, isDynamaxed),
getMoveDetails(pokeInfo.find(".move3"), name, ability, item, isDynamaxed),
getMoveDetails(pokeInfo.find(".move4"), name, ability, item, isDynamaxed)
getMoveDetails(pokeInfo.find(".move1"), name, ability, item, isDynamaxed, isGigantamaxed),
getMoveDetails(pokeInfo.find(".move2"), name, ability, item, isDynamaxed, isGigantamaxed),
getMoveDetails(pokeInfo.find(".move3"), name, ability, item, isDynamaxed, isGigantamaxed),
getMoveDetails(pokeInfo.find(".move4"), name, ability, item, isDynamaxed, isGigantamaxed)
],
overrides: {
baseStats: baseStats,
Expand All @@ -882,7 +885,7 @@ function getGender(gender) {
return 'F';
}

function getMoveDetails(moveInfo, species, ability, item, useMax) {
function getMoveDetails(moveInfo, species, ability, item, useMax, isGmax) {
var moveName = moveInfo.find("select.move-selector").val();
var isZMove = gen > 6 && moveInfo.find("input.move-z").prop("checked");
var isCrit = moveInfo.find(".move-crit").prop("checked");
Expand All @@ -895,8 +898,8 @@ function getMoveDetails(moveInfo, species, ability, item, useMax) {
};
if (gen >= 4) overrides.category = moveInfo.find(".move-cat").val();
return new calc.Move(gen, moveName, {
ability: ability, item: item, useZ: isZMove, species: species, isCrit: isCrit, hits: hits,
timesUsed: timesUsed, timesUsedWithMetronome: timesUsedWithMetronome, overrides: overrides, useMax: useMax
ability: ability, item: item, useZ: isZMove, species: species, isCrit: isCrit, hits: hits, timesUsed: timesUsed,
timesUsedWithMetronome: timesUsedWithMetronome, overrides: overrides, useMax: useMax, isGmax: isGmax
});
}

Expand Down Expand Up @@ -993,7 +996,7 @@ function calcStat(poke, StatID) {
}
// Shedinja still has 1 max HP during the effect even if its Dynamax Level is maxed (DaWoblefet)
var total = calc.calcStat(gen, legacyStatToStat(StatID), base, ivs, evs, level, nature);
if (gen > 7 && StatID === "hp" && poke.isDynamaxed && total !== 1) {
if (gen > 7 && StatID === "hp" && (poke.isDynamaxed || poke.isGigantamaxed) && total !== 1) {
total *= 2;
}
stat.find(".total").text(total);
Expand Down
Loading

0 comments on commit 7d8e97d

Please sign in to comment.