Merge branch 'beta' into reviverseed

This commit is contained in:
schmidtc1 2025-02-20 20:57:51 -05:00 committed by GitHub
commit 8b044b5363
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 34 additions and 8 deletions

@ -1 +1 @@
Subproject commit 58dda14ee834204c4bd5ece47694a3c068df4b0e Subproject commit ef43efffe5fe454862c350f1b9393c3ad755bcc2

View File

@ -1404,7 +1404,7 @@ export class DamageBoostAbAttr extends PreAttackAbAttr {
applyPreAttack(pokemon: Pokemon, passive: boolean, simulated: boolean, defender: Pokemon, move: Move, args: any[]): boolean { applyPreAttack(pokemon: Pokemon, passive: boolean, simulated: boolean, defender: Pokemon, move: Move, args: any[]): boolean {
if (this.condition(pokemon, defender, move)) { if (this.condition(pokemon, defender, move)) {
const power = args[0] as Utils.NumberHolder; const power = args[0] as Utils.NumberHolder;
power.value = Math.floor(power.value * this.damageMultiplier); power.value = Utils.toDmgValue(power.value * this.damageMultiplier);
return true; return true;
} }

View File

@ -2348,12 +2348,14 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
const maxPower = Math.min(movePool.reduce((v, m) => Math.max(allMoves[m[0]].power, v), 40), 90); const maxPower = Math.min(movePool.reduce((v, m) => Math.max(allMoves[m[0]].power, v), 40), 90);
movePool = movePool.map(m => [ m[0], m[1] * (allMoves[m[0]].category === MoveCategory.STATUS ? 1 : Math.max(Math.min(allMoves[m[0]].power / maxPower, 1), 0.5)) ]); movePool = movePool.map(m => [ m[0], m[1] * (allMoves[m[0]].category === MoveCategory.STATUS ? 1 : Math.max(Math.min(allMoves[m[0]].power / maxPower, 1), 0.5)) ]);
// Weight damaging moves against the lower stat // Weight damaging moves against the lower stat. This uses a non-linear relationship.
// If the higher stat is 1 - 1.09x higher, no change. At higher stat ~1.38x lower stat, off-stat moves have half weight.
// One third weight at ~1.58x higher, one quarter weight at ~1.73x higher, one fifth at ~1.87x, and one tenth at ~2.35x higher.
const atk = this.getStat(Stat.ATK); const atk = this.getStat(Stat.ATK);
const spAtk = this.getStat(Stat.SPATK); const spAtk = this.getStat(Stat.SPATK);
const worseCategory: MoveCategory = atk > spAtk ? MoveCategory.SPECIAL : MoveCategory.PHYSICAL; const worseCategory: MoveCategory = atk > spAtk ? MoveCategory.SPECIAL : MoveCategory.PHYSICAL;
const statRatio = worseCategory === MoveCategory.PHYSICAL ? atk / spAtk : spAtk / atk; const statRatio = worseCategory === MoveCategory.PHYSICAL ? atk / spAtk : spAtk / atk;
movePool = movePool.map(m => [ m[0], m[1] * (allMoves[m[0]].category === worseCategory ? statRatio : 1) ]); movePool = movePool.map(m => [ m[0], m[1] * (allMoves[m[0]].category === worseCategory ? Math.min(Math.pow(statRatio, 3) * 1.3, 1) : 1) ]);
/** The higher this is the more the game weights towards higher level moves. At `0` all moves are equal weight. */ /** The higher this is the more the game weights towards higher level moves. At `0` all moves are equal weight. */
let weightMultiplier = 0.9; let weightMultiplier = 0.9;

View File

@ -3389,7 +3389,7 @@ abstract class EnemyDamageMultiplierModifier extends EnemyPersistentModifier {
* @returns always `true` * @returns always `true`
*/ */
override apply(multiplier: NumberHolder): boolean { override apply(multiplier: NumberHolder): boolean {
multiplier.value = Math.floor(multiplier.value * Math.pow(this.damageMultiplier, this.getStackCount())); multiplier.value = toDmgValue(multiplier.value * Math.pow(this.damageMultiplier, this.getStackCount()));
return true; return true;
} }

View File

@ -1,4 +1,6 @@
import { allMoves } from "#app/data/move"; import { allMoves } from "#app/data/move";
import type { EnemyPersistentModifier } from "#app/modifier/modifier";
import { modifierTypes } from "#app/modifier/modifier-type";
import { Abilities } from "#enums/abilities"; import { Abilities } from "#enums/abilities";
import { ArenaTagType } from "#enums/arena-tag-type"; import { ArenaTagType } from "#enums/arena-tag-type";
import { Moves } from "#enums/moves"; import { Moves } from "#enums/moves";
@ -65,6 +67,28 @@ describe("Battle Mechanics - Damage Calculation", () => {
expect(aggron.hp).toBe(aggron.getMaxHp() - 1); expect(aggron.hp).toBe(aggron.getMaxHp() - 1);
}); });
it("Attacks deal 1 damage at minimum even with many tokens", async () => {
game.override
.startingLevel(1)
.enemySpecies(Species.AGGRON)
.enemyAbility(Abilities.STURDY)
.enemyLevel(10000);
await game.classicMode.startBattle([ Species.SHUCKLE ]);
const dmg_redux_modifier = modifierTypes.ENEMY_DAMAGE_REDUCTION().newModifier() as EnemyPersistentModifier;
dmg_redux_modifier.stackCount = 1000;
await game.scene.addEnemyModifier(modifierTypes.ENEMY_DAMAGE_REDUCTION().newModifier() as EnemyPersistentModifier);
const aggron = game.scene.getEnemyPokemon()!;
game.move.select(Moves.TACKLE);
await game.phaseInterceptor.to("BerryPhase", false);
expect(aggron.hp).toBe(aggron.getMaxHp() - 1);
});
it("Fixed-damage moves ignore damage multipliers", async () => { it("Fixed-damage moves ignore damage multipliers", async () => {
game.override game.override
.enemySpecies(Species.DRAGONITE) .enemySpecies(Species.DRAGONITE)

View File

@ -93,9 +93,9 @@ export default class MoveTouchControlsHandler {
toolbar.innerHTML = ` toolbar.innerHTML = `
<div class="column"> <div class="column">
<div class="button-row"> <div class="button-row">
<div id="resetButton" class="button">${i18next.t("settings:reset")}</div> <div id="resetButton" class="button">${i18next.t("settings:touchReset")}</div>
<div id="saveButton" class="button">${i18next.t("settings:saveClose")}</div> <div id="saveButton" class="button">${i18next.t("settings:touchSaveClose")}</div>
<div id="cancelButton" class="button">${i18next.t("settings:cancel")}</div> <div id="cancelButton" class="button">${i18next.t("settings:touchCancel")}</div>
</div> </div>
<div class="info-row"> <div class="info-row">
<div class="orientation-label"> <div class="orientation-label">