From 610de916a02268f8b245d893ab2ce15843d7faca Mon Sep 17 00:00:00 2001 From: Lugiad Date: Mon, 13 May 2024 20:01:30 +0200 Subject: [PATCH 1/5] Update French starter-select-ui-handler.ts (#821) --- src/locales/fr/starter-select-ui-handler.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/locales/fr/starter-select-ui-handler.ts b/src/locales/fr/starter-select-ui-handler.ts index 3a8bb2e653b..9f4309e40f4 100644 --- a/src/locales/fr/starter-select-ui-handler.ts +++ b/src/locales/fr/starter-select-ui-handler.ts @@ -29,6 +29,6 @@ export const starterSelectUiHandler: SimpleTranslationEntries = { "cycleVariant": "V: » Variants", "enablePassive": "Activer Passif", "disablePassive": "Désactiver Passif", - "locked": "Locked", - "disabled": "Disabled" + "locked": "Verrouillé", + "disabled": "Désactivé" } From fa60e002e89c6d5d5da2f451ac4370aeffb758b6 Mon Sep 17 00:00:00 2001 From: Matt Ross <13306707+mattrossdev@users.noreply.github.com> Date: Mon, 13 May 2024 11:05:09 -0700 Subject: [PATCH 2/5] Fixes some variable damage moves not working with tinted lens (#759) * Fixes some variable damage moves not working with abilities * Rework as new ability attribute * Update variable base power check to original location * formatting * Add tsdoc comments * add floor for potential non int multipliers * Update pokemon.ts --------- Co-authored-by: Benjamin Odom --- src/data/ability.ts | 38 +++++++++++++++++++++++++++++++++++++- src/field/pokemon.ts | 5 ++++- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/src/data/ability.ts b/src/data/ability.ts index 662cd3715eb..fee574e4a5e 100644 --- a/src/data/ability.ts +++ b/src/data/ability.ts @@ -991,6 +991,42 @@ export class MoveTypeChangeAttr extends PreAttackAbAttr { } } +/** + * Class for abilities that boost the damage of moves + * For abilities that boost the base power of moves, see VariableMovePowerAbAttr + * @param damageMultiplier the amount to multiply the damage by + * @param condition the condition for this ability to be applied + */ +export class DamageBoostAbAttr extends PreAttackAbAttr { + private damageMultiplier: number; + private condition: PokemonAttackCondition; + + constructor(damageMultiplier: number, condition: PokemonAttackCondition){ + super(true); + this.damageMultiplier = damageMultiplier; + this.condition = condition; + } + + /** + * + * @param pokemon the attacker pokemon + * @param passive N/A + * @param defender the target pokemon + * @param move the move used by the attacker pokemon + * @param args Utils.NumberHolder as damage + * @returns true if the function succeeds + */ + applyPreAttack(pokemon: Pokemon, passive: boolean, defender: Pokemon, move: PokemonMove, args: any[]): boolean { + if (this.condition(pokemon, defender, move.getMove())) { + const power = args[0] as Utils.NumberHolder; + power.value = Math.floor(power.value * this.damageMultiplier); + return true; + } + + return false; + } +} + export class MovePowerBoostAbAttr extends VariableMovePowerAbAttr { private condition: PokemonAttackCondition; private powerMultiplier: number; @@ -3121,7 +3157,7 @@ export function initAbilities() { .attr(IgnoreOpponentStatChangesAbAttr) .ignorable(), new Ability(Abilities.TINTED_LENS, 4) - .attr(MovePowerBoostAbAttr, (user, target, move) => target.getAttackTypeEffectiveness(move.type, user) <= 0.5, 2), + .attr(DamageBoostAbAttr, 2, (user, target, move) => target.getAttackTypeEffectiveness(move.type, user) <= 0.5), new Ability(Abilities.FILTER, 4) .attr(ReceivedMoveDamageMultiplierAbAttr,(target, user, move) => target.getAttackTypeEffectiveness(move.type, user) >= 2, 0.75) .ignorable(), diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 807be3f8d9d..307f98f2f2d 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -27,7 +27,7 @@ import { TempBattleStat } from '../data/temp-battle-stat'; import { ArenaTagSide, WeakenMoveScreenTag, WeakenMoveTypeTag } from '../data/arena-tag'; import { ArenaTagType } from "../data/enums/arena-tag-type"; import { Biome } from "../data/enums/biome"; -import { Ability, AbAttr, BattleStatMultiplierAbAttr, BlockCritAbAttr, BonusCritAbAttr, BypassBurnDamageReductionAbAttr, FieldPriorityMoveImmunityAbAttr, FieldVariableMovePowerAbAttr, IgnoreOpponentStatChangesAbAttr, MoveImmunityAbAttr, MoveTypeChangeAttr, NonSuperEffectiveImmunityAbAttr, PreApplyBattlerTagAbAttr, PreDefendFullHpEndureAbAttr, ReceivedMoveDamageMultiplierAbAttr, ReduceStatusEffectDurationAbAttr, StabBoostAbAttr, StatusEffectImmunityAbAttr, TypeImmunityAbAttr, VariableMovePowerAbAttr, VariableMoveTypeAbAttr, WeightMultiplierAbAttr, allAbilities, applyAbAttrs, applyBattleStatMultiplierAbAttrs, applyPostDefendAbAttrs, applyPreApplyBattlerTagAbAttrs, applyPreAttackAbAttrs, applyPreDefendAbAttrs, applyPreSetStatusAbAttrs, UnsuppressableAbilityAbAttr, SuppressFieldAbilitiesAbAttr, NoFusionAbilityAbAttr, MultCritAbAttr, IgnoreTypeImmunityAbAttr } from '../data/ability'; +import { Ability, AbAttr, BattleStatMultiplierAbAttr, BlockCritAbAttr, BonusCritAbAttr, BypassBurnDamageReductionAbAttr, FieldPriorityMoveImmunityAbAttr, FieldVariableMovePowerAbAttr, IgnoreOpponentStatChangesAbAttr, MoveImmunityAbAttr, MoveTypeChangeAttr, NonSuperEffectiveImmunityAbAttr, PreApplyBattlerTagAbAttr, PreDefendFullHpEndureAbAttr, ReceivedMoveDamageMultiplierAbAttr, ReduceStatusEffectDurationAbAttr, StabBoostAbAttr, StatusEffectImmunityAbAttr, TypeImmunityAbAttr, VariableMovePowerAbAttr, VariableMoveTypeAbAttr, WeightMultiplierAbAttr, allAbilities, applyAbAttrs, applyBattleStatMultiplierAbAttrs, applyPostDefendAbAttrs, applyPreApplyBattlerTagAbAttrs, applyPreAttackAbAttrs, applyPreDefendAbAttrs, applyPreSetStatusAbAttrs, UnsuppressableAbilityAbAttr, SuppressFieldAbilitiesAbAttr, NoFusionAbilityAbAttr, MultCritAbAttr, IgnoreTypeImmunityAbAttr, DamageBoostAbAttr } from '../data/ability'; import { Abilities } from "#app/data/enums/abilities"; import PokemonData from '../system/pokemon-data'; import Battle, { BattlerIndex } from '../battle'; @@ -1545,6 +1545,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { if (!burnDamageReductionCancelled.value) damage.value = Math.floor(damage.value / 2); } + + applyPreAttackAbAttrs(DamageBoostAbAttr, source, this, battlerMove, damage); + move.getAttrs(HitsTagAttr).map(hta => hta as HitsTagAttr).filter(hta => hta.doubleDamage).forEach(hta => { if (this.getTag(hta.tagType)) damage.value *= 2; From 4e6cf2a6aced2e5d23c4fbe74e03574db7f91431 Mon Sep 17 00:00:00 2001 From: Matt Ross <13306707+mattrossdev@users.noreply.github.com> Date: Mon, 13 May 2024 11:06:15 -0700 Subject: [PATCH 3/5] Facade should ignore burn damage reduction (#530) * Facade should ignore burn damage reduction * update order of burn conditions * remove unnecessary space * undo facade check in apply * Rework facade bypassing burn as move attribute * Only check ability attribute if move attribute was false * Add missing semicolon * Add tsdoc comment * Add comment to burn damage reduction class * Added changes from Discord thread --------- Co-authored-by: Benjamin Odom --- src/data/move.ts | 22 +++++++++++++++++++++- src/field/pokemon.ts | 12 +++++++----- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/data/move.ts b/src/data/move.ts index 2a841a40150..652e832fdd6 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -1353,6 +1353,25 @@ export class BypassSleepAttr extends MoveAttr { } } +/** + * Attribute used for moves that bypass the burn damage reduction of physical moves, currently only facade + * Called during damage calculation + * @param user N/A + * @param target N/A + * @param move Move with this attribute + * @param args Utils.BooleanHolder for burnDamageReductionCancelled + * @returns true if the function succeeds + */ +export class BypassBurnDamageReductionAttr extends MoveAttr { + + /** Prevents the move's damage from being reduced by burn */ + apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { + (args[0] as Utils.BooleanHolder).value = true; + + return true; + } +} + export class WeatherChangeAttr extends MoveEffectAttr { private weatherType: WeatherType; @@ -4904,7 +4923,8 @@ export function initMoves() { .attr(StatChangeAttr, [ BattleStat.ATK, BattleStat.SPATK ], -2), new AttackMove(Moves.FACADE, Type.NORMAL, MoveCategory.PHYSICAL, 70, 100, 20, -1, 0, 3) .attr(MovePowerMultiplierAttr, (user, target, move) => user.status - && (user.status.effect === StatusEffect.BURN || user.status.effect === StatusEffect.POISON || user.status.effect === StatusEffect.TOXIC || user.status.effect === StatusEffect.PARALYSIS) ? 2 : 1), + && (user.status.effect === StatusEffect.BURN || user.status.effect === StatusEffect.POISON || user.status.effect === StatusEffect.TOXIC || user.status.effect === StatusEffect.PARALYSIS) ? 2 : 1) + .attr(BypassBurnDamageReductionAttr), new AttackMove(Moves.FOCUS_PUNCH, Type.FIGHTING, MoveCategory.PHYSICAL, 150, 100, 20, -1, -3, 3) .punchingMove() .ignoresVirtual() diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 307f98f2f2d..245820484bd 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -4,7 +4,7 @@ import { Variant, VariantSet, variantColorCache } from '#app/data/variant'; 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, CounterDamageAttr, StatChangeAttr, RechargeAttr, ChargeAttr, IgnoreWeatherTypeDebuffAttr } 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, CounterDamageAttr, StatChangeAttr, RechargeAttr, ChargeAttr, IgnoreWeatherTypeDebuffAttr, BypassBurnDamageReductionAttr } from "../data/move"; 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'; @@ -1540,10 +1540,12 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { if (!isTypeImmune) { damage.value = Math.ceil(((((2 * source.level / 5 + 2) * power.value * sourceAtk.value / targetDef.value) / 50) + 2) * stabMultiplier.value * typeMultiplier.value * arenaAttackTypeMultiplier.value * screenMultiplier.value * ((this.scene.randBattleSeedInt(15) + 85) / 100) * criticalMultiplier.value); if (isPhysical && source.status && source.status.effect === StatusEffect.BURN) { - const burnDamageReductionCancelled = new Utils.BooleanHolder(false); - applyAbAttrs(BypassBurnDamageReductionAbAttr, source, burnDamageReductionCancelled); - if (!burnDamageReductionCancelled.value) - damage.value = Math.floor(damage.value / 2); + if(!move.getAttrs(BypassBurnDamageReductionAttr).length) { + const burnDamageReductionCancelled = new Utils.BooleanHolder(false); + applyAbAttrs(BypassBurnDamageReductionAbAttr, source, burnDamageReductionCancelled); + if (!burnDamageReductionCancelled.value) + damage.value = Math.floor(damage.value / 2); + } } applyPreAttackAbAttrs(DamageBoostAbAttr, source, this, battlerMove, damage); From 40993793cb7e3ad7e690c3e50d3e858abd1e2e97 Mon Sep 17 00:00:00 2001 From: Matthew Olker Date: Mon, 13 May 2024 14:23:34 -0400 Subject: [PATCH 4/5] Show default icon for missing starter icon --- src/ui/starter-select-ui-handler.ts | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/ui/starter-select-ui-handler.ts b/src/ui/starter-select-ui-handler.ts index 148600b8d31..b9ed8195c0d 100644 --- a/src/ui/starter-select-ui-handler.ts +++ b/src/ui/starter-select-ui-handler.ts @@ -357,6 +357,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { icon.setScale(0.5); icon.setOrigin(0, 0); icon.setFrame(species.getIconId(defaultProps.female, defaultProps.formIndex, defaultProps.shiny, defaultProps.variant)); + this.checkIconId(icon, species, defaultProps.female, defaultProps.formIndex, defaultProps.shiny, defaultProps.variant); icon.setTint(0); this.starterSelectGenIconContainers[g].add(icon); this.iconAnimHandler.addOrUpdate(icon, PokemonIconAnimMode.NONE); @@ -792,6 +793,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { const props = this.scene.gameData.getSpeciesDexAttrProps(species, this.dexAttrCursor); this.starterIcons[this.starterCursors.length].setTexture(species.getIconAtlasKey(props.formIndex, props.shiny, props.variant)); this.starterIcons[this.starterCursors.length].setFrame(species.getIconId(props.female, props.formIndex, props.shiny, props.variant)); + this.checkIconId(this.starterIcons[this.starterCursors.length], species, props.female, props.formIndex, props.shiny, props.variant); this.starterGens.push(this.getGenCursorWithScroll()); this.starterCursors.push(this.cursor); this.starterAttr.push(this.dexAttrCursor); @@ -1306,6 +1308,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { const props = this.scene.gameData.getSpeciesDexAttrProps(this.lastSpecies, dexAttr); const lastSpeciesIcon = (this.starterSelectGenIconContainers[this.lastSpecies.generation - 1].getAt(this.genSpecies[this.lastSpecies.generation - 1].indexOf(this.lastSpecies)) as Phaser.GameObjects.Sprite); lastSpeciesIcon.setTexture(this.lastSpecies.getIconAtlasKey(props.formIndex, props.shiny, props.variant), this.lastSpecies.getIconId(props.female, props.formIndex, props.shiny, props.variant)); + this.checkIconId(lastSpeciesIcon, this.lastSpecies, props.female, props.formIndex, props.shiny, props.variant); this.iconAnimHandler.addOrUpdate(lastSpeciesIcon, PokemonIconAnimMode.NONE); } @@ -1548,12 +1551,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { (this.starterSelectGenIconContainers[this.getGenCursorWithScroll()].getAt(this.cursor) as Phaser.GameObjects.Sprite) .setTexture(species.getIconAtlasKey(formIndex, shiny, variant), species.getIconId(female, formIndex, shiny, variant)); - // Temporary fix to show pokemon's default icon if variant icon doesn't exist - if ((this.starterSelectGenIconContainers[this.getGenCursorWithScroll()].getAt(this.cursor) as Phaser.GameObjects.Sprite).frame.name != species.getIconId(female, formIndex, shiny, variant)) { - console.log(`${species.name}'s variant icon does not exist. Replacing with default.`); - (this.starterSelectGenIconContainers[this.getGenCursorWithScroll()].getAt(this.cursor) as Phaser.GameObjects.Sprite).setTexture(species.getIconAtlasKey(formIndex, false, variant)); - (this.starterSelectGenIconContainers[this.getGenCursorWithScroll()].getAt(this.cursor) as Phaser.GameObjects.Sprite).setFrame(species.getIconId(female, formIndex, false, variant)); - } + this.checkIconId((this.starterSelectGenIconContainers[this.getGenCursorWithScroll()].getAt(this.cursor) as Phaser.GameObjects.Sprite), species, female, formIndex, shiny, variant); this.canCycleShiny = !!(dexEntry.caughtAttr & DexAttr.NON_SHINY && dexEntry.caughtAttr & DexAttr.SHINY); this.canCycleGender = !!(dexEntry.caughtAttr & DexAttr.MALE && dexEntry.caughtAttr & DexAttr.FEMALE); this.canCycleAbility = [ abilityAttr & AbilityAttr.ABILITY_1, (abilityAttr & AbilityAttr.ABILITY_2) && species.ability2, abilityAttr & AbilityAttr.ABILITY_HIDDEN ].filter(a => a).length > 1; @@ -1827,4 +1825,12 @@ export default class StarterSelectUiHandler extends MessageUiHandler { if (this.statsMode) this.toggleStatsMode(false); } + + checkIconId(icon: Phaser.GameObjects.Sprite, species: PokemonSpecies, female, formIndex, shiny, variant) { + if (icon.frame.name != species.getIconId(female, formIndex, shiny, variant)) { + console.log(`${species.name}'s variant icon does not exist. Replacing with default.`); + icon.setTexture(species.getIconAtlasKey(formIndex, false, variant)); + icon.setFrame(species.getIconId(female, formIndex, false, variant)); + } + } } \ No newline at end of file From 487b1d26d140528326ed35272154caa4144b4d66 Mon Sep 17 00:00:00 2001 From: Jannik Tappert <38758606+CodeTappert@users.noreply.github.com> Date: Mon, 13 May 2024 20:24:55 +0200 Subject: [PATCH 5/5] Added german localization to the new entries in starter-select-ui-handler.ts (#822) --- src/locales/de/starter-select-ui-handler.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/locales/de/starter-select-ui-handler.ts b/src/locales/de/starter-select-ui-handler.ts index 5ee3da9db0d..791a7c053d4 100644 --- a/src/locales/de/starter-select-ui-handler.ts +++ b/src/locales/de/starter-select-ui-handler.ts @@ -29,6 +29,6 @@ export const starterSelectUiHandler: SimpleTranslationEntries = { "cycleVariant": "V: Seltenheit ändern", "enablePassive": "Passiv-Skill aktivieren", "disablePassive": "Passiv-Skill deaktivieren", - "locked": "Locked", - "disabled": "Disabled" + "locked": "Gesperrt", + "disabled": "Deaktiviert" } \ No newline at end of file