mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-08-21 06:49:35 +02:00
Create Nuzlocke-related challenges
- "No Free Heal": Disables the automatic healing that occurs after every 10th wave, replacing it with a normal shop phase - "Hardcore": Fainted Pokémon can't be revived - "Limited Catch": Only the first wild Pokémon encounter of every biome can be added to your current party
This commit is contained in:
parent
414e0a5447
commit
df73978bb4
File diff suppressed because it is too large
Load Diff
@ -5,4 +5,7 @@ export enum Challenges {
|
|||||||
LOWER_STARTER_POINTS,
|
LOWER_STARTER_POINTS,
|
||||||
FRESH_START,
|
FRESH_START,
|
||||||
INVERSE_BATTLE,
|
INVERSE_BATTLE,
|
||||||
|
NO_AUTO_HEAL,
|
||||||
|
HARDCORE,
|
||||||
|
LIMITED_CATCH,
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ import BattleScene from "#app/battle-scene";
|
|||||||
import { EvolutionItem, pokemonEvolutions } from "#app/data/balance/pokemon-evolutions";
|
import { EvolutionItem, pokemonEvolutions } from "#app/data/balance/pokemon-evolutions";
|
||||||
import { tmPoolTiers, tmSpecies } from "#app/data/balance/tms";
|
import { tmPoolTiers, tmSpecies } from "#app/data/balance/tms";
|
||||||
import { getBerryEffectDescription, getBerryName } from "#app/data/berry";
|
import { getBerryEffectDescription, getBerryName } from "#app/data/berry";
|
||||||
|
import { applyChallenges, ChallengeType } from "#app/data/challenge";
|
||||||
import { allMoves, AttackMove, selfStatLowerMoves } from "#app/data/move";
|
import { allMoves, AttackMove, selfStatLowerMoves } from "#app/data/move";
|
||||||
import { getNatureName, getNatureStatMultiplier, Nature } from "#app/data/nature";
|
import { getNatureName, getNatureStatMultiplier, Nature } from "#app/data/nature";
|
||||||
import { getPokeballCatchMultiplier, getPokeballName, MAX_PER_TYPE_POKEBALLS, PokeballType } from "#app/data/pokeball";
|
import { getPokeballCatchMultiplier, getPokeballName, MAX_PER_TYPE_POKEBALLS, PokeballType } from "#app/data/pokeball";
|
||||||
@ -9,6 +10,7 @@ import { FormChangeItem, pokemonFormChanges, SpeciesFormChangeCondition, Species
|
|||||||
import { getStatusEffectDescriptor, StatusEffect } from "#app/data/status-effect";
|
import { getStatusEffectDescriptor, StatusEffect } from "#app/data/status-effect";
|
||||||
import { Type } from "#app/data/type";
|
import { Type } from "#app/data/type";
|
||||||
import Pokemon, { EnemyPokemon, PlayerPokemon, PokemonMove } from "#app/field/pokemon";
|
import Pokemon, { EnemyPokemon, PlayerPokemon, PokemonMove } from "#app/field/pokemon";
|
||||||
|
import { GameMode } from "#app/game-mode";
|
||||||
import { getPokemonNameWithAffix } from "#app/messages";
|
import { getPokemonNameWithAffix } from "#app/messages";
|
||||||
import {
|
import {
|
||||||
AddPokeballModifier, AddVoucherModifier, AttackTypeBoosterModifier, BaseStatModifier, BerryModifier, BoostBugSpawnModifier, BypassSpeedChanceModifier, ContactHeldItemTransferChanceModifier, CritBoosterModifier, DamageMoneyRewardModifier, DoubleBattleChanceBoosterModifier, EnemyAttackStatusEffectChanceModifier, EnemyDamageBoosterModifier, EnemyDamageReducerModifier, EnemyEndureChanceModifier, EnemyFusionChanceModifier, EnemyStatusEffectHealChanceModifier, EnemyTurnHealModifier, EvolutionItemModifier, EvolutionStatBoosterModifier, EvoTrackerModifier, ExpBalanceModifier, ExpBoosterModifier, ExpShareModifier, ExtraModifierModifier, FlinchChanceModifier, FusePokemonModifier, GigantamaxAccessModifier, HealingBoosterModifier, HealShopCostModifier, HiddenAbilityRateBoosterModifier, HitHealModifier, IvScannerModifier, LevelIncrementBoosterModifier, LockModifierTiersModifier, MapModifier, MegaEvolutionAccessModifier, MoneyInterestModifier, MoneyMultiplierModifier, MoneyRewardModifier, MultipleParticipantExpBonusModifier, PokemonAllMovePpRestoreModifier, PokemonBaseStatFlatModifier, PokemonBaseStatTotalModifier, PokemonExpBoosterModifier, PokemonFormChangeItemModifier, PokemonFriendshipBoosterModifier, PokemonHeldItemModifier, PokemonHpRestoreModifier, PokemonIncrementingStatModifier, PokemonInstantReviveModifier, PokemonLevelIncrementModifier, PokemonMoveAccuracyBoosterModifier, PokemonMultiHitModifier, PokemonNatureChangeModifier, PokemonNatureWeightModifier, PokemonPpRestoreModifier, PokemonPpUpModifier, PokemonStatusHealModifier, PreserveBerryModifier, RememberMoveModifier, ResetNegativeStatStageModifier, ShinyRateBoosterModifier, SpeciesCritBoosterModifier, SpeciesStatBoosterModifier, SurviveDamageModifier, SwitchEffectTransferModifier, TempCritBoosterModifier, TempStatStageBoosterModifier, TerastallizeAccessModifier, TerastallizeModifier, TmModifier, TurnHealModifier, TurnHeldItemTransferModifier, TurnStatusEffectModifier, type EnemyPersistentModifier, type Modifier, type PersistentModifier, TempExtraModifierModifier
|
AddPokeballModifier, AddVoucherModifier, AttackTypeBoosterModifier, BaseStatModifier, BerryModifier, BoostBugSpawnModifier, BypassSpeedChanceModifier, ContactHeldItemTransferChanceModifier, CritBoosterModifier, DamageMoneyRewardModifier, DoubleBattleChanceBoosterModifier, EnemyAttackStatusEffectChanceModifier, EnemyDamageBoosterModifier, EnemyDamageReducerModifier, EnemyEndureChanceModifier, EnemyFusionChanceModifier, EnemyStatusEffectHealChanceModifier, EnemyTurnHealModifier, EvolutionItemModifier, EvolutionStatBoosterModifier, EvoTrackerModifier, ExpBalanceModifier, ExpBoosterModifier, ExpShareModifier, ExtraModifierModifier, FlinchChanceModifier, FusePokemonModifier, GigantamaxAccessModifier, HealingBoosterModifier, HealShopCostModifier, HiddenAbilityRateBoosterModifier, HitHealModifier, IvScannerModifier, LevelIncrementBoosterModifier, LockModifierTiersModifier, MapModifier, MegaEvolutionAccessModifier, MoneyInterestModifier, MoneyMultiplierModifier, MoneyRewardModifier, MultipleParticipantExpBonusModifier, PokemonAllMovePpRestoreModifier, PokemonBaseStatFlatModifier, PokemonBaseStatTotalModifier, PokemonExpBoosterModifier, PokemonFormChangeItemModifier, PokemonFriendshipBoosterModifier, PokemonHeldItemModifier, PokemonHpRestoreModifier, PokemonIncrementingStatModifier, PokemonInstantReviveModifier, PokemonLevelIncrementModifier, PokemonMoveAccuracyBoosterModifier, PokemonMultiHitModifier, PokemonNatureChangeModifier, PokemonNatureWeightModifier, PokemonPpRestoreModifier, PokemonPpUpModifier, PokemonStatusHealModifier, PreserveBerryModifier, RememberMoveModifier, ResetNegativeStatStageModifier, ShinyRateBoosterModifier, SpeciesCritBoosterModifier, SpeciesStatBoosterModifier, SurviveDamageModifier, SwitchEffectTransferModifier, TempCritBoosterModifier, TempStatStageBoosterModifier, TerastallizeAccessModifier, TerastallizeModifier, TmModifier, TurnHealModifier, TurnHeldItemTransferModifier, TurnStatusEffectModifier, type EnemyPersistentModifier, type Modifier, type PersistentModifier, TempExtraModifierModifier
|
||||||
@ -19,7 +21,7 @@ import { Unlockables } from "#app/system/unlockables";
|
|||||||
import { getVoucherTypeIcon, getVoucherTypeName, VoucherType } from "#app/system/voucher";
|
import { getVoucherTypeIcon, getVoucherTypeName, VoucherType } from "#app/system/voucher";
|
||||||
import PartyUiHandler, { PokemonMoveSelectFilter, PokemonSelectFilter } from "#app/ui/party-ui-handler";
|
import PartyUiHandler, { PokemonMoveSelectFilter, PokemonSelectFilter } from "#app/ui/party-ui-handler";
|
||||||
import { getModifierTierTextTint } from "#app/ui/text";
|
import { getModifierTierTextTint } from "#app/ui/text";
|
||||||
import { formatMoney, getEnumKeys, getEnumValues, IntegerHolder, NumberHolder, padInt, randSeedInt, randSeedItem } from "#app/utils";
|
import { BooleanHolder, formatMoney, getEnumKeys, getEnumValues, IntegerHolder, NumberHolder, padInt, randSeedInt, randSeedItem } from "#app/utils";
|
||||||
import { Abilities } from "#enums/abilities";
|
import { Abilities } from "#enums/abilities";
|
||||||
import { BattlerTagType } from "#enums/battler-tag-type";
|
import { BattlerTagType } from "#enums/battler-tag-type";
|
||||||
import { BerryType } from "#enums/berry-type";
|
import { BerryType } from "#enums/berry-type";
|
||||||
@ -144,7 +146,7 @@ export class ModifierType {
|
|||||||
type ModifierTypeGeneratorFunc = (party: Pokemon[], pregenArgs?: any[]) => ModifierType | null;
|
type ModifierTypeGeneratorFunc = (party: Pokemon[], pregenArgs?: any[]) => ModifierType | null;
|
||||||
|
|
||||||
export class ModifierTypeGenerator extends ModifierType {
|
export class ModifierTypeGenerator extends ModifierType {
|
||||||
private genTypeFunc: ModifierTypeGeneratorFunc;
|
private genTypeFunc: ModifierTypeGeneratorFunc;
|
||||||
|
|
||||||
constructor(genTypeFunc: ModifierTypeGeneratorFunc) {
|
constructor(genTypeFunc: ModifierTypeGeneratorFunc) {
|
||||||
super(null, null, null);
|
super(null, null, null);
|
||||||
@ -873,7 +875,7 @@ export class FormChangeItemModifierType extends PokemonModifierType implements G
|
|||||||
if (pokemonFormChanges.hasOwnProperty(pokemon.species.speciesId)
|
if (pokemonFormChanges.hasOwnProperty(pokemon.species.speciesId)
|
||||||
// Get all form changes for this species with an item trigger, including any compound triggers
|
// Get all form changes for this species with an item trigger, including any compound triggers
|
||||||
&& pokemonFormChanges[pokemon.species.speciesId].filter(fc => fc.trigger.hasTriggerType(SpeciesFormChangeItemTrigger) && (fc.preFormKey === pokemon.getFormKey()))
|
&& pokemonFormChanges[pokemon.species.speciesId].filter(fc => fc.trigger.hasTriggerType(SpeciesFormChangeItemTrigger) && (fc.preFormKey === pokemon.getFormKey()))
|
||||||
// Returns true if any form changes match this item
|
// Returns true if any form changes match this item
|
||||||
.map(fc => fc.findTrigger(SpeciesFormChangeItemTrigger) as SpeciesFormChangeItemTrigger)
|
.map(fc => fc.findTrigger(SpeciesFormChangeItemTrigger) as SpeciesFormChangeItemTrigger)
|
||||||
.flat().flatMap(fc => fc.item).includes(this.formChangeItem)
|
.flat().flatMap(fc => fc.item).includes(this.formChangeItem)
|
||||||
) {
|
) {
|
||||||
@ -1272,7 +1274,7 @@ type WeightedModifierTypeWeightFunc = (party: Pokemon[], rerollCount?: integer)
|
|||||||
*/
|
*/
|
||||||
function skipInClassicAfterWave(wave: integer, defaultWeight: integer): WeightedModifierTypeWeightFunc {
|
function skipInClassicAfterWave(wave: integer, defaultWeight: integer): WeightedModifierTypeWeightFunc {
|
||||||
return (party: Pokemon[]) => {
|
return (party: Pokemon[]) => {
|
||||||
const gameMode = party[0].scene.gameMode;
|
const gameMode = party[0].scene.gameMode;
|
||||||
const currentWave = party[0].scene.currentBattle.waveIndex;
|
const currentWave = party[0].scene.currentBattle.waveIndex;
|
||||||
return gameMode.isClassic && currentWave >= wave ? 0 : defaultWeight;
|
return gameMode.isClassic && currentWave >= wave ? 0 : defaultWeight;
|
||||||
};
|
};
|
||||||
@ -1284,7 +1286,7 @@ function skipInClassicAfterWave(wave: integer, defaultWeight: integer): Weighted
|
|||||||
* @param defaultWeight ModifierType default weight
|
* @param defaultWeight ModifierType default weight
|
||||||
* @returns A WeightedModifierTypeWeightFunc
|
* @returns A WeightedModifierTypeWeightFunc
|
||||||
*/
|
*/
|
||||||
function skipInLastClassicWaveOrDefault(defaultWeight: integer) : WeightedModifierTypeWeightFunc {
|
function skipInLastClassicWaveOrDefault(defaultWeight: number): WeightedModifierTypeWeightFunc {
|
||||||
return skipInClassicAfterWave(199, defaultWeight);
|
return skipInClassicAfterWave(199, defaultWeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1302,7 +1304,7 @@ function lureWeightFunc(maxBattles: number, weight: number): WeightedModifierTyp
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
class WeightedModifierType {
|
export class WeightedModifierType {
|
||||||
public modifierType: ModifierType;
|
public modifierType: ModifierType;
|
||||||
public weight: integer | WeightedModifierTypeWeightFunc;
|
public weight: integer | WeightedModifierTypeWeightFunc;
|
||||||
public maxWeight: integer;
|
public maxWeight: integer;
|
||||||
@ -1598,7 +1600,7 @@ export const modifierTypes = {
|
|||||||
MYSTERY_ENCOUNTER_GOLDEN_BUG_NET: () => new ModifierType("modifierType:ModifierType.MYSTERY_ENCOUNTER_GOLDEN_BUG_NET", "golden_net", (type, _args) => new BoostBugSpawnModifier(type)),
|
MYSTERY_ENCOUNTER_GOLDEN_BUG_NET: () => new ModifierType("modifierType:ModifierType.MYSTERY_ENCOUNTER_GOLDEN_BUG_NET", "golden_net", (type, _args) => new BoostBugSpawnModifier(type)),
|
||||||
};
|
};
|
||||||
|
|
||||||
interface ModifierPool {
|
export interface ModifierPool {
|
||||||
[tier: string]: WeightedModifierType[]
|
[tier: string]: WeightedModifierType[]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1910,10 +1912,10 @@ const enemyBuffModifierPool: ModifierPool = {
|
|||||||
].map(m => {
|
].map(m => {
|
||||||
m.setTier(ModifierTier.ULTRA); return m;
|
m.setTier(ModifierTier.ULTRA); return m;
|
||||||
}),
|
}),
|
||||||
[ModifierTier.ROGUE]: [ ].map((m: WeightedModifierType) => {
|
[ModifierTier.ROGUE]: [].map((m: WeightedModifierType) => {
|
||||||
m.setTier(ModifierTier.ROGUE); return m;
|
m.setTier(ModifierTier.ROGUE); return m;
|
||||||
}),
|
}),
|
||||||
[ModifierTier.MASTER]: [ ].map((m: WeightedModifierType) => {
|
[ModifierTier.MASTER]: [].map((m: WeightedModifierType) => {
|
||||||
m.setTier(ModifierTier.MASTER); return m;
|
m.setTier(ModifierTier.MASTER); return m;
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
@ -2018,7 +2020,7 @@ export function regenerateModifierPoolThresholds(party: Pokemon[], poolType: Mod
|
|||||||
let tierMaxWeight = 0;
|
let tierMaxWeight = 0;
|
||||||
let i = 0;
|
let i = 0;
|
||||||
pool[t].reduce((total: integer, modifierType: WeightedModifierType) => {
|
pool[t].reduce((total: integer, modifierType: WeightedModifierType) => {
|
||||||
const weightedModifierType = modifierType as WeightedModifierType;
|
const weightedModifierType = modifierType;
|
||||||
const existingModifiers = party[0].scene.findModifiers(m => m.type.id === weightedModifierType.modifierType.id, poolType === ModifierPoolType.PLAYER);
|
const existingModifiers = party[0].scene.findModifiers(m => m.type.id === weightedModifierType.modifierType.id, poolType === ModifierPoolType.PLAYER);
|
||||||
const itemModifierType = weightedModifierType.modifierType instanceof ModifierTypeGenerator
|
const itemModifierType = weightedModifierType.modifierType instanceof ModifierTypeGenerator
|
||||||
? weightedModifierType.modifierType.generateType(party)
|
? weightedModifierType.modifierType.generateType(party)
|
||||||
@ -2028,8 +2030,8 @@ export function regenerateModifierPoolThresholds(party: Pokemon[], poolType: Mod
|
|||||||
|| itemModifierType instanceof FormChangeItemModifierType
|
|| itemModifierType instanceof FormChangeItemModifierType
|
||||||
|| existingModifiers.find(m => m.stackCount < m.getMaxStackCount(party[0].scene, true))
|
|| existingModifiers.find(m => m.stackCount < m.getMaxStackCount(party[0].scene, true))
|
||||||
? weightedModifierType.weight instanceof Function
|
? weightedModifierType.weight instanceof Function
|
||||||
? (weightedModifierType.weight as Function)(party, rerollCount)
|
? weightedModifierType.weight(party, rerollCount)
|
||||||
: weightedModifierType.weight as integer
|
: weightedModifierType.weight
|
||||||
: 0;
|
: 0;
|
||||||
if (weightedModifierType.maxWeight) {
|
if (weightedModifierType.maxWeight) {
|
||||||
const modifierId = weightedModifierType.modifierType.id;
|
const modifierId = weightedModifierType.modifierType.id;
|
||||||
@ -2174,12 +2176,23 @@ export function getPlayerModifierTypeOptions(count: integer, party: PlayerPokemo
|
|||||||
* @param tier If specified will generate item of tier
|
* @param tier If specified will generate item of tier
|
||||||
* @param allowLuckUpgrades `true` to allow items to upgrade tiers (the little animation that plays and is affected by luck)
|
* @param allowLuckUpgrades `true` to allow items to upgrade tiers (the little animation that plays and is affected by luck)
|
||||||
*/
|
*/
|
||||||
function getModifierTypeOptionWithRetry(existingOptions: ModifierTypeOption[], retryCount: integer, party: PlayerPokemon[], tier?: ModifierTier, allowLuckUpgrades?: boolean): ModifierTypeOption {
|
function getModifierTypeOptionWithRetry(existingOptions: ModifierTypeOption[], retryCount: number, party: PlayerPokemon[], tier?: ModifierTier, allowLuckUpgrades?: boolean): ModifierTypeOption {
|
||||||
allowLuckUpgrades = allowLuckUpgrades ?? true;
|
allowLuckUpgrades = allowLuckUpgrades ?? true;
|
||||||
let candidate = getNewModifierTypeOption(party, ModifierPoolType.PLAYER, tier, undefined, 0, allowLuckUpgrades);
|
let candidate = getNewModifierTypeOption(party, ModifierPoolType.PLAYER, tier, undefined, 0, allowLuckUpgrades);
|
||||||
let r = 0;
|
let r = 0;
|
||||||
while (existingOptions.length && ++r < retryCount && existingOptions.filter(o => o.type.name === candidate?.type.name || o.type.group === candidate?.type.group).length) {
|
let isValidForChallenge = new BooleanHolder(true);
|
||||||
|
applyChallenges(party[0].scene.gameMode, ChallengeType.RANDOM_ITEM_BLACKLIST, candidate, isValidForChallenge);
|
||||||
|
while (
|
||||||
|
(
|
||||||
|
existingOptions.length
|
||||||
|
&& ++r < retryCount
|
||||||
|
&& existingOptions.filter(o => o.type.name === candidate?.type.name || o.type.group === candidate?.type.group).length
|
||||||
|
)
|
||||||
|
|| !isValidForChallenge.value
|
||||||
|
) {
|
||||||
candidate = getNewModifierTypeOption(party, ModifierPoolType.PLAYER, candidate?.type.tier ?? tier, candidate?.upgradeCount, 0, allowLuckUpgrades);
|
candidate = getNewModifierTypeOption(party, ModifierPoolType.PLAYER, candidate?.type.tier ?? tier, candidate?.upgradeCount, 0, allowLuckUpgrades);
|
||||||
|
isValidForChallenge = new BooleanHolder(true);
|
||||||
|
applyChallenges(party[0].scene.gameMode, ChallengeType.RANDOM_ITEM_BLACKLIST, candidate, isValidForChallenge);
|
||||||
}
|
}
|
||||||
return candidate!;
|
return candidate!;
|
||||||
}
|
}
|
||||||
@ -2209,7 +2222,7 @@ export function overridePlayerModifierTypeOptions(options: ModifierTypeOption[],
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getPlayerShopModifierTypeOptionsForWave(waveIndex: integer, baseCost: integer): ModifierTypeOption[] {
|
export function getPlayerShopModifierTypeOptionsForWave(waveIndex: number, baseCost: number, gameMode: GameMode): ModifierTypeOption[] {
|
||||||
if (!(waveIndex % 10)) {
|
if (!(waveIndex % 10)) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
@ -2244,7 +2257,11 @@ export function getPlayerShopModifierTypeOptionsForWave(waveIndex: integer, base
|
|||||||
new ModifierTypeOption(modifierTypes.SACRED_ASH(), 0, baseCost * 10)
|
new ModifierTypeOption(modifierTypes.SACRED_ASH(), 0, baseCost * 10)
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
return options.slice(0, Math.ceil(Math.max(waveIndex + 10, 0) / 30)).flat();
|
return options.slice(0, Math.ceil(Math.max(waveIndex + 10, 0) / 30)).flat().filter(item => {
|
||||||
|
const isValidForChallenge = new BooleanHolder(true);
|
||||||
|
applyChallenges(gameMode, ChallengeType.SHOP_ITEM_BLACKLIST, item, isValidForChallenge);
|
||||||
|
return isValidForChallenge.value;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getEnemyBuffModifierForWave(tier: ModifierTier, enemyModifiers: PersistentModifier[], scene: BattleScene): EnemyPersistentModifier {
|
export function getEnemyBuffModifierForWave(tier: ModifierTier, enemyModifiers: PersistentModifier[], scene: BattleScene): EnemyPersistentModifier {
|
||||||
@ -2319,8 +2336,8 @@ export function getDailyRunStarterModifiers(party: PlayerPokemon[]): PokemonHeld
|
|||||||
* @param retryCount Max allowed tries before the next tier down is checked for a valid ModifierType
|
* @param retryCount Max allowed tries before the next tier down is checked for a valid ModifierType
|
||||||
* @param allowLuckUpgrades Default true. If false, will not allow ModifierType to randomly upgrade to next tier
|
* @param allowLuckUpgrades Default true. If false, will not allow ModifierType to randomly upgrade to next tier
|
||||||
*/
|
*/
|
||||||
function getNewModifierTypeOption(party: Pokemon[], poolType: ModifierPoolType, tier?: ModifierTier, upgradeCount?: integer, retryCount: integer = 0, allowLuckUpgrades: boolean = true): ModifierTypeOption | null {
|
function getNewModifierTypeOption(party: Pokemon[], poolType: ModifierPoolType, tier?: ModifierTier, upgradeCount?: number, retryCount: number = 0, allowLuckUpgrades: boolean = true): ModifierTypeOption | null {
|
||||||
const player = !poolType;
|
const player = poolType === ModifierPoolType.PLAYER;
|
||||||
const pool = getModifierPoolForType(poolType);
|
const pool = getModifierPoolForType(poolType);
|
||||||
let thresholds: object;
|
let thresholds: object;
|
||||||
switch (poolType) {
|
switch (poolType) {
|
||||||
@ -2370,7 +2387,7 @@ function getNewModifierTypeOption(party: Pokemon[], poolType: ModifierPoolType,
|
|||||||
}
|
}
|
||||||
|
|
||||||
tier += upgradeCount;
|
tier += upgradeCount;
|
||||||
while (tier && (!modifierPool.hasOwnProperty(tier) || !modifierPool[tier].length)) {
|
while (tier && (!pool.hasOwnProperty(tier) || !pool[tier].length)) {
|
||||||
tier--;
|
tier--;
|
||||||
if (upgradeCount) {
|
if (upgradeCount) {
|
||||||
upgradeCount--;
|
upgradeCount--;
|
||||||
@ -2381,7 +2398,7 @@ function getNewModifierTypeOption(party: Pokemon[], poolType: ModifierPoolType,
|
|||||||
if (tier < ModifierTier.MASTER && allowLuckUpgrades) {
|
if (tier < ModifierTier.MASTER && allowLuckUpgrades) {
|
||||||
const partyShinyCount = party.filter(p => p.isShiny() && !p.isFainted()).length;
|
const partyShinyCount = party.filter(p => p.isShiny() && !p.isFainted()).length;
|
||||||
const upgradeOdds = Math.floor(32 / ((partyShinyCount + 2) / 2));
|
const upgradeOdds = Math.floor(32 / ((partyShinyCount + 2) / 2));
|
||||||
while (modifierPool.hasOwnProperty(tier + upgradeCount + 1) && modifierPool[tier + upgradeCount + 1].length) {
|
while (pool.hasOwnProperty(tier + upgradeCount + 1) && pool[tier + upgradeCount + 1].length) {
|
||||||
if (!randSeedInt(upgradeOdds)) {
|
if (!randSeedInt(upgradeOdds)) {
|
||||||
upgradeCount++;
|
upgradeCount++;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,21 +1,23 @@
|
|||||||
import BattleScene from "#app/battle-scene";
|
|
||||||
import { BattlerIndex } from "#app/battle";
|
import { BattlerIndex } from "#app/battle";
|
||||||
import { getPokeballCatchMultiplier, getPokeballAtlasKey, getPokeballTintColor, doPokeballBounceAnim } from "#app/data/pokeball";
|
import BattleScene from "#app/battle-scene";
|
||||||
|
import { SubstituteTag } from "#app/data/battler-tags";
|
||||||
|
import { ChallengeType, applyChallenges } from "#app/data/challenge";
|
||||||
|
import { doPokeballBounceAnim, getPokeballAtlasKey, getPokeballCatchMultiplier, getPokeballTintColor } from "#app/data/pokeball";
|
||||||
import { getStatusEffectCatchRateMultiplier } from "#app/data/status-effect";
|
import { getStatusEffectCatchRateMultiplier } from "#app/data/status-effect";
|
||||||
import { PokeballType } from "#app/enums/pokeball";
|
import { PokeballType } from "#app/enums/pokeball";
|
||||||
import { StatusEffect } from "#app/enums/status-effect";
|
import { StatusEffect } from "#app/enums/status-effect";
|
||||||
import { addPokeballOpenParticles, addPokeballCaptureStars } from "#app/field/anims";
|
import { addPokeballCaptureStars, addPokeballOpenParticles } from "#app/field/anims";
|
||||||
import { EnemyPokemon } from "#app/field/pokemon";
|
import { EnemyPokemon } from "#app/field/pokemon";
|
||||||
import { getPokemonNameWithAffix } from "#app/messages";
|
import { getPokemonNameWithAffix } from "#app/messages";
|
||||||
import { PokemonHeldItemModifier } from "#app/modifier/modifier";
|
import { PokemonHeldItemModifier } from "#app/modifier/modifier";
|
||||||
|
import { PokemonPhase } from "#app/phases/pokemon-phase";
|
||||||
|
import { VictoryPhase } from "#app/phases/victory-phase";
|
||||||
import { achvs } from "#app/system/achv";
|
import { achvs } from "#app/system/achv";
|
||||||
import { PartyUiMode, PartyOption } from "#app/ui/party-ui-handler";
|
import { PartyOption, PartyUiMode } from "#app/ui/party-ui-handler";
|
||||||
import { SummaryUiMode } from "#app/ui/summary-ui-handler";
|
import { SummaryUiMode } from "#app/ui/summary-ui-handler";
|
||||||
import { Mode } from "#app/ui/ui";
|
import { Mode } from "#app/ui/ui";
|
||||||
|
import { BooleanHolder } from "#app/utils";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import { PokemonPhase } from "./pokemon-phase";
|
|
||||||
import { VictoryPhase } from "./victory-phase";
|
|
||||||
import { SubstituteTag } from "#app/data/battler-tags";
|
|
||||||
|
|
||||||
export class AttemptCapturePhase extends PokemonPhase {
|
export class AttemptCapturePhase extends PokemonPhase {
|
||||||
private pokeballType: PokeballType;
|
private pokeballType: PokeballType;
|
||||||
@ -249,6 +251,13 @@ export class AttemptCapturePhase extends PokemonPhase {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
Promise.all([ pokemon.hideInfo(), this.scene.gameData.setPokemonCaught(pokemon) ]).then(() => {
|
Promise.all([ pokemon.hideInfo(), this.scene.gameData.setPokemonCaught(pokemon) ]).then(() => {
|
||||||
|
const challengeCanAddToParty = new BooleanHolder(true);
|
||||||
|
applyChallenges(this.scene.gameMode, ChallengeType.ADD_POKEMON_TO_PARTY, pokemon, this.scene.currentBattle.waveIndex, challengeCanAddToParty);
|
||||||
|
if (!challengeCanAddToParty.value) {
|
||||||
|
removePokemon();
|
||||||
|
end();
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (this.scene.getParty().length === 6) {
|
if (this.scene.getParty().length === 6) {
|
||||||
const promptRelease = () => {
|
const promptRelease = () => {
|
||||||
this.scene.ui.showText(i18next.t("battle:partyFull", { pokemonName: pokemon.getNameToRender() }), null, () => {
|
this.scene.ui.showText(i18next.t("battle:partyFull", { pokemonName: pokemon.getNameToRender() }), null, () => {
|
||||||
|
@ -1,22 +1,23 @@
|
|||||||
|
import { BattleType, TurnCommand } from "#app/battle";
|
||||||
import BattleScene from "#app/battle-scene";
|
import BattleScene from "#app/battle-scene";
|
||||||
import { TurnCommand, BattleType } from "#app/battle";
|
|
||||||
import { TrappedTag, EncoreTag } from "#app/data/battler-tags";
|
|
||||||
import { MoveTargetSet, getMoveTargets } from "#app/data/move";
|
|
||||||
import { speciesStarterCosts } from "#app/data/balance/starters";
|
import { speciesStarterCosts } from "#app/data/balance/starters";
|
||||||
import { Abilities } from "#app/enums/abilities";
|
import { EncoreTag, TrappedTag } from "#app/data/battler-tags";
|
||||||
import { BattlerTagType } from "#app/enums/battler-tag-type";
|
import { applyChallenges, ChallengeType } from "#app/data/challenge";
|
||||||
import { Biome } from "#app/enums/biome";
|
import { getMoveTargets, MoveTargetSet } from "#app/data/move";
|
||||||
import { Moves } from "#app/enums/moves";
|
|
||||||
import { PokeballType } from "#app/enums/pokeball";
|
import { PokeballType } from "#app/enums/pokeball";
|
||||||
import { FieldPosition, PlayerPokemon } from "#app/field/pokemon";
|
import { FieldPosition, PlayerPokemon } from "#app/field/pokemon";
|
||||||
import { getPokemonNameWithAffix } from "#app/messages";
|
import { getPokemonNameWithAffix } from "#app/messages";
|
||||||
|
import { FieldPhase } from "#app/phases/field-phase";
|
||||||
|
import { SelectTargetPhase } from "#app/phases/select-target-phase";
|
||||||
import { Command } from "#app/ui/command-ui-handler";
|
import { Command } from "#app/ui/command-ui-handler";
|
||||||
import { Mode } from "#app/ui/ui";
|
import { Mode } from "#app/ui/ui";
|
||||||
import i18next from "i18next";
|
import { BooleanHolder, isNullOrUndefined } from "#app/utils";
|
||||||
import { FieldPhase } from "./field-phase";
|
import { Abilities } from "#enums/abilities";
|
||||||
import { SelectTargetPhase } from "./select-target-phase";
|
import { BattlerTagType } from "#enums/battler-tag-type";
|
||||||
|
import { Biome } from "#enums/biome";
|
||||||
|
import { Moves } from "#enums/moves";
|
||||||
import { MysteryEncounterMode } from "#enums/mystery-encounter-mode";
|
import { MysteryEncounterMode } from "#enums/mystery-encounter-mode";
|
||||||
import { isNullOrUndefined } from "#app/utils";
|
import i18next from "i18next";
|
||||||
|
|
||||||
export class CommandPhase extends FieldPhase {
|
export class CommandPhase extends FieldPhase {
|
||||||
protected fieldIndex: integer;
|
protected fieldIndex: integer;
|
||||||
@ -94,6 +95,18 @@ export class CommandPhase extends FieldPhase {
|
|||||||
|
|
||||||
switch (command) {
|
switch (command) {
|
||||||
case Command.FIGHT:
|
case Command.FIGHT:
|
||||||
|
// Check if move can be used in challenge
|
||||||
|
const isValidForChallenge = new BooleanHolder(true);
|
||||||
|
applyChallenges(this.scene.gameMode, ChallengeType.MOVE_BLACKLIST, playerPokemon.getMoveset()[cursor]!, isValidForChallenge);
|
||||||
|
if (!isValidForChallenge.value) {
|
||||||
|
const moveName = playerPokemon.getMoveset()[cursor]?.getName();
|
||||||
|
this.scene.ui.setMode(Mode.MESSAGE);
|
||||||
|
this.scene.ui.showText(i18next.t("challenges:illegalMove", { moveName: moveName }), null, () => {
|
||||||
|
this.scene.ui.clearText();
|
||||||
|
this.scene.ui.setMode(Mode.FIGHT, this.fieldIndex);
|
||||||
|
}, null, true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
let useStruggle = false;
|
let useStruggle = false;
|
||||||
if (cursor === -1 ||
|
if (cursor === -1 ||
|
||||||
playerPokemon.trySelectMove(cursor, args[0] as boolean) ||
|
playerPokemon.trySelectMove(cursor, args[0] as boolean) ||
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import BattleScene from "#app/battle-scene";
|
import BattleScene from "#app/battle-scene";
|
||||||
import * as Utils from "#app/utils";
|
import { applyChallenges, ChallengeType } from "#app/data/challenge";
|
||||||
import { BattlePhase } from "./battle-phase";
|
import { BattlePhase } from "#app/phases/battle-phase";
|
||||||
|
import { BooleanHolder, fixedInt } from "#app/utils";
|
||||||
|
|
||||||
export class PartyHealPhase extends BattlePhase {
|
export class PartyHealPhase extends BattlePhase {
|
||||||
private resumeBgm: boolean;
|
private resumeBgm: boolean;
|
||||||
@ -14,21 +15,34 @@ export class PartyHealPhase extends BattlePhase {
|
|||||||
start() {
|
start() {
|
||||||
super.start();
|
super.start();
|
||||||
|
|
||||||
|
const isHealPhaseActive = new BooleanHolder(true);
|
||||||
|
applyChallenges(this.scene.gameMode, ChallengeType.NO_HEAL_PHASE, isHealPhaseActive);
|
||||||
|
if (!isHealPhaseActive.value) {
|
||||||
|
return this.end();
|
||||||
|
}
|
||||||
|
|
||||||
const bgmPlaying = this.scene.isBgmPlaying();
|
const bgmPlaying = this.scene.isBgmPlaying();
|
||||||
if (bgmPlaying) {
|
if (bgmPlaying) {
|
||||||
this.scene.fadeOutBgm(1000, false);
|
this.scene.fadeOutBgm(1000, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const canBeRevived = new BooleanHolder(true);
|
||||||
this.scene.ui.fadeOut(1000).then(() => {
|
this.scene.ui.fadeOut(1000).then(() => {
|
||||||
for (const pokemon of this.scene.getParty()) {
|
for (const pokemon of this.scene.getParty()) {
|
||||||
pokemon.hp = pokemon.getMaxHp();
|
applyChallenges(this.scene.gameMode, ChallengeType.PREVENT_REVIVE, pokemon, canBeRevived);
|
||||||
pokemon.resetStatus();
|
if (canBeRevived.value || !pokemon.isFainted()) {
|
||||||
for (const move of pokemon.moveset) {
|
pokemon.hp = pokemon.getMaxHp();
|
||||||
move!.ppUsed = 0; // TODO: is this bang correct?
|
pokemon.resetStatus();
|
||||||
|
for (const move of pokemon.moveset) {
|
||||||
|
if (move) {
|
||||||
|
move.ppUsed = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pokemon.updateInfo(true);
|
||||||
}
|
}
|
||||||
pokemon.updateInfo(true);
|
|
||||||
}
|
}
|
||||||
const healSong = this.scene.playSoundWithoutBgm("heal");
|
const healSong = this.scene.playSoundWithoutBgm("heal");
|
||||||
this.scene.time.delayedCall(Utils.fixedInt(healSong.totalDuration * 1000), () => {
|
this.scene.time.delayedCall(fixedInt(healSong.totalDuration * 1000), () => {
|
||||||
healSong.destroy();
|
healSong.destroy();
|
||||||
if (this.resumeBgm && bgmPlaying) {
|
if (this.resumeBgm && bgmPlaying) {
|
||||||
this.scene.playBgm();
|
this.scene.playBgm();
|
||||||
|
@ -1,16 +1,35 @@
|
|||||||
import BattleScene from "#app/battle-scene";
|
import BattleScene from "#app/battle-scene";
|
||||||
|
import {
|
||||||
|
ExtraModifierModifier,
|
||||||
|
HealShopCostModifier,
|
||||||
|
Modifier,
|
||||||
|
PokemonHeldItemModifier,
|
||||||
|
TempExtraModifierModifier
|
||||||
|
} from "#app/modifier/modifier";
|
||||||
import { ModifierTier } from "#app/modifier/modifier-tier";
|
import { ModifierTier } from "#app/modifier/modifier-tier";
|
||||||
import { regenerateModifierPoolThresholds, ModifierTypeOption, ModifierType, getPlayerShopModifierTypeOptionsForWave, PokemonModifierType, FusePokemonModifierType, PokemonMoveModifierType, TmModifierType, RememberMoveModifierType, PokemonPpRestoreModifierType, PokemonPpUpModifierType, ModifierPoolType, getPlayerModifierTypeOptions } from "#app/modifier/modifier-type";
|
import {
|
||||||
import { ExtraModifierModifier, HealShopCostModifier, Modifier, PokemonHeldItemModifier, TempExtraModifierModifier } from "#app/modifier/modifier";
|
CustomModifierSettings,
|
||||||
import ModifierSelectUiHandler, { SHOP_OPTIONS_ROW_LIMIT } from "#app/ui/modifier-select-ui-handler";
|
FusePokemonModifierType,
|
||||||
import PartyUiHandler, { PartyUiMode, PartyOption } from "#app/ui/party-ui-handler";
|
getPlayerModifierTypeOptions,
|
||||||
import { Mode } from "#app/ui/ui";
|
getPlayerShopModifierTypeOptionsForWave,
|
||||||
import i18next from "i18next";
|
ModifierPoolType,
|
||||||
import * as Utils from "#app/utils";
|
ModifierType,
|
||||||
import { BattlePhase } from "./battle-phase";
|
ModifierTypeOption,
|
||||||
|
PokemonModifierType,
|
||||||
|
PokemonMoveModifierType,
|
||||||
|
PokemonPpRestoreModifierType,
|
||||||
|
PokemonPpUpModifierType,
|
||||||
|
regenerateModifierPoolThresholds,
|
||||||
|
RememberMoveModifierType,
|
||||||
|
TmModifierType
|
||||||
|
} from "#app/modifier/modifier-type";
|
||||||
import Overrides from "#app/overrides";
|
import Overrides from "#app/overrides";
|
||||||
import { CustomModifierSettings } from "#app/modifier/modifier-type";
|
import { BattlePhase } from "#app/phases/battle-phase";
|
||||||
|
import ModifierSelectUiHandler, { SHOP_OPTIONS_ROW_LIMIT } from "#app/ui/modifier-select-ui-handler";
|
||||||
|
import PartyUiHandler, { PartyOption, PartyUiMode } from "#app/ui/party-ui-handler";
|
||||||
|
import { Mode } from "#app/ui/ui";
|
||||||
import { isNullOrUndefined, NumberHolder } from "#app/utils";
|
import { isNullOrUndefined, NumberHolder } from "#app/utils";
|
||||||
|
import i18next from "i18next";
|
||||||
|
|
||||||
export class SelectModifierPhase extends BattlePhase {
|
export class SelectModifierPhase extends BattlePhase {
|
||||||
private rerollCount: integer;
|
private rerollCount: integer;
|
||||||
@ -42,7 +61,7 @@ export class SelectModifierPhase extends BattlePhase {
|
|||||||
if (!this.isCopy) {
|
if (!this.isCopy) {
|
||||||
regenerateModifierPoolThresholds(party, this.getPoolType(), this.rerollCount);
|
regenerateModifierPoolThresholds(party, this.getPoolType(), this.rerollCount);
|
||||||
}
|
}
|
||||||
const modifierCount = new Utils.IntegerHolder(3);
|
const modifierCount = new NumberHolder(3);
|
||||||
if (this.isPlayer()) {
|
if (this.isPlayer()) {
|
||||||
this.scene.applyModifiers(ExtraModifierModifier, true, modifierCount);
|
this.scene.applyModifiers(ExtraModifierModifier, true, modifierCount);
|
||||||
this.scene.applyModifiers(TempExtraModifierModifier, true, modifierCount);
|
this.scene.applyModifiers(TempExtraModifierModifier, true, modifierCount);
|
||||||
@ -140,7 +159,7 @@ export class SelectModifierPhase extends BattlePhase {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
const shopOptions = getPlayerShopModifierTypeOptionsForWave(this.scene.currentBattle.waveIndex, this.scene.getWaveMoneyAmount(1));
|
const shopOptions = getPlayerShopModifierTypeOptionsForWave(this.scene.currentBattle.waveIndex, this.scene.getWaveMoneyAmount(1), this.scene.gameMode);
|
||||||
const shopOption = shopOptions[rowCursor > 2 || shopOptions.length <= SHOP_OPTIONS_ROW_LIMIT ? cursor : cursor + SHOP_OPTIONS_ROW_LIMIT];
|
const shopOption = shopOptions[rowCursor > 2 || shopOptions.length <= SHOP_OPTIONS_ROW_LIMIT ? cursor : cursor + SHOP_OPTIONS_ROW_LIMIT];
|
||||||
if (shopOption.type) {
|
if (shopOption.type) {
|
||||||
modifierType = shopOption.type;
|
modifierType = shopOption.type;
|
||||||
|
@ -1,16 +1,18 @@
|
|||||||
import BattleScene from "#app/battle-scene";
|
|
||||||
import { BattlerIndex, BattleType, ClassicFixedBossWaves } from "#app/battle";
|
import { BattlerIndex, BattleType, ClassicFixedBossWaves } from "#app/battle";
|
||||||
import { CustomModifierSettings, modifierTypes } from "#app/modifier/modifier-type";
|
import BattleScene from "#app/battle-scene";
|
||||||
import { BattleEndPhase } from "./battle-end-phase";
|
import { applyChallenges, ChallengeType } from "#app/data/challenge";
|
||||||
import { NewBattlePhase } from "./new-battle-phase";
|
|
||||||
import { PokemonPhase } from "./pokemon-phase";
|
|
||||||
import { AddEnemyBuffModifierPhase } from "./add-enemy-buff-modifier-phase";
|
|
||||||
import { EggLapsePhase } from "./egg-lapse-phase";
|
|
||||||
import { GameOverPhase } from "./game-over-phase";
|
|
||||||
import { ModifierRewardPhase } from "./modifier-reward-phase";
|
|
||||||
import { SelectModifierPhase } from "./select-modifier-phase";
|
|
||||||
import { TrainerVictoryPhase } from "./trainer-victory-phase";
|
|
||||||
import { handleMysteryEncounterVictory } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
import { handleMysteryEncounterVictory } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||||
|
import { CustomModifierSettings, modifierTypes } from "#app/modifier/modifier-type";
|
||||||
|
import { AddEnemyBuffModifierPhase } from "#app/phases/add-enemy-buff-modifier-phase";
|
||||||
|
import { BattleEndPhase } from "#app/phases/battle-end-phase";
|
||||||
|
import { EggLapsePhase } from "#app/phases/egg-lapse-phase";
|
||||||
|
import { GameOverPhase } from "#app/phases/game-over-phase";
|
||||||
|
import { ModifierRewardPhase } from "#app/phases/modifier-reward-phase";
|
||||||
|
import { NewBattlePhase } from "#app/phases/new-battle-phase";
|
||||||
|
import { PokemonPhase } from "#app/phases/pokemon-phase";
|
||||||
|
import { SelectModifierPhase } from "#app/phases/select-modifier-phase";
|
||||||
|
import { TrainerVictoryPhase } from "#app/phases/trainer-victory-phase";
|
||||||
|
import { BooleanHolder } from "#app/utils";
|
||||||
|
|
||||||
export class VictoryPhase extends PokemonPhase {
|
export class VictoryPhase extends PokemonPhase {
|
||||||
/** If true, indicates that the phase is intended for EXP purposes only, and not to continue a battle to next phase */
|
/** If true, indicates that the phase is intended for EXP purposes only, and not to continue a battle to next phase */
|
||||||
@ -40,6 +42,9 @@ export class VictoryPhase extends PokemonPhase {
|
|||||||
return this.end();
|
return this.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isHealPhaseActive = new BooleanHolder(true);
|
||||||
|
applyChallenges(this.scene.gameMode, ChallengeType.NO_HEAL_PHASE, isHealPhaseActive);
|
||||||
|
|
||||||
if (!this.scene.getEnemyParty().find(p => this.scene.currentBattle.battleType === BattleType.WILD ? p.isOnField() : !p?.isFainted(true))) {
|
if (!this.scene.getEnemyParty().find(p => this.scene.currentBattle.battleType === BattleType.WILD ? p.isOnField() : !p?.isFainted(true))) {
|
||||||
this.scene.pushPhase(new BattleEndPhase(this.scene));
|
this.scene.pushPhase(new BattleEndPhase(this.scene));
|
||||||
if (this.scene.currentBattle.battleType === BattleType.TRAINER) {
|
if (this.scene.currentBattle.battleType === BattleType.TRAINER) {
|
||||||
@ -51,7 +56,7 @@ export class VictoryPhase extends PokemonPhase {
|
|||||||
// Should get Lock Capsule on 165 before shop phase so it can be used in the rewards shop
|
// Should get Lock Capsule on 165 before shop phase so it can be used in the rewards shop
|
||||||
this.scene.pushPhase(new ModifierRewardPhase(this.scene, modifierTypes.LOCK_CAPSULE));
|
this.scene.pushPhase(new ModifierRewardPhase(this.scene, modifierTypes.LOCK_CAPSULE));
|
||||||
}
|
}
|
||||||
if (this.scene.currentBattle.waveIndex % 10) {
|
if (this.scene.currentBattle.waveIndex % 10 || (this.scene.currentBattle.waveIndex === 0 && !isHealPhaseActive.value)) {
|
||||||
this.scene.pushPhase(new SelectModifierPhase(this.scene, undefined, undefined, this.getFixedBattleCustomModifiers()));
|
this.scene.pushPhase(new SelectModifierPhase(this.scene, undefined, undefined, this.getFixedBattleCustomModifiers()));
|
||||||
} else if (this.scene.gameMode.isDaily) {
|
} else if (this.scene.gameMode.isDaily) {
|
||||||
this.scene.pushPhase(new ModifierRewardPhase(this.scene, modifierTypes.EXP_CHARM));
|
this.scene.pushPhase(new ModifierRewardPhase(this.scene, modifierTypes.EXP_CHARM));
|
||||||
|
62
src/test/challenge/hardcore.test.ts
Normal file
62
src/test/challenge/hardcore.test.ts
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
import { Abilities } from "#enums/abilities";
|
||||||
|
import { Challenges } from "#enums/challenges";
|
||||||
|
import { Moves } from "#enums/moves";
|
||||||
|
import { Species } from "#enums/species";
|
||||||
|
import GameManager from "#test/utils/gameManager";
|
||||||
|
import Phaser from "phaser";
|
||||||
|
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
||||||
|
|
||||||
|
describe("Challenge - Hardcore", () => {
|
||||||
|
let phaserGame: Phaser.Game;
|
||||||
|
let game: GameManager;
|
||||||
|
|
||||||
|
beforeAll(() => {
|
||||||
|
phaserGame = new Phaser.Game({
|
||||||
|
type: Phaser.HEADLESS,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
game.phaseInterceptor.restoreOg();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
game = new GameManager(phaserGame);
|
||||||
|
|
||||||
|
game.challengeMode.addChallenge(Challenges.HARDCORE);
|
||||||
|
|
||||||
|
game.override
|
||||||
|
.battleType("single")
|
||||||
|
.ability(Abilities.BALL_FETCH)
|
||||||
|
.moveset(Moves.THUNDERBOLT)
|
||||||
|
.startingLevel(2000)
|
||||||
|
.enemySpecies(Species.MAGIKARP)
|
||||||
|
.enemyAbility(Abilities.BALL_FETCH)
|
||||||
|
.enemyMoveset(Moves.SPLASH);
|
||||||
|
});
|
||||||
|
|
||||||
|
it.todo("prevents revival items from showing up in the shop", async () => {
|
||||||
|
game.override.startingWave(191);
|
||||||
|
await game.challengeMode.startBattle();
|
||||||
|
|
||||||
|
game.move.select(Moves.THUNDERBOLT);
|
||||||
|
await game.phaseInterceptor.to("SelectModifierPhase");
|
||||||
|
|
||||||
|
expect(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it.todo("prevents revival items from showing up in rewards", async () => {
|
||||||
|
game.modifiers
|
||||||
|
.addCheck("REVIVE")
|
||||||
|
.addCheck("MAX_REVIVE")
|
||||||
|
.addCheck("REVIVER_SEED");
|
||||||
|
await game.challengeMode.startBattle();
|
||||||
|
|
||||||
|
game.move.select(Moves.THUNDERBOLT);
|
||||||
|
await game.phaseInterceptor.to("SelectModifierPhase");
|
||||||
|
game.modifiers
|
||||||
|
.testCheck("REVIVE", false)
|
||||||
|
.testCheck("MAX_REVIVE", false)
|
||||||
|
.testCheck("REVIVER_SEED", false);
|
||||||
|
});
|
||||||
|
});
|
43
src/test/challenge/limited_catch.test.ts
Normal file
43
src/test/challenge/limited_catch.test.ts
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import { CommandPhase } from "#app/phases/command-phase";
|
||||||
|
import { Command } from "#app/ui/command-ui-handler";
|
||||||
|
import { Challenges } from "#enums/challenges";
|
||||||
|
import { Species } from "#enums/species";
|
||||||
|
import GameManager from "#test/utils/gameManager";
|
||||||
|
import Phaser from "phaser";
|
||||||
|
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
||||||
|
|
||||||
|
describe("Challenge - Limited Catch", () => {
|
||||||
|
let phaserGame: Phaser.Game;
|
||||||
|
let game: GameManager;
|
||||||
|
|
||||||
|
beforeAll(() => {
|
||||||
|
phaserGame = new Phaser.Game({
|
||||||
|
type: Phaser.HEADLESS,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
game.phaseInterceptor.restoreOg();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
game = new GameManager(phaserGame);
|
||||||
|
|
||||||
|
game.challengeMode.addChallenge(Challenges.LIMITED_CATCH);
|
||||||
|
|
||||||
|
game.override.battleType("single");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("prevents catching pokemon outside of the first wave of the biome", async () => {
|
||||||
|
game.override
|
||||||
|
.startingWave(3)
|
||||||
|
.pokeballs([ 0, 0, 0, 0, 100 ]);
|
||||||
|
await game.challengeMode.startBattle([ Species.FEEBAS ]);
|
||||||
|
|
||||||
|
const phase = game.scene.getCurrentPhase() as CommandPhase;
|
||||||
|
phase.handleCommand(Command.BALL, 4);
|
||||||
|
await game.phaseInterceptor.to("BattleEndPhase");
|
||||||
|
|
||||||
|
expect(game.scene.getParty().length).toBe(1);
|
||||||
|
});
|
||||||
|
});
|
55
src/test/challenge/no_auto_heal.test.ts
Normal file
55
src/test/challenge/no_auto_heal.test.ts
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
import { Abilities } from "#enums/abilities";
|
||||||
|
import { Challenges } from "#enums/challenges";
|
||||||
|
import { Moves } from "#enums/moves";
|
||||||
|
import { Species } from "#enums/species";
|
||||||
|
import GameManager from "#test/utils/gameManager";
|
||||||
|
import Phaser from "phaser";
|
||||||
|
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
||||||
|
|
||||||
|
describe("Challenge - No Auto Heal", () => {
|
||||||
|
let phaserGame: Phaser.Game;
|
||||||
|
let game: GameManager;
|
||||||
|
|
||||||
|
beforeAll(() => {
|
||||||
|
phaserGame = new Phaser.Game({
|
||||||
|
type: Phaser.HEADLESS,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
game.phaseInterceptor.restoreOg();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
game = new GameManager(phaserGame);
|
||||||
|
|
||||||
|
game.challengeMode.addChallenge(Challenges.NO_AUTO_HEAL);
|
||||||
|
|
||||||
|
game.override
|
||||||
|
.battleType("single")
|
||||||
|
.starterSpecies(Species.FEEBAS)
|
||||||
|
.ability(Abilities.BALL_FETCH)
|
||||||
|
.moveset(Moves.THUNDERBOLT)
|
||||||
|
.enemySpecies(Species.MAGIKARP)
|
||||||
|
.enemyAbility(Abilities.BALL_FETCH)
|
||||||
|
.enemyMoveset(Moves.SPLASH);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("prevents PartyHealPhase from healing the player's pokemon", async () => {
|
||||||
|
game.override
|
||||||
|
.startingWave(10)
|
||||||
|
.startingLevel(100);
|
||||||
|
await game.challengeMode.startBattle();
|
||||||
|
|
||||||
|
const player = game.scene.getPlayerField()[0];
|
||||||
|
player.damageAndUpdate(1);
|
||||||
|
|
||||||
|
game.move.select(Moves.THUNDERBOLT);
|
||||||
|
await game.phaseInterceptor.to("SelectModifierPhase", false);
|
||||||
|
game.doSelectModifier();
|
||||||
|
await game.toNextTurn();
|
||||||
|
|
||||||
|
expect(player.hp).toBe(player.getMaxHp() - 1);
|
||||||
|
expect(player.moveset[0]?.ppUsed).toBe(1);
|
||||||
|
});
|
||||||
|
});
|
@ -1,13 +1,11 @@
|
|||||||
import { MapModifier } from "#app/modifier/modifier";
|
|
||||||
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
|
||||||
import GameManager from "./utils/gameManager";
|
|
||||||
import { Moves } from "#app/enums/moves";
|
|
||||||
import { Biome } from "#app/enums/biome";
|
import { Biome } from "#app/enums/biome";
|
||||||
import { Mode } from "#app/ui/ui";
|
import { Moves } from "#app/enums/moves";
|
||||||
|
import { MapModifier } from "#app/modifier/modifier";
|
||||||
import ModifierSelectUiHandler from "#app/ui/modifier-select-ui-handler";
|
import ModifierSelectUiHandler from "#app/ui/modifier-select-ui-handler";
|
||||||
|
import { Mode } from "#app/ui/ui";
|
||||||
import { Species } from "#enums/species";
|
import { Species } from "#enums/species";
|
||||||
|
import GameManager from "#test/utils/gameManager";
|
||||||
//const TIMEOUT = 20 * 1000;
|
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
||||||
|
|
||||||
describe("Daily Mode", () => {
|
describe("Daily Mode", () => {
|
||||||
let phaserGame: Phaser.Game;
|
let phaserGame: Phaser.Game;
|
||||||
|
@ -1,16 +1,15 @@
|
|||||||
import { BattleStyle } from "#app/enums/battle-style";
|
import { Challenge, copyChallenge } from "#app/data/challenge";
|
||||||
import { Species } from "#app/enums/species";
|
|
||||||
import overrides from "#app/overrides";
|
import overrides from "#app/overrides";
|
||||||
|
import { CommandPhase } from "#app/phases/command-phase";
|
||||||
import { EncounterPhase } from "#app/phases/encounter-phase";
|
import { EncounterPhase } from "#app/phases/encounter-phase";
|
||||||
import { SelectStarterPhase } from "#app/phases/select-starter-phase";
|
import { SelectStarterPhase } from "#app/phases/select-starter-phase";
|
||||||
import { Mode } from "#app/ui/ui";
|
|
||||||
import { generateStarter } from "../gameManagerUtils";
|
|
||||||
import { GameManagerHelper } from "./gameManagerHelper";
|
|
||||||
import { Challenge } from "#app/data/challenge";
|
|
||||||
import { CommandPhase } from "#app/phases/command-phase";
|
|
||||||
import { TurnInitPhase } from "#app/phases/turn-init-phase";
|
import { TurnInitPhase } from "#app/phases/turn-init-phase";
|
||||||
|
import { Mode } from "#app/ui/ui";
|
||||||
|
import { BattleStyle } from "#enums/battle-style";
|
||||||
import { Challenges } from "#enums/challenges";
|
import { Challenges } from "#enums/challenges";
|
||||||
import { copyChallenge } from "data/challenge";
|
import { Species } from "#enums/species";
|
||||||
|
import { generateStarter } from "#test/utils/gameManagerUtils";
|
||||||
|
import { GameManagerHelper } from "#test/utils/helpers/gameManagerHelper";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper to handle Challenge mode specifics
|
* Helper to handle Challenge mode specifics
|
||||||
@ -25,7 +24,7 @@ export class ChallengeModeHelper extends GameManagerHelper {
|
|||||||
* @param value - The challenge value.
|
* @param value - The challenge value.
|
||||||
* @param severity - The challenge severity.
|
* @param severity - The challenge severity.
|
||||||
*/
|
*/
|
||||||
addChallenge(id: Challenges, value: number, severity: number) {
|
addChallenge(id: Challenges, value: number = 1, severity: number = 1) {
|
||||||
const challenge = copyChallenge({ id, value, severity });
|
const challenge = copyChallenge({ id, value, severity });
|
||||||
this.challenges.push(challenge);
|
this.challenges.push(challenge);
|
||||||
}
|
}
|
||||||
|
@ -1,19 +1,20 @@
|
|||||||
import { StatusEffect } from "#app/data/status-effect";
|
import { StatusEffect } from "#app/data/status-effect";
|
||||||
|
import { Variant } from "#app/data/variant";
|
||||||
import { Weather, WeatherType } from "#app/data/weather";
|
import { Weather, WeatherType } from "#app/data/weather";
|
||||||
import { Abilities } from "#app/enums/abilities";
|
|
||||||
import { Biome } from "#app/enums/biome";
|
|
||||||
import { Moves } from "#app/enums/moves";
|
|
||||||
import { Species } from "#app/enums/species";
|
|
||||||
import * as GameMode from "#app/game-mode";
|
import * as GameMode from "#app/game-mode";
|
||||||
import { GameModes, getGameMode } from "#app/game-mode";
|
import { GameModes, getGameMode } from "#app/game-mode";
|
||||||
import { ModifierOverride } from "#app/modifier/modifier-type";
|
import { ModifierOverride } from "#app/modifier/modifier-type";
|
||||||
import Overrides from "#app/overrides";
|
import Overrides from "#app/overrides";
|
||||||
import { vi } from "vitest";
|
|
||||||
import { GameManagerHelper } from "./gameManagerHelper";
|
|
||||||
import { Unlockables } from "#app/system/unlockables";
|
import { Unlockables } from "#app/system/unlockables";
|
||||||
import { Variant } from "#app/data/variant";
|
import { Abilities } from "#enums/abilities";
|
||||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
import { Biome } from "#enums/biome";
|
||||||
|
import { Moves } from "#enums/moves";
|
||||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||||
|
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||||
|
import { PokeballType } from "#enums/pokeball";
|
||||||
|
import { Species } from "#enums/species";
|
||||||
|
import { GameManagerHelper } from "#test/utils/helpers/gameManagerHelper";
|
||||||
|
import { vi } from "vitest";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper to handle overrides in tests
|
* Helper to handle overrides in tests
|
||||||
@ -27,14 +28,14 @@ export class OverridesHelper extends GameManagerHelper {
|
|||||||
/**
|
/**
|
||||||
* Override the starting biome
|
* Override the starting biome
|
||||||
* @warning Any event listeners that are attached to [NewArenaEvent](events\battle-scene.ts) may need to be handled down the line
|
* @warning Any event listeners that are attached to [NewArenaEvent](events\battle-scene.ts) may need to be handled down the line
|
||||||
* @param biome the biome to set
|
* @param biome The {@linkcode Biome} to set
|
||||||
|
* @returns `this`
|
||||||
*/
|
*/
|
||||||
public startingBiome(biome: Biome): this {
|
public startingBiome(biome: Biome): this {
|
||||||
this.game.scene.newArena(biome);
|
this.game.scene.newArena(biome);
|
||||||
this.log(`Starting biome set to ${Biome[biome]} (=${biome})!`);
|
this.log(`Starting biome set to ${Biome[biome]} (=${biome})!`);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Override the starting wave (index)
|
* Override the starting wave (index)
|
||||||
* @param wave the wave (index) to set. Classic: `1`-`200`
|
* @param wave the wave (index) to set. Classic: `1`-`200`
|
||||||
@ -47,8 +48,8 @@ export class OverridesHelper extends GameManagerHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Override the player (pokemon) starting level
|
* Override the player pokemon's starting level
|
||||||
* @param level the (pokemon) level to set
|
* @param level the level to set
|
||||||
* @returns `this`
|
* @returns `this`
|
||||||
*/
|
*/
|
||||||
public startingLevel(level: Species | number): this {
|
public startingLevel(level: Species | number): this {
|
||||||
@ -69,8 +70,8 @@ export class OverridesHelper extends GameManagerHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Override the player (pokemon) starting held items
|
* Override the player pokemon's starting held items
|
||||||
* @param items the items to hold
|
* @param items the {@linkcode ModifierOverride | items} to hold
|
||||||
* @returns `this`
|
* @returns `this`
|
||||||
*/
|
*/
|
||||||
public startingHeldItems(items: ModifierOverride[]): this {
|
public startingHeldItems(items: ModifierOverride[]): this {
|
||||||
@ -80,8 +81,35 @@ export class OverridesHelper extends GameManagerHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Override the player (pokemon) {@linkcode Species | species}
|
* Override the player's pokeball inventory
|
||||||
* @param species the (pokemon) {@linkcode Species | species} to set
|
* @param pokeballs Array specifying the amount of each pokeball to set, or `null` if disabling the override
|
||||||
|
* @param enable Whether to enable or disable the override, default `true`
|
||||||
|
* @returns `this`
|
||||||
|
*/
|
||||||
|
pokeballs(pokeballs: [number, number, number, number, number] | null, enable: boolean = true): this {
|
||||||
|
if (!pokeballs) {
|
||||||
|
pokeballs = [ 5, 0, 0, 0, 0 ];
|
||||||
|
}
|
||||||
|
pokeballs = pokeballs!;
|
||||||
|
const pokeballOverride = {
|
||||||
|
active: enable,
|
||||||
|
pokeballs: {
|
||||||
|
[PokeballType.POKEBALL]: pokeballs[0],
|
||||||
|
[PokeballType.GREAT_BALL]: pokeballs[1],
|
||||||
|
[PokeballType.ULTRA_BALL]: pokeballs[2],
|
||||||
|
[PokeballType.ROGUE_BALL]: pokeballs[3],
|
||||||
|
[PokeballType.MASTER_BALL]: pokeballs[4],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
vi.spyOn(Overrides, "POKEBALL_OVERRIDE", "get").mockReturnValue(pokeballOverride);
|
||||||
|
this.log(`Pokeball override ${enable ? `set to [${pokeballs}]!` : "disabled!"}`);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override the player pokemon's species.
|
||||||
|
* It's preferred to use `startBattle([Species.PKMN1, Species.PKMN2, ...])` if possible.
|
||||||
|
* @param species the {@linkcode Species} to set
|
||||||
* @returns `this`
|
* @returns `this`
|
||||||
*/
|
*/
|
||||||
public starterSpecies(species: Species | number): this {
|
public starterSpecies(species: Species | number): this {
|
||||||
@ -112,8 +140,15 @@ export class OverridesHelper extends GameManagerHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Override the player (pokemons) forms
|
* Override the player pokemons' forms
|
||||||
* @param forms the (pokemon) forms to set
|
* @param forms the forms to set
|
||||||
|
* @example
|
||||||
|
* ```ts
|
||||||
|
* game.override.starterForms({
|
||||||
|
* [Species.KYOGRE]: 1,
|
||||||
|
* [Species.PIKACHU]: 3,
|
||||||
|
* });
|
||||||
|
* ```
|
||||||
* @returns `this`
|
* @returns `this`
|
||||||
*/
|
*/
|
||||||
public starterForms(forms: Partial<Record<Species, number>>): this {
|
public starterForms(forms: Partial<Record<Species, number>>): this {
|
||||||
@ -127,7 +162,7 @@ export class OverridesHelper extends GameManagerHelper {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Override the player's starting modifiers
|
* Override the player's starting modifiers
|
||||||
* @param modifiers the modifiers to set
|
* @param modifiers the {@linkcode ModifierOverride | modifiers} to set
|
||||||
* @returns `this`
|
* @returns `this`
|
||||||
*/
|
*/
|
||||||
public startingModifier(modifiers: ModifierOverride[]): this {
|
public startingModifier(modifiers: ModifierOverride[]): this {
|
||||||
@ -137,8 +172,8 @@ export class OverridesHelper extends GameManagerHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Override the player (pokemon) {@linkcode Abilities | ability}
|
* Override the player pokemon's ability
|
||||||
* @param ability the (pokemon) {@linkcode Abilities | ability} to set
|
* @param ability the {@linkcode Abilities | ability} to set
|
||||||
* @returns `this`
|
* @returns `this`
|
||||||
*/
|
*/
|
||||||
public ability(ability: Abilities): this {
|
public ability(ability: Abilities): this {
|
||||||
@ -148,8 +183,8 @@ export class OverridesHelper extends GameManagerHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Override the player (pokemon) **passive** {@linkcode Abilities | ability}
|
* Override the player pokemon's **passive** ability
|
||||||
* @param passiveAbility the (pokemon) **passive** {@linkcode Abilities | ability} to set
|
* @param passiveAbility the **passive** {@linkcode Abilities | ability} to set
|
||||||
* @returns `this`
|
* @returns `this`
|
||||||
*/
|
*/
|
||||||
public passiveAbility(passiveAbility: Abilities): this {
|
public passiveAbility(passiveAbility: Abilities): this {
|
||||||
@ -159,8 +194,8 @@ export class OverridesHelper extends GameManagerHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Override the player (pokemon) {@linkcode Moves | moves}set
|
* Override the player pokemon's moveset
|
||||||
* @param moveset the {@linkcode Moves | moves}set to set
|
* @param moveset the {@linkcode Moves | moveset} to set
|
||||||
* @returns `this`
|
* @returns `this`
|
||||||
*/
|
*/
|
||||||
public moveset(moveset: Moves | Moves[]): this {
|
public moveset(moveset: Moves | Moves[]): this {
|
||||||
@ -174,9 +209,9 @@ export class OverridesHelper extends GameManagerHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Override the player (pokemon) {@linkcode StatusEffect | status-effect}
|
* Override the player pokemon's status effect
|
||||||
* @param statusEffect the {@linkcode StatusEffect | status-effect} to set
|
* @param statusEffect the {@linkcode StatusEffect | status effect} to set
|
||||||
* @returns
|
* @returns `this`
|
||||||
*/
|
*/
|
||||||
public statusEffect(statusEffect: StatusEffect): this {
|
public statusEffect(statusEffect: StatusEffect): this {
|
||||||
vi.spyOn(Overrides, "STATUS_OVERRIDE", "get").mockReturnValue(statusEffect);
|
vi.spyOn(Overrides, "STATUS_OVERRIDE", "get").mockReturnValue(statusEffect);
|
||||||
@ -210,8 +245,8 @@ export class OverridesHelper extends GameManagerHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Override the {@linkcode WeatherType | weather (type)}
|
* Override the weather
|
||||||
* @param type {@linkcode WeatherType | weather type} to set
|
* @param type The {@linkcode WeatherType} to set
|
||||||
* @returns `this`
|
* @returns `this`
|
||||||
*/
|
*/
|
||||||
public weather(type: WeatherType): this {
|
public weather(type: WeatherType): this {
|
||||||
@ -237,8 +272,8 @@ export class OverridesHelper extends GameManagerHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Override the battle type (single or double)
|
* Override the battle type
|
||||||
* @param battleType battle type to set
|
* @param battleType - The battle type to set ("single" or "double"), `null` to disable
|
||||||
* @returns `this`
|
* @returns `this`
|
||||||
*/
|
*/
|
||||||
public battleType(battleType: "single" | "double" | null): this {
|
public battleType(battleType: "single" | "double" | null): this {
|
||||||
@ -248,8 +283,8 @@ export class OverridesHelper extends GameManagerHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Override the enemy (pokemon) {@linkcode Species | species}
|
* Override the enemy pokemon's species
|
||||||
* @param species the (pokemon) {@linkcode Species | species} to set
|
* @param species the {@linkcode Species} to set
|
||||||
* @returns `this`
|
* @returns `this`
|
||||||
*/
|
*/
|
||||||
public enemySpecies(species: Species | number): this {
|
public enemySpecies(species: Species | number): this {
|
||||||
@ -280,7 +315,7 @@ export class OverridesHelper extends GameManagerHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Override the enemy (pokemon) {@linkcode Abilities | ability}
|
* Override the enemy pokemon's ability
|
||||||
* @param ability the (pokemon) {@linkcode Abilities | ability} to set
|
* @param ability the (pokemon) {@linkcode Abilities | ability} to set
|
||||||
* @returns `this`
|
* @returns `this`
|
||||||
*/
|
*/
|
||||||
@ -291,8 +326,8 @@ export class OverridesHelper extends GameManagerHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Override the enemy (pokemon) **passive** {@linkcode Abilities | ability}
|
* Override the enemy pokemon's **passive** ability
|
||||||
* @param passiveAbility the (pokemon) **passive** {@linkcode Abilities | ability} to set
|
* @param passiveAbility the **passive** {@linkcode Abilities | ability} to set
|
||||||
* @returns `this`
|
* @returns `this`
|
||||||
*/
|
*/
|
||||||
public enemyPassiveAbility(passiveAbility: Abilities): this {
|
public enemyPassiveAbility(passiveAbility: Abilities): this {
|
||||||
@ -302,8 +337,8 @@ export class OverridesHelper extends GameManagerHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Override the enemy (pokemon) {@linkcode Moves | moves}set
|
* Override the enemy pokemon's moveset
|
||||||
* @param moveset the {@linkcode Moves | moves}set to set
|
* @param moveset the {@linkcode Moves | moveset} to set
|
||||||
* @returns `this`
|
* @returns `this`
|
||||||
*/
|
*/
|
||||||
public enemyMoveset(moveset: Moves | Moves[]): this {
|
public enemyMoveset(moveset: Moves | Moves[]): this {
|
||||||
@ -317,7 +352,7 @@ export class OverridesHelper extends GameManagerHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Override the enemy (pokemon) level
|
* Override the enemy pokemon's level
|
||||||
* @param level the level to set
|
* @param level the level to set
|
||||||
* @returns `this`
|
* @returns `this`
|
||||||
*/
|
*/
|
||||||
@ -328,8 +363,8 @@ export class OverridesHelper extends GameManagerHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Override the enemy (pokemon) {@linkcode StatusEffect | status-effect}
|
* Override the enemy pokemon's status effect
|
||||||
* @param statusEffect the {@linkcode StatusEffect | status-effect} to set
|
* @param statusEffect the {@linkcode StatusEffect} to set
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
public enemyStatusEffect(statusEffect: StatusEffect): this {
|
public enemyStatusEffect(statusEffect: StatusEffect): this {
|
||||||
@ -339,8 +374,8 @@ export class OverridesHelper extends GameManagerHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Override the enemy (pokemon) held items
|
* Override the enemy pokemon's held items
|
||||||
* @param items the items to hold
|
* @param items the {@linkcode ModifierOverride | items} to hold
|
||||||
* @returns `this`
|
* @returns `this`
|
||||||
*/
|
*/
|
||||||
public enemyHeldItems(items: ModifierOverride[]): this {
|
public enemyHeldItems(items: ModifierOverride[]): this {
|
||||||
@ -362,7 +397,7 @@ export class OverridesHelper extends GameManagerHelper {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Override the items rolled at the end of a battle
|
* Override the items rolled at the end of a battle
|
||||||
* @param items the items to be rolled
|
* @param items the {@linkcode ModifierOverride | items} to be rolled
|
||||||
* @returns `this`
|
* @returns `this`
|
||||||
*/
|
*/
|
||||||
public itemRewards(items: ModifierOverride[]): this {
|
public itemRewards(items: ModifierOverride[]): this {
|
||||||
@ -420,7 +455,7 @@ export class OverridesHelper extends GameManagerHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Override the enemy (Pokemon) to have the given amount of health segments
|
* Override the enemy Pokemon to have the given amount of health segments
|
||||||
* @param healthSegments the number of segments to give
|
* @param healthSegments the number of segments to give
|
||||||
* - `0` (default): the health segments will be handled like in the game based on wave, level and species
|
* - `0` (default): the health segments will be handled like in the game based on wave, level and species
|
||||||
* - `1`: the Pokemon will not be a boss
|
* - `1`: the Pokemon will not be a boss
|
||||||
@ -462,8 +497,8 @@ export class OverridesHelper extends GameManagerHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Override the encounter chance for a mystery encounter.
|
* Override the encounter tier for a mystery encounter.
|
||||||
* @param tier - The {@linkcode MysteryEncounterTier} to encounter
|
* @param tier What {@linkcode MysteryEncounterTier | tier} of encounter to set
|
||||||
* @returns `this`
|
* @returns `this`
|
||||||
*/
|
*/
|
||||||
public mysteryEncounterTier(tier: MysteryEncounterTier): this {
|
public mysteryEncounterTier(tier: MysteryEncounterTier): this {
|
||||||
@ -474,7 +509,7 @@ export class OverridesHelper extends GameManagerHelper {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Override the encounter that spawns for the scene
|
* Override the encounter that spawns for the scene
|
||||||
* @param encounterType - The {@linkcode MysteryEncounterType} of the encounter
|
* @param encounterType What {@linkcode MysteryEncounterType | type} of encounter to set
|
||||||
* @returns `this`
|
* @returns `this`
|
||||||
*/
|
*/
|
||||||
public mysteryEncounter(encounterType: MysteryEncounterType): this {
|
public mysteryEncounter(encounterType: MysteryEncounterType): this {
|
||||||
|
@ -1,20 +1,20 @@
|
|||||||
import BattleScene from "../battle-scene";
|
import BattleScene from "#app/battle-scene";
|
||||||
import { getPlayerShopModifierTypeOptionsForWave, ModifierTypeOption, TmModifierType } from "../modifier/modifier-type";
|
import { applyChallenges, ChallengeType } from "#app/data/challenge";
|
||||||
import { getPokeballAtlasKey, PokeballType } from "../data/pokeball";
|
import { allMoves } from "#app/data/move";
|
||||||
import { addTextObject, getTextStyleOptions, getModifierTierTextTint, getTextColor, TextStyle } from "./text";
|
import { getPokeballAtlasKey, PokeballType } from "#app/data/pokeball";
|
||||||
import AwaitableUiHandler from "./awaitable-ui-handler";
|
import { HealShopCostModifier, LockModifierTiersModifier, PokemonHeldItemModifier } from "#app/modifier/modifier";
|
||||||
import { Mode } from "./ui";
|
import { getPlayerShopModifierTypeOptionsForWave, ModifierTypeOption, TmModifierType } from "#app/modifier/modifier-type";
|
||||||
import { LockModifierTiersModifier, PokemonHeldItemModifier, HealShopCostModifier } from "../modifier/modifier";
|
|
||||||
import { handleTutorial, Tutorial } from "../tutorial";
|
|
||||||
import { Button } from "#enums/buttons";
|
|
||||||
import MoveInfoOverlay from "./move-info-overlay";
|
|
||||||
import { allMoves } from "../data/move";
|
|
||||||
import * as Utils from "./../utils";
|
|
||||||
import Overrides from "#app/overrides";
|
import Overrides from "#app/overrides";
|
||||||
|
import { handleTutorial, Tutorial } from "#app/tutorial";
|
||||||
|
import { BooleanHolder, formatMoney, NumberHolder } from "#app/utils";
|
||||||
|
import { Button } from "#enums/buttons";
|
||||||
|
import { ShopCursorTarget } from "#enums/shop-cursor-target";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import { ShopCursorTarget } from "#app/enums/shop-cursor-target";
|
|
||||||
import { IntegerHolder } from "./../utils";
|
|
||||||
import Phaser from "phaser";
|
import Phaser from "phaser";
|
||||||
|
import AwaitableUiHandler from "./awaitable-ui-handler";
|
||||||
|
import MoveInfoOverlay from "./move-info-overlay";
|
||||||
|
import { addTextObject, getModifierTierTextTint, getTextColor, getTextStyleOptions, TextStyle } from "./text";
|
||||||
|
import { Mode } from "./ui";
|
||||||
|
|
||||||
export const SHOP_OPTIONS_ROW_LIMIT = 7;
|
export const SHOP_OPTIONS_ROW_LIMIT = 7;
|
||||||
const SINGLE_SHOP_ROW_YOFFSET = 12;
|
const SINGLE_SHOP_ROW_YOFFSET = 12;
|
||||||
@ -189,10 +189,16 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler {
|
|||||||
|
|
||||||
const typeOptions = args[1] as ModifierTypeOption[];
|
const typeOptions = args[1] as ModifierTypeOption[];
|
||||||
const removeHealShop = this.scene.gameMode.hasNoShop;
|
const removeHealShop = this.scene.gameMode.hasNoShop;
|
||||||
const baseShopCost = new IntegerHolder(this.scene.getWaveMoneyAmount(1));
|
const baseShopCost = new NumberHolder(this.scene.getWaveMoneyAmount(1));
|
||||||
|
|
||||||
this.scene.applyModifier(HealShopCostModifier, true, baseShopCost);
|
this.scene.applyModifier(HealShopCostModifier, true, baseShopCost);
|
||||||
|
|
||||||
const shopTypeOptions = !removeHealShop
|
const shopTypeOptions = !removeHealShop
|
||||||
? getPlayerShopModifierTypeOptionsForWave(this.scene.currentBattle.waveIndex, baseShopCost.value)
|
? getPlayerShopModifierTypeOptionsForWave(this.scene.currentBattle.waveIndex, baseShopCost.value, this.scene.gameMode).filter(shopItem => {
|
||||||
|
const isValidForChallenge = new BooleanHolder(true);
|
||||||
|
applyChallenges(this.scene.gameMode, ChallengeType.SHOP_ITEM_BLACKLIST, shopItem, isValidForChallenge);
|
||||||
|
return isValidForChallenge.value;
|
||||||
|
})
|
||||||
: [];
|
: [];
|
||||||
const optionsYOffset = shopTypeOptions.length > SHOP_OPTIONS_ROW_LIMIT ? -SINGLE_SHOP_ROW_YOFFSET : -DOUBLE_SHOP_ROW_YOFFSET;
|
const optionsYOffset = shopTypeOptions.length > SHOP_OPTIONS_ROW_LIMIT ? -SINGLE_SHOP_ROW_YOFFSET : -DOUBLE_SHOP_ROW_YOFFSET;
|
||||||
|
|
||||||
@ -559,7 +565,7 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler {
|
|||||||
}
|
}
|
||||||
const canReroll = this.scene.money >= this.rerollCost;
|
const canReroll = this.scene.money >= this.rerollCost;
|
||||||
|
|
||||||
const formattedMoney = Utils.formatMoney(this.scene.moneyFormat, this.rerollCost);
|
const formattedMoney = formatMoney(this.scene.moneyFormat, this.rerollCost);
|
||||||
|
|
||||||
this.rerollCostText.setText(i18next.t("modifierSelectUiHandler:rerollCost", { formattedMoney }));
|
this.rerollCostText.setText(i18next.t("modifierSelectUiHandler:rerollCost", { formattedMoney }));
|
||||||
this.rerollCostText.setColor(this.getTextColor(canReroll ? TextStyle.MONEY : TextStyle.PARTY_RED));
|
this.rerollCostText.setColor(this.getTextColor(canReroll ? TextStyle.MONEY : TextStyle.PARTY_RED));
|
||||||
@ -828,7 +834,7 @@ class ModifierOption extends Phaser.GameObjects.Container {
|
|||||||
const cost = Overrides.WAIVE_ROLL_FEE_OVERRIDE ? 0 : this.modifierTypeOption.cost;
|
const cost = Overrides.WAIVE_ROLL_FEE_OVERRIDE ? 0 : this.modifierTypeOption.cost;
|
||||||
const textStyle = cost <= scene.money ? TextStyle.MONEY : TextStyle.PARTY_RED;
|
const textStyle = cost <= scene.money ? TextStyle.MONEY : TextStyle.PARTY_RED;
|
||||||
|
|
||||||
const formattedMoney = Utils.formatMoney(scene.moneyFormat, cost);
|
const formattedMoney = formatMoney(scene.moneyFormat, cost);
|
||||||
|
|
||||||
this.itemCostText.setText(i18next.t("modifierSelectUiHandler:itemCost", { formattedMoney }));
|
this.itemCostText.setText(i18next.t("modifierSelectUiHandler:itemCost", { formattedMoney }));
|
||||||
this.itemCostText.setColor(getTextColor(textStyle, false, scene.uiTheme));
|
this.itemCostText.setColor(getTextColor(textStyle, false, scene.uiTheme));
|
||||||
|
Loading…
Reference in New Issue
Block a user