Compare commits

...

7 Commits

Author SHA1 Message Date
Madmadness65
6011794732 Minor egg move fix
Gen 8 fossils unintentionally had Earthquake. They have now been replaced.
2024-05-02 21:58:38 -05:00
Flashfyre
b30ab6136e Starter friendship for candies is split between spliced species 2024-05-02 21:55:11 -04:00
Simoninoo
67431fb83b
Patch Ita (#399)
* Syntax correction

* Tutorial translation
2024-05-02 20:45:45 -04:00
Benjamin Odom
fec8771830 Fix Shedinja Luck and Crash
Shedinja wasn't taking the luck value from Ninjask so when it calculated its luck it just took the entire fused Pokemon's luck somehow. This has been fixed so it takes both the first and second part of the fusion's luck values instead.

Also fixes an issue where Shedinja crashed the game if it was the second part of a fusion combo. Now the correct pokemon species gets checked against and the correct pokemon evolution occurs to create Shedinja.
2024-05-02 17:55:45 -04:00
Flashfyre
991f097e9e Rebalance friendship and add starter friendship with candy reward 2024-05-02 17:48:08 -04:00
maru
dffa9b2704
Add more files to be purged from CF cache on deploy 2024-05-02 15:48:59 -04:00
Benjamin Odom
9d8f7ddcf0
Implement Tailwind (#398)
Added a new ArenaTagType for Tailwind. Lasts 4 turns including the turn used.
2024-05-02 14:10:21 -05:00
13 changed files with 144 additions and 62 deletions

View File

@ -41,4 +41,6 @@ jobs:
files: |
https://pokerogue.net/
https://pokerogue.net/index.html
https://pokerogue.net/manifest.json
https://pokerogue.net/manifest.json
https://pokerogue.net/manifest.webmanifest
https://pokerogue.net/service-worker.js

View File

@ -482,6 +482,20 @@ export class GravityTag extends ArenaTag {
}
}
class TailwindTag extends ArenaTag {
constructor(turnCount: integer, sourceId: integer, side: ArenaTagSide) {
super(ArenaTagType.TAILWIND, turnCount, Moves.TAILWIND, sourceId, side);
}
onAdd(arena: Arena): void {
arena.scene.queueMessage(`The Tailwind blew from behind${this.side === ArenaTagSide.PLAYER ? '\nyour' : this.side === ArenaTagSide.ENEMY ? '\nthe opposing' : ''} team!`);
}
onRemove(arena: Arena): void {
arena.scene.queueMessage(`${this.side === ArenaTagSide.PLAYER ? 'Your' : this.side === ArenaTagSide.ENEMY ? 'The opposing' : ''} team's Tailwind petered out!`);
}
}
export function getArenaTag(tagType: ArenaTagType, turnCount: integer, sourceMove: Moves, sourceId: integer, targetIndex?: BattlerIndex, side: ArenaTagSide = ArenaTagSide.BOTH): ArenaTag {
switch (tagType) {
case ArenaTagType.MIST:
@ -513,5 +527,7 @@ export function getArenaTag(tagType: ArenaTagType, turnCount: integer, sourceMov
return new LightScreenTag(turnCount, sourceId, side);
case ArenaTagType.AURORA_VEIL:
return new AuroraVeilTag(turnCount, sourceId, side);
case ArenaTagType.TAILWIND:
return new TailwindTag(turnCount, sourceId, side);
}
}

View File

@ -458,9 +458,9 @@ export const speciesEggMoves = {
[Species.MORPEKO]: [ Moves.TRIPLE_AXEL, Moves.OBSTRUCT, Moves.PARTING_SHOT, Moves.SWORDS_DANCE ],
[Species.CUFANT]: [ Moves.LIQUIDATION, Moves.HEAVY_SLAM, Moves.CLOSE_COMBAT, Moves.GIGATON_HAMMER ],
[Species.DRACOZOLT]: [ Moves.TRIPLE_AXEL, Moves.DRAGON_HAMMER, Moves.FIRE_LASH, Moves.DRAGON_DANCE ],
[Species.ARCTOZOLT]: [ Moves.TRIPLE_AXEL, Moves.EARTHQUAKE, Moves.HIGH_HORSEPOWER, Moves.SHIFT_GEAR ],
[Species.ARCTOZOLT]: [ Moves.TRIPLE_AXEL, Moves.LIQUIDATION, Moves.HIGH_HORSEPOWER, Moves.SHIFT_GEAR ],
[Species.DRACOVISH]: [ Moves.TRIPLE_AXEL, Moves.DRAGON_HAMMER, Moves.THUNDER_FANG, Moves.DRAGON_DANCE ],
[Species.ARCTOVISH]: [ Moves.TRIPLE_AXEL, Moves.EARTHQUAKE, Moves.HIGH_HORSEPOWER, Moves.SHIFT_GEAR ],
[Species.ARCTOVISH]: [ Moves.TRIPLE_AXEL, Moves.SUPERCELL_SLAM, Moves.HIGH_HORSEPOWER, Moves.SHIFT_GEAR ],
[Species.DURALUDON]: [ Moves.CALM_MIND, Moves.BODY_PRESS, Moves.EARTH_POWER, Moves.RECOVER ],
[Species.DREEPY]: [ Moves.DRAGON_ENERGY, Moves.SHED_TAIL, Moves.BLAZING_TORQUE, Moves.SPECTRAL_THIEF ],
[Species.ZACIAN]: [ Moves.MAGICAL_TORQUE, Moves.BITTER_BLADE, Moves.LEAF_BLADE, Moves.VICTORY_DANCE ],

View File

@ -15,5 +15,6 @@ export enum ArenaTagType {
GRAVITY = "GRAVITY",
REFLECT = "REFLECT",
LIGHT_SCREEN = "LIGHT_SCREEN",
AURORA_VEIL = "AURORA_VEIL"
AURORA_VEIL = "AURORA_VEIL",
TAILWIND = "TAILWIND"
}

View File

@ -4805,8 +4805,8 @@ export function initMoves() {
.partial(),
new StatusMove(Moves.TAILWIND, Type.FLYING, -1, 15, -1, 0, 4)
.windMove()
.target(MoveTarget.USER_SIDE)
.unimplemented(),
.attr(AddArenaTagAttr, ArenaTagType.TAILWIND, 4, true)
.target(MoveTarget.USER_SIDE),
new StatusMove(Moves.ACUPRESSURE, Type.NORMAL, -1, 30, -1, 0, 4)
.attr(StatChangeAttr, BattleStat.RAND, 2)
.target(MoveTarget.USER_OR_NEAR_ALLY),

View File

@ -367,8 +367,8 @@ export abstract class PokemonSpeciesForm {
loadAssets(scene: BattleScene, female: boolean, formIndex?: integer, shiny?: boolean, variant?: Variant, startLoad?: boolean): Promise<void> {
return new Promise(resolve => {
const spriteKey = this.getSpriteKey(female, formIndex, shiny, variant);
scene.load.audio(this.getCryKey(formIndex), `audio/cry/${this.getCryKey(formIndex)}.m4a`);
scene.loadPokemonAtlas(spriteKey, this.getSpriteAtlasPath(female, formIndex, shiny, variant));
scene.load.audio(this.getCryKey(formIndex), `audio/cry/${this.getCryKey(formIndex)}.m4a`);
scene.load.once(Phaser.Loader.Events.COMPLETE, () => {
const originalWarn = console.warn;
// Ignore warnings for missing frames, because there will be a lot
@ -3156,6 +3156,30 @@ export const noStarterFormKeys: string[] = [
SpeciesFormKey.ETERNAMAX
].map(k => k.toString());
export function getStarterValueFriendshipCap(value: integer): integer {
switch (value) {
case 1:
return 20;
case 2:
return 40;
case 3:
return 60;
case 4:
return 100;
case 5:
return 140;
case 6:
return 200;
case 7:
return 280;
case 8:
case 9:
return 450;
default:
return 600;
}
}
export const starterPassiveAbilities = {
[Species.BULBASAUR]: Abilities.SOLAR_POWER,
[Species.CHARMANDER]: Abilities.INTIMIDATE,

View File

@ -5,12 +5,12 @@ import { variantData } from '#app/data/variant';
import BattleInfo, { PlayerBattleInfo, EnemyBattleInfo } from '../ui/battle-info';
import { Moves } from "../data/enums/moves";
import Move, { HighCritAttr, HitsTagAttr, applyMoveAttrs, FixedDamageAttr, VariableAtkAttr, VariablePowerAttr, allMoves, MoveCategory, TypelessAttr, CritOnlyAttr, getMoveTargets, OneHitKOAttr, MultiHitAttr, StatusMoveTypeImmunityAttr, MoveTarget, VariableDefAttr, AttackMove, ModifiedDamageAttr, VariableMoveTypeMultiplierAttr, IgnoreOpponentStatChangesAttr, SacrificialAttr, VariableMoveTypeAttr, VariableMoveCategoryAttr } from "../data/move";
import { default as PokemonSpecies, PokemonSpeciesForm, SpeciesFormKey, getFusedSpeciesName, getPokemonSpecies, getPokemonSpeciesForm, starterPassiveAbilities } from '../data/pokemon-species';
import { default as PokemonSpecies, PokemonSpeciesForm, SpeciesFormKey, getFusedSpeciesName, getPokemonSpecies, getPokemonSpeciesForm, getStarterValueFriendshipCap, speciesStarters, starterPassiveAbilities } from '../data/pokemon-species';
import * as Utils from '../utils';
import { Type, TypeDamageMultiplier, getTypeDamageMultiplier, getTypeRgb } from '../data/type';
import { getLevelTotalExp } from '../data/exp';
import { Stat } from '../data/pokemon-stat';
import { AttackTypeBoosterModifier, DamageMoneyRewardModifier, EnemyDamageBoosterModifier, EnemyDamageReducerModifier, EnemyEndureChanceModifier, EnemyFusionChanceModifier, HiddenAbilityRateBoosterModifier, PokemonBaseStatModifier, PokemonHeldItemModifier, PokemonMultiHitModifier, PokemonNatureWeightModifier, ShinyRateBoosterModifier, SurviveDamageModifier, TempBattleStatBoosterModifier, TerastallizeModifier } from '../modifier/modifier';
import { AttackTypeBoosterModifier, DamageMoneyRewardModifier, EnemyDamageBoosterModifier, EnemyDamageReducerModifier, EnemyEndureChanceModifier, EnemyFusionChanceModifier, HiddenAbilityRateBoosterModifier, PokemonBaseStatModifier, PokemonFriendshipBoosterModifier, PokemonHeldItemModifier, PokemonMultiHitModifier, PokemonNatureWeightModifier, ShinyRateBoosterModifier, SurviveDamageModifier, TempBattleStatBoosterModifier, TerastallizeModifier } from '../modifier/modifier';
import { PokeballType } from '../data/pokeball';
import { Gender } from '../data/gender';
import { initMoveAnim, loadMoveAnimAssets } from '../data/battle-anims';
@ -37,7 +37,7 @@ import PartyUiHandler, { PartyOption, PartyUiMode } from '../ui/party-ui-handler
import SoundFade from 'phaser3-rex-plugins/plugins/soundfade';
import { LevelMoves } from '../data/pokemon-level-moves';
import { DamageAchv, achvs } from '../system/achv';
import { DexAttr, StarterMoveset } from '../system/game-data';
import { DexAttr, StarterDataEntry, StarterMoveset } from '../system/game-data';
import { QuantizerCelebi, argbFromRgba, rgbaFromArgb } from '@material/material-color-utilities';
import { Nature, getNatureStatMultiplier } from '../data/nature';
import { SpeciesFormChange, SpeciesFormChangeActiveTrigger, SpeciesFormChangeMoveLearnedTrigger, SpeciesFormChangePostMoveTrigger, SpeciesFormChangeStatusEffectTrigger } from '../data/pokemon-forms';
@ -589,6 +589,11 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
ret *= 1.5;
break;
case Stat.SPD:
// Check both the player and enemy to see if Tailwind should be multiplying the speed of the Pokemon
if ((this.isPlayer() && this.scene.arena.getTagOnSide(ArenaTagType.TAILWIND, ArenaTagSide.PLAYER))
|| (!this.isPlayer() && this.scene.arena.getTagOnSide(ArenaTagType.TAILWIND, ArenaTagSide.ENEMY)))
ret *= 2;
if (this.getTag(BattlerTagType.SLOW_START))
ret >>= 1;
if (this.status && this.status.effect === StatusEffect.PARALYSIS)
@ -2362,6 +2367,37 @@ export class PlayerPokemon extends Pokemon {
}, PartyUiHandler.FilterNonFainted);
});
}
addFriendship(friendship: integer): void {
const starterSpeciesId = this.species.getRootSpeciesId();
const fusionStarterSpeciesId = this.isFusion() ? this.fusionSpecies.getRootSpeciesId() : 0;
const starterData = [
this.scene.gameData.starterData[starterSpeciesId],
fusionStarterSpeciesId ? this.scene.gameData.starterData[fusionStarterSpeciesId] : null
].filter(d => d);
const amount = new Utils.IntegerHolder(friendship);
const starterAmount = new Utils.IntegerHolder(Math.floor(friendship * (this.scene.gameMode.isClassic ? 2 : 1) / (fusionStarterSpeciesId ? 2 : 1)));
if (amount.value > 0) {
this.scene.applyModifier(PokemonFriendshipBoosterModifier, true, this, amount);
this.scene.applyModifier(PokemonFriendshipBoosterModifier, true, this, starterAmount);
this.friendship = Math.min(this.friendship + amount.value, 255);
if (this.friendship === 255)
this.scene.validateAchv(achvs.MAX_FRIENDSHIP);
starterData.forEach((sd: StarterDataEntry, i: integer) => {
const speciesId = !i ? starterSpeciesId : fusionStarterSpeciesId as Species;
sd.friendship = (sd.friendship || 0) + starterAmount.value;
if (sd.friendship >= getStarterValueFriendshipCap(speciesStarters[speciesId])) {
this.scene.gameData.addStarterCandy(getPokemonSpecies(speciesId), 1);
sd.friendship = 0;
}
});
} else {
this.friendship = Math.max(this.friendship + amount.value, 0);
for (let sd of starterData)
sd.friendship = Math.max((sd.friendship || 0) + starterAmount.value, 0);
}
}
getPossibleEvolution(evolution: SpeciesFormEvolution): Promise<Pokemon> {
return new Promise(resolve => {
@ -2429,12 +2465,17 @@ export class PlayerPokemon extends Pokemon {
private handleSpecialEvolutions(evolution: SpeciesFormEvolution) {
const isFusion = evolution instanceof FusionSpeciesFormEvolution;
if ((!isFusion ? this.species : this.fusionSpecies).speciesId === Species.NINCADA && evolution.speciesId === Species.NINJASK) {
const newEvolution = pokemonEvolutions[this.species.speciesId][1];
const evoSpecies = (!isFusion ? this.species : this.fusionSpecies)
if (evoSpecies.speciesId === Species.NINCADA && evolution.speciesId === Species.NINJASK) {
const newEvolution = pokemonEvolutions[evoSpecies.speciesId][1];
if (newEvolution.condition.predicate(this)) {
const newPokemon = this.scene.addPlayerPokemon(this.species, this.level, this.abilityIndex, this.formIndex, undefined, this.shiny, this.variant, this.ivs, this.nature);
newPokemon.natureOverride = this.natureOverride;
newPokemon.moveset = this.moveset.slice();
newPokemon.luck = this.luck;
newPokemon.fusionSpecies = this.fusionSpecies;
newPokemon.fusionFormIndex = this.fusionFormIndex;
newPokemon.fusionAbilityIndex = this.fusionAbilityIndex;
@ -2442,8 +2483,9 @@ export class PlayerPokemon extends Pokemon {
newPokemon.fusionVariant = this.fusionVariant;
newPokemon.fusionGender = this.fusionGender;
newPokemon.fusionLuck = this.fusionLuck;
this.scene.getParty().push(newPokemon);
newPokemon.evolve(newEvolution);
newPokemon.evolve(!isFusion ? newEvolution : new FusionSpeciesFormEvolution(this.id, newEvolution));
const modifiers = this.scene.findModifiers(m => m instanceof PokemonHeldItemModifier
&& (m as PokemonHeldItemModifier).pokemonId === this.id, true) as PokemonHeldItemModifier[];
modifiers.forEach(m => {

View File

@ -5,7 +5,7 @@ export const pokemonStat: SimpleTranslationEntries = {
"HPshortened": "PS",
"ATK": "Attacco",
"ATKshortened": "Att",
"DEF": "Difensa",
"DEF": "Difesa",
"DEFshortened": "Dif",
"SPATK": "Att. Sp.",
"SPATKshortened": "AttSp",

View File

@ -1,42 +1,42 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const tutorial: SimpleTranslationEntries = {
"intro": `Welcome to PokéRogue! This is a battle-focused Pokémon fangame with roguelite elements.
$This game is not monetized and we claim no ownership of Pokémon nor of the copyrighted assets used.
$The game is a work in progress, but fully playable.\nFor bug reports, please use the Discord community.
$If the game runs slowly, please ensure 'Hardware Acceleration' is turned on in your browser settings.`,
"intro": `Benvenuto in PokéRogue! Questo gioco si concentra sulle battaglie, con elementi roguelite.
$Questo gioco non è monetizzato e non siamo proprietari di Pokemon e Assets presenti nel gioco.
$Il gioco è work-in-progress ma giocabile al 100%.\nPer reportare eventuali bugs è possibile discuterne sul nostro Discord.
$Se il game risulta 'lento', assicurati di aver abilitato l'Accelerazione Hardware nelle impostazioni del tuo Browser`,
"accessMenu": `To access the menu, press M or Escape while awaiting input.\nThe menu contains settings and various features.`,
"accessMenu": `Per accedere al menù, press M o Esc.\nDal menù puoi cambiare impostazioni, controllare la wiki e accedere a varie features.`,
"menu": `From this menu you can access the settings.
$From the settings you can change game speed, window style, and other options.
$There are also various other features here, so be sure to check them all!`,
"menu": `Da questo menù puoi accedere alle impostazioni.
$Dalle impostazioni puoi cambiare velocità di gioco, stile di finestra e altre opzioni.
$Ci sono varie funzionalità, controlla bene e non perderti nulla!`,
"starterSelect": `From this screen, you can select your starters.\nThese are your initial party members.
$Each starter has a value. Your party can have up to\n6 members as long as the total does not exceed 10.
$You can also select gender, ability, and form depending on\nthe variants you've caught or hatched.
$The IVs for a species are also the best of every one you've\ncaught or hatched, so try to get lots of the same species!`,
"starterSelect": `Da questa schermata puoi selezionare il tuo starter.\nQuesti sono i membri iniziali del tuo parti.
$Ogni starter ha un valore. Puoi avere fino a \n6 Pokèmon, avendo a disposizione un massimo di 10 punti.
$Puoi anche selezionare Sesso, Abilità, e Forma a seconda delle\nvarianti che hai catturato o schiuso.
$Le IVs di una specie sono le migliori rispetto a tutte quelle che hai\ncatturato o schiuso, quindi prova a catturarne il piu possibile!`,
"pokerus": `A daily random 3 selectable starters have a purple border.
$If you see a starter you own with one of these,\ntry adding it to your party. Be sure to check its summary!`,
"pokerus": `Giornalmente 3 Starter casuali disponibili avranno il bordo viola.
$Se possiedi uno di questi starter,\nprova ad aggiungerlo al party. Ricorda di controllare le info!`,
"statChange": `Stat changes persist across battles as long as your Pokémon aren't recalled.
$Your Pokémon are recalled before a trainer battle and before entering a new biome.
$You can also view the stat changes for the Pokémon on the field by holding C or Shift.`,
"statChange": `I cambiamenti alle statistiche persistono fintanto che i tuoi pokèmon resteranno in campo.
$I tuoi pokemon verranno richiamati quando incontrerai un allenatore o al cambiamento di bioma.
$Puoi anche vedere i cambiamenti alle statistiche in corso tenendo premuto C o Shift`,
"selectItem": `After every battle, you are given a choice of 3 random items.\nYou may only pick one.
$These range from consumables, to Pokémon held items, to passive permanent items.
$Most non-consumable item effects will stack in various ways.
$Some items will only show up if they can be used, such as evolution items.
$You can also transfer held items between Pokémon using the transfer option.
$The transfer option will appear in the bottom right once you have obtained a held item.
$You may purchase consumable items with money, and a larger variety will be available the further you get.
$Be sure to buy these before you pick your random item, as it will progress to the next battle once you do.`,
"selectItem": `Dopo ogni battaglia avrai disponibili tre item.\nPotrai prenderne solo uno.
$Questi spaziano tra consumabili, item tenuti da Pokèmon o con un effetto passivo permanente.
$La maggior parte degli Item non Consumabili possono stackare in diversi modi.
$Alcuni Item risulteranno disponibili solo se possono essere usati, come Item Evolutivi.
$Puoi anche passare un Item tenuto da un Pokèmon ad un altro attraverso l'opzione 'trasferisci strumento'.
$L'opzione 'trasferisci strumento' sarà disponibile solo dopo aver assegnato uno strumento ad un Pokèmon.
$Puoi acquistare consumabili con le monete, progredendo saranno poi disponibili ulteriori oggetti.
$Assicurati di fare un acquisto prima di selezionare un item casuale, poichè passerai subito alla lotta successiva.`,
"eggGacha": `From this screen, you can redeem your vouchers for\nPokémon eggs.
$Eggs have to be hatched and get closer to hatching after\nevery battle. Rarer eggs take longer to hatch.
$Hatched Pokémon also won't be added to your party, they will\nbe added to your starters.
$Pokémon hatched from eggs generally have better IVs than\nwild Pokémon.
$Some Pokémon can only even be obtained from eggs.
$There are 3 different machines to pull from with different\nbonuses, so pick the one that suits you best!`,
"eggGacha": `Da questa schermata, puoi riscattare i tuoi vouchers in cambio di\nuova Pokèmon.
$Le uova vanno schiuse e saranno sempre più vicine alla schiusura dopo\nogni battaglia. Le uova più rare impiegheranno più battaglie per la schiusura.
$I Pokémon schiusi non verranno aggiunti alla tua squadra, saranno\naggiunti ai tuoi starters.
$I Pokémon schiusi generalmente hanno IVs migliori rispetto ai\n Pokémon selvatici.
$Alcuni Pokémon possono essere ottenuti solo tramite uova.
$Ci sono 3 diversi macchinari con differenti\nbonus, scegli quello che preferisci!`,
} as const;

View File

@ -1058,7 +1058,6 @@ const modifierPool: ModifierPool = {
new WeightedModifierType(modifierTypes.ATTACK_TYPE_BOOSTER, 10),
new WeightedModifierType(modifierTypes.TM_ULTRA, 8),
new WeightedModifierType(modifierTypes.RARER_CANDY, 4),
new WeightedModifierType(modifierTypes.SOOTHE_BELL, (party: Pokemon[]) => party.find(p => (pokemonEvolutions.hasOwnProperty(p.species.speciesId) && pokemonEvolutions[p.species.speciesId].find(e => e.condition && e.condition instanceof SpeciesFriendshipEvolutionCondition)) || p.moveset.find(m => m.moveId === Moves.RETURN)) ? 16 : 0, 16),
new WeightedModifierType(modifierTypes.GOLDEN_PUNCH, 2),
new WeightedModifierType(modifierTypes.IV_SCANNER, 4),
new WeightedModifierType(modifierTypes.EXP_CHARM, 8),
@ -1078,6 +1077,7 @@ const modifierPool: ModifierPool = {
new WeightedModifierType(modifierTypes.BATON, 2),
new WeightedModifierType(modifierTypes.SOUL_DEW, 8),
//new WeightedModifierType(modifierTypes.OVAL_CHARM, 6),
new WeightedModifierType(modifierTypes.SOOTHE_BELL, 4),
new WeightedModifierType(modifierTypes.ABILITY_CHARM, 6),
new WeightedModifierType(modifierTypes.FOCUS_BAND, 5),
new WeightedModifierType(modifierTypes.KINGS_ROCK, 3),

View File

@ -1111,9 +1111,7 @@ export class PokemonLevelIncrementModifier extends ConsumablePokemonModifier {
pokemon.levelExp = 0;
}
const friendshipIncrease = new Utils.IntegerHolder(5);
pokemon.scene.applyModifier(PokemonFriendshipBoosterModifier, true, pokemon, friendshipIncrease);
pokemon.friendship = Math.min(pokemon.friendship + friendshipIncrease.value, 255);
pokemon.addFriendship(5);
pokemon.scene.unshiftPhase(new LevelUpPhase(pokemon.scene, pokemon.scene.getParty().indexOf(pokemon), pokemon.level - levelCount.value, pokemon.level));
@ -1392,13 +1390,14 @@ export class PokemonFriendshipBoosterModifier extends PokemonHeldItemModifier {
}
apply(args: any[]): boolean {
(args[1] as Utils.IntegerHolder).value *= 1 + 0.5 * this.getStackCount();
const friendship = args[1] as Utils.IntegerHolder;
friendship.value = Math.floor(friendship.value * (1 + 0.5 * this.getStackCount()));
return true;
}
getMaxHeldItemCount(pokemon: Pokemon): integer {
return 5;
return 3;
}
}

View File

@ -6,7 +6,7 @@ import { allMoves, applyMoveAttrs, BypassSleepAttr, ChargeAttr, applyFilteredMov
import { Mode } from './ui/ui';
import { Command } from "./ui/command-ui-handler";
import { Stat } from "./data/pokemon-stat";
import { BerryModifier, ContactHeldItemTransferChanceModifier, EnemyAttackStatusEffectChanceModifier, EnemyPersistentModifier, EnemyStatusEffectHealChanceModifier, EnemyTurnHealModifier, ExpBalanceModifier, ExpBoosterModifier, ExpShareModifier, ExtraModifierModifier, FlinchChanceModifier, FusePokemonModifier, HealingBoosterModifier, HitHealModifier, LapsingPersistentModifier, MapModifier, Modifier, MultipleParticipantExpBonusModifier, PersistentModifier, PokemonExpBoosterModifier, PokemonHeldItemModifier, PokemonInstantReviveModifier, SwitchEffectTransferModifier, TempBattleStatBoosterModifier, TurnHealModifier, TurnHeldItemTransferModifier, MoneyMultiplierModifier, MoneyInterestModifier, IvScannerModifier, PokemonFriendshipBoosterModifier, LapsingPokemonHeldItemModifier, PokemonMultiHitModifier, PokemonMoveAccuracyBoosterModifier } from "./modifier/modifier";
import { BerryModifier, ContactHeldItemTransferChanceModifier, EnemyAttackStatusEffectChanceModifier, EnemyPersistentModifier, EnemyStatusEffectHealChanceModifier, EnemyTurnHealModifier, ExpBalanceModifier, ExpBoosterModifier, ExpShareModifier, ExtraModifierModifier, FlinchChanceModifier, FusePokemonModifier, HealingBoosterModifier, HitHealModifier, LapsingPersistentModifier, MapModifier, Modifier, MultipleParticipantExpBonusModifier, PersistentModifier, PokemonExpBoosterModifier, PokemonHeldItemModifier, PokemonInstantReviveModifier, SwitchEffectTransferModifier, TempBattleStatBoosterModifier, TurnHealModifier, TurnHeldItemTransferModifier, MoneyMultiplierModifier, MoneyInterestModifier, IvScannerModifier, LapsingPokemonHeldItemModifier, PokemonMultiHitModifier, PokemonMoveAccuracyBoosterModifier } from "./modifier/modifier";
import PartyUiHandler, { PartyOption, PartyUiMode } from "./ui/party-ui-handler";
import { doPokeballBounceAnim, getPokeballAtlasKey, getPokeballCatchMultiplier, getPokeballTintColor, PokeballType } from "./data/pokeball";
import { CommonAnim, CommonBattleAnim, MoveAnim, initMoveAnim, loadMoveAnimAssets } from "./data/battle-anims";
@ -3154,8 +3154,8 @@ export class FaintPhase extends PokemonPhase {
this.scene.getField(true).filter(p => p !== pokemon).forEach(p => p.removeTagsBySourceId(pokemon.id));
pokemon.faintCry(() => {
const friendshipDecrease = new Utils.IntegerHolder(10);
pokemon.friendship = Math.max(pokemon.friendship - friendshipDecrease.value, 0);
if (pokemon instanceof PlayerPokemon)
pokemon.addFriendship(-10);
pokemon.hideInfo();
this.scene.playSound('faint');
this.scene.tweens.add({
@ -3226,13 +3226,8 @@ export class VictoryPhase extends PokemonPhase {
for (let partyMember of expPartyMembers) {
const pId = partyMember.id;
const participated = participantIds.has(pId);
if (participated) {
const friendshipIncrease = new Utils.IntegerHolder(2);
this.scene.applyModifier(PokemonFriendshipBoosterModifier, true, partyMember, friendshipIncrease);
partyMember.friendship = Math.min(partyMember.friendship + friendshipIncrease.value, 255);
if (partyMember.friendship === 255)
this.scene.validateAchv(achvs.MAX_FRIENDSHIP);
}
if (participated)
partyMember.addFriendship(2);
else if (!expShareModifier) {
partyMemberExp.push(0);
continue;

View File

@ -169,6 +169,7 @@ export interface StarterDataEntry {
moveset: StarterMoveset | StarterFormMoveData;
eggMoves: integer;
candyCount: integer;
friendship: integer;
abilityAttr: integer;
passiveAttr: integer;
valueReduction: integer;
@ -988,6 +989,7 @@ export class GameData {
moveset: null,
eggMoves: 0,
candyCount: 0,
friendship: 0,
abilityAttr: defaultStarterSpecies.includes(speciesId) ? AbilityAttr.ABILITY_1 : 0,
passiveAttr: 0,
valueReduction: 0
@ -1035,6 +1037,7 @@ export class GameData {
const hasPrevolution = pokemonPrevolutions.hasOwnProperty(species.speciesId);
const newCatch = !caughtAttr;
const hasNewAttr = (caughtAttr & dexAttr) !== dexAttr;
if (incrementCount) {
if (!fromEgg) {
@ -1057,7 +1060,7 @@ export class GameData {
this.gameStats.shinyPokemonHatched++;
}
if (!hasPrevolution)
if (!hasPrevolution && (!pokemon.scene.gameMode.isDaily || hasNewAttr))
this.addStarterCandy(species, (1 * (pokemon.isShiny() ? 5 * Math.pow(2, pokemon.variant || 0) : 1)) * (fromEgg || pokemon.isBoss() ? 2 : 1));
}