mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-08-19 22:09:27 +02:00
Introduced getSpeciesData
function
This commit is contained in:
parent
46c78a0540
commit
1ddcca7da5
@ -3,9 +3,11 @@ import { getRandomTrainerFunc } from "#app/battle";
|
|||||||
import { defaultStarterSpecies } from "#app/constants";
|
import { defaultStarterSpecies } from "#app/constants";
|
||||||
import { speciesStarterCosts } from "#balance/starters";
|
import { speciesStarterCosts } from "#balance/starters";
|
||||||
import type { PokemonSpecies } from "#data/pokemon-species";
|
import type { PokemonSpecies } from "#data/pokemon-species";
|
||||||
|
import { AbilityAttr } from "#enums/ability-attr";
|
||||||
import { BattleType } from "#enums/battle-type";
|
import { BattleType } from "#enums/battle-type";
|
||||||
import { Challenges } from "#enums/challenges";
|
import { Challenges } from "#enums/challenges";
|
||||||
import { TypeColor, TypeShadow } from "#enums/color";
|
import { TypeColor, TypeShadow } from "#enums/color";
|
||||||
|
import { DexAttr } from "#enums/dex-attr";
|
||||||
import { ClassicFixedBossWaves } from "#enums/fixed-boss-waves";
|
import { ClassicFixedBossWaves } from "#enums/fixed-boss-waves";
|
||||||
import { ModifierTier } from "#enums/modifier-tier";
|
import { ModifierTier } from "#enums/modifier-tier";
|
||||||
import { MoveId } from "#enums/move-id";
|
import { MoveId } from "#enums/move-id";
|
||||||
@ -19,8 +21,9 @@ import type { EnemyPokemon, PlayerPokemon, Pokemon } from "#field/pokemon";
|
|||||||
import { Trainer } from "#field/trainer";
|
import { Trainer } from "#field/trainer";
|
||||||
import type { ModifierTypeOption } from "#modifiers/modifier-type";
|
import type { ModifierTypeOption } from "#modifiers/modifier-type";
|
||||||
import { PokemonMove } from "#moves/pokemon-move";
|
import { PokemonMove } from "#moves/pokemon-move";
|
||||||
import type { DexAttrProps, GameData } from "#system/game-data";
|
import type { DexAttrProps, GameData, StarterDataEntry } from "#system/game-data";
|
||||||
import { RibbonData, type RibbonFlag } from "#system/ribbons/ribbon-data";
|
import { RibbonData, type RibbonFlag } from "#system/ribbons/ribbon-data";
|
||||||
|
import type { DexEntry } from "#types/dex-data";
|
||||||
import { type BooleanHolder, isBetween, type NumberHolder, randSeedItem } from "#utils/common";
|
import { type BooleanHolder, isBetween, type NumberHolder, randSeedItem } from "#utils/common";
|
||||||
import { deepCopy } from "#utils/data";
|
import { deepCopy } from "#utils/data";
|
||||||
import { getPokemonSpecies, getPokemonSpeciesForm } from "#utils/pokemon-utils";
|
import { getPokemonSpecies, getPokemonSpeciesForm } from "#utils/pokemon-utils";
|
||||||
@ -237,6 +240,15 @@ export abstract class Challenge {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An apply function for STARTER_SELECT_MODIFY challenges. Derived classes should alter this.
|
||||||
|
* @param _pokemon {@link Pokemon} The starter pokemon to modify.
|
||||||
|
* @returns {@link boolean} Whether this function did anything.
|
||||||
|
*/
|
||||||
|
applyStarterSelectModify(_dexEntry: DexEntry, _starterDataEntry: StarterDataEntry): boolean {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An apply function for STARTER_MODIFY challenges. Derived classes should alter this.
|
* An apply function for STARTER_MODIFY challenges. Derived classes should alter this.
|
||||||
* @param _pokemon {@link Pokemon} The starter pokemon to modify.
|
* @param _pokemon {@link Pokemon} The starter pokemon to modify.
|
||||||
@ -797,6 +809,53 @@ export class FreshStartChallenge extends Challenge {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
applyStarterSelectModify(dexEntry: DexEntry, starterDataEntry: StarterDataEntry): boolean {
|
||||||
|
// Remove all egg moves
|
||||||
|
starterDataEntry.eggMoves = 0;
|
||||||
|
console.log("I AM APPLYING, ", starterDataEntry.eggMoves);
|
||||||
|
|
||||||
|
// Remove hidden and passive ability
|
||||||
|
const defaultAbilities = AbilityAttr.ABILITY_1 | AbilityAttr.ABILITY_2;
|
||||||
|
starterDataEntry.abilityAttr &= defaultAbilities;
|
||||||
|
starterDataEntry.passiveAttr = 0;
|
||||||
|
|
||||||
|
// Remove cost reduction
|
||||||
|
starterDataEntry.valueReduction = 0;
|
||||||
|
|
||||||
|
// Remove natures except for the default ones
|
||||||
|
const neutralNaturesAttr =
|
||||||
|
(1 << (Nature.HARDY + 1)) |
|
||||||
|
(1 << (Nature.DOCILE + 1)) |
|
||||||
|
(1 << (Nature.SERIOUS + 1)) |
|
||||||
|
(1 << (Nature.BASHFUL + 1)) |
|
||||||
|
(1 << (Nature.QUIRKY + 1));
|
||||||
|
dexEntry.natureAttr &= neutralNaturesAttr;
|
||||||
|
|
||||||
|
// Set all ivs to 15
|
||||||
|
dexEntry.ivs = [15, 15, 15, 15, 15, 15];
|
||||||
|
|
||||||
|
// Removes shiny, variants, and any unlocked forms
|
||||||
|
const defaultDexEntry = DexAttr.NON_SHINY | DexAttr.MALE | DexAttr.FEMALE | DexAttr.DEFAULT_FORM;
|
||||||
|
dexEntry.caughtAttr &= defaultDexEntry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
let validMoves = pokemon.species
|
||||||
|
.getLevelMoves()
|
||||||
|
.filter(m => isBetween(m[0], 1, 5))
|
||||||
|
.map(lm => lm[1]);
|
||||||
|
// Filter egg moves out of the moveset
|
||||||
|
pokemon.moveset = pokemon.moveset.filter(pm => validMoves.includes(pm.moveId));
|
||||||
|
if (pokemon.moveset.length < 4) {
|
||||||
|
// If there's empty slots fill with remaining valid moves
|
||||||
|
const existingMoveIds = pokemon.moveset.map(pm => pm.moveId);
|
||||||
|
validMoves = validMoves.filter(m => !existingMoveIds.includes(m));
|
||||||
|
pokemon.moveset = pokemon.moveset.concat(validMoves.map(m => new PokemonMove(m))).slice(0, 4);
|
||||||
|
}
|
||||||
|
pokemon.teraType = pokemon.species.type1; // Always primary tera type
|
||||||
|
*/
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
applyStarterModify(pokemon: Pokemon): boolean {
|
applyStarterModify(pokemon: Pokemon): boolean {
|
||||||
pokemon.abilityIndex = pokemon.abilityIndex % 2; // Always base ability, if you set it to hidden it wraps to first ability
|
pokemon.abilityIndex = pokemon.abilityIndex % 2; // Always base ability, if you set it to hidden it wraps to first ability
|
||||||
pokemon.passive = false; // Passive isn't unlocked
|
pokemon.passive = false; // Passive isn't unlocked
|
||||||
|
@ -18,6 +18,11 @@ export enum ChallengeType {
|
|||||||
* @see {@link Challenge.applyStarterPointCost}
|
* @see {@link Challenge.applyStarterPointCost}
|
||||||
*/
|
*/
|
||||||
STARTER_COST,
|
STARTER_COST,
|
||||||
|
/**
|
||||||
|
* Challenges which modify the starter data in starter select
|
||||||
|
* @see {@link Challenge.applyStarterSelectModify}
|
||||||
|
*/
|
||||||
|
STARTER_SELECT_MODIFY,
|
||||||
/**
|
/**
|
||||||
* Challenges which modify your starters in some way
|
* Challenges which modify your starters in some way
|
||||||
* @see {@link Challenge.applyStarterModify}
|
* @see {@link Challenge.applyStarterModify}
|
||||||
|
@ -64,7 +64,7 @@ import { trainerConfigs } from "#trainers/trainer-config";
|
|||||||
import type { DexData, DexEntry } from "#types/dex-data";
|
import type { DexData, DexEntry } from "#types/dex-data";
|
||||||
import { RUN_HISTORY_LIMIT } from "#ui/run-history-ui-handler";
|
import { RUN_HISTORY_LIMIT } from "#ui/run-history-ui-handler";
|
||||||
import { applyChallenges } from "#utils/challenge-utils";
|
import { applyChallenges } from "#utils/challenge-utils";
|
||||||
import { executeIf, fixedInt, isLocal, NumberHolder, randInt, randSeedItem } from "#utils/common";
|
import { executeIf, fixedInt, isLocal, isNullOrUndefined, NumberHolder, randInt, randSeedItem } from "#utils/common";
|
||||||
import { decrypt, encrypt } from "#utils/data";
|
import { decrypt, encrypt } from "#utils/data";
|
||||||
import { getEnumKeys } from "#utils/enums";
|
import { getEnumKeys } from "#utils/enums";
|
||||||
import { getPokemonSpecies } from "#utils/pokemon-utils";
|
import { getPokemonSpecies } from "#utils/pokemon-utils";
|
||||||
@ -2103,8 +2103,10 @@ export class GameData {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
getStarterSpeciesDefaultAbilityIndex(species: PokemonSpecies): number {
|
getStarterSpeciesDefaultAbilityIndex(species: PokemonSpecies, abilityAttr?: number): number {
|
||||||
const abilityAttr = this.starterData[species.speciesId].abilityAttr;
|
if (isNullOrUndefined(abilityAttr)) {
|
||||||
|
abilityAttr = this.starterData[species.speciesId].abilityAttr;
|
||||||
|
}
|
||||||
return abilityAttr & AbilityAttr.ABILITY_1 ? 0 : !species.ability2 || abilityAttr & AbilityAttr.ABILITY_2 ? 1 : 2;
|
return abilityAttr & AbilityAttr.ABILITY_1 ? 0 : !species.ability2 || abilityAttr & AbilityAttr.ABILITY_2 ? 1 : 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ import { BattleSceneEventType } from "#events/battle-scene";
|
|||||||
import type { Variant } from "#sprites/variant";
|
import type { Variant } from "#sprites/variant";
|
||||||
import { getVariantIcon, getVariantTint } from "#sprites/variant";
|
import { getVariantIcon, getVariantTint } from "#sprites/variant";
|
||||||
import { achvs } from "#system/achv";
|
import { achvs } from "#system/achv";
|
||||||
import type { DexAttrProps, StarterAttributes, StarterMoveset } from "#system/game-data";
|
import type { DexAttrProps, StarterAttributes, StarterDataEntry, StarterMoveset } from "#system/game-data";
|
||||||
import { RibbonData } from "#system/ribbons/ribbon-data";
|
import { RibbonData } from "#system/ribbons/ribbon-data";
|
||||||
import { SettingKeyboard } from "#system/settings-keyboard";
|
import { SettingKeyboard } from "#system/settings-keyboard";
|
||||||
import type { DexEntry } from "#types/dex-data";
|
import type { DexEntry } from "#types/dex-data";
|
||||||
@ -1141,7 +1141,7 @@ export class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
|
|
||||||
this.allSpecies.forEach((species, s) => {
|
this.allSpecies.forEach((species, s) => {
|
||||||
const icon = this.starterContainers[s].icon;
|
const icon = this.starterContainers[s].icon;
|
||||||
const dexEntry = globalScene.gameData.dexData[species.speciesId];
|
const { dexEntry } = this.getSpeciesData(species.speciesId);
|
||||||
|
|
||||||
// Initialize the StarterAttributes for this species
|
// Initialize the StarterAttributes for this species
|
||||||
this.starterPreferences[species.speciesId] = this.initStarterPrefs(species);
|
this.starterPreferences[species.speciesId] = this.initStarterPrefs(species);
|
||||||
@ -1714,7 +1714,8 @@ export class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
globalScene.gameData.getSpeciesDexAttrProps(species, this.getCurrentDexProps(species.speciesId)),
|
globalScene.gameData.getSpeciesDexAttrProps(species, this.getCurrentDexProps(species.speciesId)),
|
||||||
this.isPartyValid(),
|
this.isPartyValid(),
|
||||||
);
|
);
|
||||||
const isCaught = globalScene.gameData.dexData[species.speciesId].caughtAttr;
|
const { dexEntry } = this.getSpeciesData(species.speciesId);
|
||||||
|
const isCaught = dexEntry.caughtAttr;
|
||||||
return (
|
return (
|
||||||
!isDupe && isValidForChallenge && currentPartyValue + starterCost <= this.getValueLimit() && isCaught
|
!isDupe && isValidForChallenge && currentPartyValue + starterCost <= this.getValueLimit() && isCaught
|
||||||
);
|
);
|
||||||
@ -2994,8 +2995,9 @@ export class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
container.cost = globalScene.gameData.getSpeciesStarterValue(container.species.speciesId);
|
container.cost = globalScene.gameData.getSpeciesStarterValue(container.species.speciesId);
|
||||||
|
|
||||||
// First, ensure you have the caught attributes for the species else default to bigint 0
|
// First, ensure you have the caught attributes for the species else default to bigint 0
|
||||||
const caughtAttr = globalScene.gameData.dexData[container.species.speciesId]?.caughtAttr || BigInt(0);
|
const { dexEntry, starterDataEntry } = this.getSpeciesData(container.species.speciesId);
|
||||||
const starterData = globalScene.gameData.starterData[container.species.speciesId];
|
const caughtAttr = dexEntry?.caughtAttr || BigInt(0);
|
||||||
|
const starterData = starterDataEntry;
|
||||||
const isStarterProgressable = speciesEggMoves.hasOwnProperty(container.species.speciesId);
|
const isStarterProgressable = speciesEggMoves.hasOwnProperty(container.species.speciesId);
|
||||||
|
|
||||||
// Gen filter
|
// Gen filter
|
||||||
@ -3393,7 +3395,11 @@ export class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setSpecies(species: PokemonSpecies | null) {
|
setSpecies(species: PokemonSpecies | null) {
|
||||||
this.speciesStarterDexEntry = species ? globalScene.gameData.dexData[species.speciesId] : null;
|
this.speciesStarterDexEntry = null;
|
||||||
|
if (species) {
|
||||||
|
const { dexEntry } = this.getSpeciesData(species.speciesId);
|
||||||
|
this.speciesStarterDexEntry = dexEntry;
|
||||||
|
}
|
||||||
this.dexAttrCursor = species ? this.getCurrentDexProps(species.speciesId) : 0n;
|
this.dexAttrCursor = species ? this.getCurrentDexProps(species.speciesId) : 0n;
|
||||||
this.abilityCursor = species ? globalScene.gameData.getStarterSpeciesDefaultAbilityIndex(species) : 0;
|
this.abilityCursor = species ? globalScene.gameData.getStarterSpeciesDefaultAbilityIndex(species) : 0;
|
||||||
this.natureCursor = species ? globalScene.gameData.getSpeciesDefaultNature(species) : 0;
|
this.natureCursor = species ? globalScene.gameData.getSpeciesDefaultNature(species) : 0;
|
||||||
@ -3663,6 +3669,17 @@ export class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getSpeciesData(speciesId: SpeciesId): { dexEntry: DexEntry; starterDataEntry: StarterDataEntry } {
|
||||||
|
const dexEntry = globalScene.gameData.dexData[speciesId];
|
||||||
|
const starterDataEntry = globalScene.gameData.starterData[speciesId];
|
||||||
|
|
||||||
|
const copiedDexEntry = { ...dexEntry };
|
||||||
|
const copiedStarterDataEntry = { ...starterDataEntry };
|
||||||
|
applyChallenges(ChallengeType.STARTER_SELECT_MODIFY, copiedDexEntry, copiedStarterDataEntry);
|
||||||
|
|
||||||
|
return { dexEntry: { ...copiedDexEntry }, starterDataEntry: { ...copiedStarterDataEntry } };
|
||||||
|
}
|
||||||
|
|
||||||
setSpeciesDetails(species: PokemonSpecies, options: SpeciesDetails = {}): void {
|
setSpeciesDetails(species: PokemonSpecies, options: SpeciesDetails = {}): void {
|
||||||
let { shiny, formIndex, female, variant, abilityIndex, natureIndex, teraType } = options;
|
let { shiny, formIndex, female, variant, abilityIndex, natureIndex, teraType } = options;
|
||||||
const forSeen: boolean = options.forSeen ?? false;
|
const forSeen: boolean = options.forSeen ?? false;
|
||||||
@ -3740,12 +3757,12 @@ export class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
this.speciesStarterMoves = [];
|
this.speciesStarterMoves = [];
|
||||||
|
|
||||||
if (species) {
|
if (species) {
|
||||||
const dexEntry = globalScene.gameData.dexData[species.speciesId];
|
const { dexEntry, starterDataEntry } = this.getSpeciesData(species.speciesId);
|
||||||
const abilityAttr = globalScene.gameData.starterData[species.speciesId].abilityAttr;
|
const caughtAttr = dexEntry.caughtAttr || BigInt(0);
|
||||||
|
const abilityAttr = starterDataEntry.abilityAttr;
|
||||||
|
console.log("I HAVE APPLIED, ", starterDataEntry.eggMoves);
|
||||||
|
|
||||||
const caughtAttr = globalScene.gameData.dexData[species.speciesId]?.caughtAttr || BigInt(0);
|
if (!caughtAttr) {
|
||||||
|
|
||||||
if (!dexEntry.caughtAttr) {
|
|
||||||
const props = globalScene.gameData.getSpeciesDexAttrProps(species, this.getCurrentDexProps(species.speciesId));
|
const props = globalScene.gameData.getSpeciesDexAttrProps(species, this.getCurrentDexProps(species.speciesId));
|
||||||
const defaultAbilityIndex = globalScene.gameData.getStarterSpeciesDefaultAbilityIndex(species);
|
const defaultAbilityIndex = globalScene.gameData.getStarterSpeciesDefaultAbilityIndex(species);
|
||||||
const defaultNature = globalScene.gameData.getSpeciesDefaultNature(species);
|
const defaultNature = globalScene.gameData.getSpeciesDefaultNature(species);
|
||||||
@ -4382,7 +4399,8 @@ export class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
*/
|
*/
|
||||||
getCurrentDexProps(speciesId: number): bigint {
|
getCurrentDexProps(speciesId: number): bigint {
|
||||||
let props = 0n;
|
let props = 0n;
|
||||||
const caughtAttr = globalScene.gameData.dexData[speciesId].caughtAttr;
|
const { dexEntry } = this.getSpeciesData(speciesId);
|
||||||
|
const caughtAttr = dexEntry.caughtAttr;
|
||||||
|
|
||||||
/* this checks the gender of the pokemon; this works by checking a) that the starter preferences for the species exist, and if so, is it female. If so, it'll add DexAttr.FEMALE to our temp props
|
/* this checks the gender of the pokemon; this works by checking a) that the starter preferences for the species exist, and if so, is it female. If so, it'll add DexAttr.FEMALE to our temp props
|
||||||
* It then checks b) if the caughtAttr for the pokemon is female and NOT male - this means that the ONLY gender we've gotten is female, and we need to add DexAttr.FEMALE to our temp props
|
* It then checks b) if the caughtAttr for the pokemon is female and NOT male - this means that the ONLY gender we've gotten is female, and we need to add DexAttr.FEMALE to our temp props
|
||||||
|
@ -10,7 +10,8 @@ import type { MoveSourceType } from "#enums/move-source-type";
|
|||||||
import type { SpeciesId } from "#enums/species-id";
|
import type { SpeciesId } from "#enums/species-id";
|
||||||
import type { EnemyPokemon, PlayerPokemon, Pokemon } from "#field/pokemon";
|
import type { EnemyPokemon, PlayerPokemon, Pokemon } from "#field/pokemon";
|
||||||
import type { ModifierTypeOption } from "#modifiers/modifier-type";
|
import type { ModifierTypeOption } from "#modifiers/modifier-type";
|
||||||
import type { DexAttrProps } from "#system/game-data";
|
import type { DexAttrProps, StarterDataEntry } from "#system/game-data";
|
||||||
|
import type { DexEntry } from "#types/dex-data";
|
||||||
import { BooleanHolder, type NumberHolder } from "./common";
|
import { BooleanHolder, type NumberHolder } from "./common";
|
||||||
import { getPokemonSpecies } from "./pokemon-utils";
|
import { getPokemonSpecies } from "./pokemon-utils";
|
||||||
|
|
||||||
@ -47,6 +48,18 @@ export function applyChallenges(
|
|||||||
species: SpeciesId,
|
species: SpeciesId,
|
||||||
cost: NumberHolder,
|
cost: NumberHolder,
|
||||||
): boolean;
|
): boolean;
|
||||||
|
/**
|
||||||
|
* Apply all challenges that modify selectable starter data.
|
||||||
|
* @param challengeType {@link ChallengeType} ChallengeType.STARTER_SELECT_MODIFY
|
||||||
|
* @param dexEntry {@link DexEntry} The pokedex data associated to the pokemon.
|
||||||
|
* @param starterDataEntry {@link StarterDataEntry} The starter data associated to the pokemon.
|
||||||
|
* @returns True if any challenge was successfully applied.
|
||||||
|
*/
|
||||||
|
export function applyChallenges(
|
||||||
|
challengeType: ChallengeType.STARTER_SELECT_MODIFY,
|
||||||
|
dexEntry: DexEntry,
|
||||||
|
starterDataEntry: StarterDataEntry,
|
||||||
|
): boolean;
|
||||||
/**
|
/**
|
||||||
* Apply all challenges that modify a starter after selection.
|
* Apply all challenges that modify a starter after selection.
|
||||||
* @param challengeType {@link ChallengeType} ChallengeType.STARTER_MODIFY
|
* @param challengeType {@link ChallengeType} ChallengeType.STARTER_MODIFY
|
||||||
@ -269,6 +282,9 @@ export function applyChallenges(challengeType: ChallengeType, ...args: any[]): b
|
|||||||
case ChallengeType.STARTER_COST:
|
case ChallengeType.STARTER_COST:
|
||||||
ret ||= c.applyStarterCost(args[0], args[1]);
|
ret ||= c.applyStarterCost(args[0], args[1]);
|
||||||
break;
|
break;
|
||||||
|
case ChallengeType.STARTER_SELECT_MODIFY:
|
||||||
|
ret ||= c.applyStarterSelectModify(args[0], args[1]);
|
||||||
|
break;
|
||||||
case ChallengeType.STARTER_MODIFY:
|
case ChallengeType.STARTER_MODIFY:
|
||||||
ret ||= c.applyStarterModify(args[0]);
|
ret ||= c.applyStarterModify(args[0]);
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user