Rebalance friendship and add starter friendship with candy reward

pull/274/merge
Flashfyre 2024-05-02 17:48:08 -04:00
parent dffa9b2704
commit 991f097e9e
6 changed files with 64 additions and 20 deletions

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> { loadAssets(scene: BattleScene, female: boolean, formIndex?: integer, shiny?: boolean, variant?: Variant, startLoad?: boolean): Promise<void> {
return new Promise(resolve => { return new Promise(resolve => {
const spriteKey = this.getSpriteKey(female, formIndex, shiny, variant); 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.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, () => { scene.load.once(Phaser.Loader.Events.COMPLETE, () => {
const originalWarn = console.warn; const originalWarn = console.warn;
// Ignore warnings for missing frames, because there will be a lot // Ignore warnings for missing frames, because there will be a lot
@ -3156,6 +3156,30 @@ export const noStarterFormKeys: string[] = [
SpeciesFormKey.ETERNAMAX SpeciesFormKey.ETERNAMAX
].map(k => k.toString()); ].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 = { export const starterPassiveAbilities = {
[Species.BULBASAUR]: Abilities.SOLAR_POWER, [Species.BULBASAUR]: Abilities.SOLAR_POWER,
[Species.CHARMANDER]: Abilities.INTIMIDATE, [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 BattleInfo, { PlayerBattleInfo, EnemyBattleInfo } from '../ui/battle-info';
import { Moves } from "../data/enums/moves"; 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 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 * as Utils from '../utils';
import { Type, TypeDamageMultiplier, getTypeDamageMultiplier, getTypeRgb } from '../data/type'; import { Type, TypeDamageMultiplier, getTypeDamageMultiplier, getTypeRgb } from '../data/type';
import { getLevelTotalExp } from '../data/exp'; import { getLevelTotalExp } from '../data/exp';
import { Stat } from '../data/pokemon-stat'; 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 { PokeballType } from '../data/pokeball';
import { Gender } from '../data/gender'; import { Gender } from '../data/gender';
import { initMoveAnim, loadMoveAnimAssets } from '../data/battle-anims'; import { initMoveAnim, loadMoveAnimAssets } from '../data/battle-anims';
@ -2368,6 +2368,29 @@ export class PlayerPokemon extends Pokemon {
}); });
} }
addFriendship(friendship: integer): void {
const starterSpeciesId = this.species.getRootSpeciesId();
const starterData = this.scene.gameData.starterData[starterSpeciesId];
const amount = new Utils.IntegerHolder(friendship);
const starterAmount = new Utils.IntegerHolder(friendship * (this.scene.gameMode.isClassic ? 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.friendship = (starterData.friendship || 0) + starterAmount.value;
if (starterData.friendship >= getStarterValueFriendshipCap(speciesStarters[starterSpeciesId])) {
this.scene.gameData.addStarterCandy(getPokemonSpecies(starterSpeciesId), 1);
starterData.friendship = 0;
}
} else {
this.friendship = Math.max(this.friendship + amount.value, 0);
starterData.friendship = Math.max((starterData.friendship || 0) + starterAmount.value, 0);
}
}
getPossibleEvolution(evolution: SpeciesFormEvolution): Promise<Pokemon> { getPossibleEvolution(evolution: SpeciesFormEvolution): Promise<Pokemon> {
return new Promise(resolve => { return new Promise(resolve => {
const evolutionSpecies = getPokemonSpecies(evolution.speciesId); const evolutionSpecies = getPokemonSpecies(evolution.speciesId);

View File

@ -1058,7 +1058,6 @@ const modifierPool: ModifierPool = {
new WeightedModifierType(modifierTypes.ATTACK_TYPE_BOOSTER, 10), new WeightedModifierType(modifierTypes.ATTACK_TYPE_BOOSTER, 10),
new WeightedModifierType(modifierTypes.TM_ULTRA, 8), new WeightedModifierType(modifierTypes.TM_ULTRA, 8),
new WeightedModifierType(modifierTypes.RARER_CANDY, 4), 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.GOLDEN_PUNCH, 2),
new WeightedModifierType(modifierTypes.IV_SCANNER, 4), new WeightedModifierType(modifierTypes.IV_SCANNER, 4),
new WeightedModifierType(modifierTypes.EXP_CHARM, 8), new WeightedModifierType(modifierTypes.EXP_CHARM, 8),
@ -1078,6 +1077,7 @@ const modifierPool: ModifierPool = {
new WeightedModifierType(modifierTypes.BATON, 2), new WeightedModifierType(modifierTypes.BATON, 2),
new WeightedModifierType(modifierTypes.SOUL_DEW, 8), new WeightedModifierType(modifierTypes.SOUL_DEW, 8),
//new WeightedModifierType(modifierTypes.OVAL_CHARM, 6), //new WeightedModifierType(modifierTypes.OVAL_CHARM, 6),
new WeightedModifierType(modifierTypes.SOOTHE_BELL, 4),
new WeightedModifierType(modifierTypes.ABILITY_CHARM, 6), new WeightedModifierType(modifierTypes.ABILITY_CHARM, 6),
new WeightedModifierType(modifierTypes.FOCUS_BAND, 5), new WeightedModifierType(modifierTypes.FOCUS_BAND, 5),
new WeightedModifierType(modifierTypes.KINGS_ROCK, 3), new WeightedModifierType(modifierTypes.KINGS_ROCK, 3),

View File

@ -1111,9 +1111,7 @@ export class PokemonLevelIncrementModifier extends ConsumablePokemonModifier {
pokemon.levelExp = 0; pokemon.levelExp = 0;
} }
const friendshipIncrease = new Utils.IntegerHolder(5); pokemon.addFriendship(5);
pokemon.scene.applyModifier(PokemonFriendshipBoosterModifier, true, pokemon, friendshipIncrease);
pokemon.friendship = Math.min(pokemon.friendship + friendshipIncrease.value, 255);
pokemon.scene.unshiftPhase(new LevelUpPhase(pokemon.scene, pokemon.scene.getParty().indexOf(pokemon), pokemon.level - levelCount.value, pokemon.level)); 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 { 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; return true;
} }
getMaxHeldItemCount(pokemon: Pokemon): integer { 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 { Mode } from './ui/ui';
import { Command } from "./ui/command-ui-handler"; import { Command } from "./ui/command-ui-handler";
import { Stat } from "./data/pokemon-stat"; 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 PartyUiHandler, { PartyOption, PartyUiMode } from "./ui/party-ui-handler";
import { doPokeballBounceAnim, getPokeballAtlasKey, getPokeballCatchMultiplier, getPokeballTintColor, PokeballType } from "./data/pokeball"; import { doPokeballBounceAnim, getPokeballAtlasKey, getPokeballCatchMultiplier, getPokeballTintColor, PokeballType } from "./data/pokeball";
import { CommonAnim, CommonBattleAnim, MoveAnim, initMoveAnim, loadMoveAnimAssets } from "./data/battle-anims"; 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)); this.scene.getField(true).filter(p => p !== pokemon).forEach(p => p.removeTagsBySourceId(pokemon.id));
pokemon.faintCry(() => { pokemon.faintCry(() => {
const friendshipDecrease = new Utils.IntegerHolder(10); if (pokemon instanceof PlayerPokemon)
pokemon.friendship = Math.max(pokemon.friendship - friendshipDecrease.value, 0); pokemon.addFriendship(-10);
pokemon.hideInfo(); pokemon.hideInfo();
this.scene.playSound('faint'); this.scene.playSound('faint');
this.scene.tweens.add({ this.scene.tweens.add({
@ -3226,13 +3226,8 @@ export class VictoryPhase extends PokemonPhase {
for (let partyMember of expPartyMembers) { for (let partyMember of expPartyMembers) {
const pId = partyMember.id; const pId = partyMember.id;
const participated = participantIds.has(pId); const participated = participantIds.has(pId);
if (participated) { if (participated)
const friendshipIncrease = new Utils.IntegerHolder(2); partyMember.addFriendship(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);
}
else if (!expShareModifier) { else if (!expShareModifier) {
partyMemberExp.push(0); partyMemberExp.push(0);
continue; continue;

View File

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