RNG dumping

This commit is contained in:
RedstonewolfX 2024-08-06 19:38:47 -04:00
parent 83bbb8109a
commit b0e0c24181
8 changed files with 74 additions and 57 deletions

View File

@ -951,8 +951,8 @@ export default class BattleScene extends SceneBase {
this.offsetGym = this.gameMode.isClassic && this.getGeneratedOffsetGym(); this.offsetGym = this.gameMode.isClassic && this.getGeneratedOffsetGym();
} }
randBattleSeedInt(range: integer, min: integer = 0): integer { randBattleSeedInt(range: integer, min: integer = 0, reason?: string): integer {
return this.currentBattle.randSeedInt(this, range, min); return this.currentBattle.randSeedInt(this, range, min, reason);
} }
reset(clearScene: boolean = false, clearData: boolean = false, reloadI18n: boolean = false): void { reset(clearScene: boolean = false, clearData: boolean = false, reloadI18n: boolean = false): void {

View File

@ -378,7 +378,7 @@ export default class Battle {
scene.rngSeedOverride = tempSeedOverride; scene.rngSeedOverride = tempSeedOverride;
} }
randSeedInt(scene: BattleScene, range: integer, min: integer = 0): integer { randSeedInt(scene: BattleScene, range: integer, min: integer = 0, reason: string = "Unlabeled randSeedInt"): integer {
if (range <= 1) { if (range <= 1) {
return min; return min;
} }
@ -394,6 +394,7 @@ export default class Battle {
scene.rngCounter = this.rngCounter++; scene.rngCounter = this.rngCounter++;
scene.rngSeedOverride = this.battleSeed; scene.rngSeedOverride = this.battleSeed;
const ret = Utils.randSeedInt(range, min); const ret = Utils.randSeedInt(range, min);
console.log(reason, ret)
this.battleSeedState = Phaser.Math.RND.state(); this.battleSeedState = Phaser.Math.RND.state();
Phaser.Math.RND.state(state); Phaser.Math.RND.state(state);
//scene.setScoreText("RNG: " + tempRngCounter + " (Last sim: " + this.rngCounter + ")") //scene.setScoreText("RNG: " + tempRngCounter + " (Last sim: " + this.rngCounter + ")")

View File

@ -813,8 +813,8 @@ export class PostDefendContactApplyStatusEffectAbAttr extends PostDefendAbAttr {
} }
applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean { applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean {
if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && !attacker.status && (this.chance === -1 || pokemon.randSeedInt(100) < this.chance)) { if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && !attacker.status && (this.chance === -1 || pokemon.randSeedInt(100, undefined, "Random chance to apply effect after something makes contact") < this.chance)) {
const effect = this.effects.length === 1 ? this.effects[0] : this.effects[pokemon.randSeedInt(this.effects.length)]; const effect = this.effects.length === 1 ? this.effects[0] : this.effects[pokemon.randSeedInt(this.effects.length, undefined, "Selecting an effect to apply")];
return attacker.trySetStatus(effect, true, pokemon); return attacker.trySetStatus(effect, true, pokemon);
} }
@ -849,7 +849,7 @@ export class PostDefendContactApplyTagChanceAbAttr extends PostDefendAbAttr {
} }
applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean { applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean {
if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && pokemon.randSeedInt(100) < this.chance) { if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && pokemon.randSeedInt(100, undefined, "Random chance to apply Battle Tag after something makes contact") < this.chance) {
return attacker.addTag(this.tagType, this.turnCount, move.id, attacker.id); return attacker.addTag(this.tagType, this.turnCount, move.id, attacker.id);
} }
@ -1017,7 +1017,7 @@ export class PostDefendMoveDisableAbAttr extends PostDefendAbAttr {
applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean { applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean {
if (!attacker.summonData.disabledMove) { if (!attacker.summonData.disabledMove) {
if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && (this.chance === -1 || pokemon.randSeedInt(100) < this.chance) && !attacker.isMax()) { if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && (this.chance === -1 || pokemon.randSeedInt(100, undefined, "Chance to disable a move") < this.chance) && !attacker.isMax()) {
this.attacker = attacker; this.attacker = attacker;
this.move = move; this.move = move;
@ -1551,7 +1551,7 @@ export class PostAttackStealHeldItemAbAttr extends PostAttackAbAttr {
if (hitResult < HitResult.NO_EFFECT && (!this.condition || this.condition(pokemon, defender, move))) { if (hitResult < HitResult.NO_EFFECT && (!this.condition || this.condition(pokemon, defender, move))) {
const heldItems = this.getTargetHeldItems(defender).filter(i => i.isTransferrable); const heldItems = this.getTargetHeldItems(defender).filter(i => i.isTransferrable);
if (heldItems.length) { if (heldItems.length) {
const stolenItem = heldItems[pokemon.randSeedInt(heldItems.length)]; const stolenItem = heldItems[pokemon.randSeedInt(heldItems.length, undefined, "Selecting item to steal")];
pokemon.scene.tryTransferHeldItemModifier(stolenItem, pokemon, false).then(success => { pokemon.scene.tryTransferHeldItemModifier(stolenItem, pokemon, false).then(success => {
if (success) { if (success) {
pokemon.scene.queueMessage(i18next.t("abilityTriggers:postAttackStealHeldItem", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), defenderName: defender.name, stolenItemType: stolenItem.type.name })); pokemon.scene.queueMessage(i18next.t("abilityTriggers:postAttackStealHeldItem", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), defenderName: defender.name, stolenItemType: stolenItem.type.name }));
@ -1586,8 +1586,8 @@ export class PostAttackApplyStatusEffectAbAttr extends PostAttackAbAttr {
applyPostAttack(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean { applyPostAttack(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean {
/**Status inflicted by abilities post attacking are also considered additional effects.*/ /**Status inflicted by abilities post attacking are also considered additional effects.*/
if (!attacker.hasAbilityWithAttr(IgnoreMoveEffectsAbAttr) && pokemon !== attacker && (!this.contactRequired || move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon)) && pokemon.randSeedInt(100) < this.chance && !pokemon.status) { if (!attacker.hasAbilityWithAttr(IgnoreMoveEffectsAbAttr) && pokemon !== attacker && (!this.contactRequired || move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon)) && pokemon.randSeedInt(100, undefined, "Chance to apply status after attacking") < this.chance && !pokemon.status) {
const effect = this.effects.length === 1 ? this.effects[0] : this.effects[pokemon.randSeedInt(this.effects.length)]; const effect = this.effects.length === 1 ? this.effects[0] : this.effects[pokemon.randSeedInt(this.effects.length, undefined, "Selecting a status to apply")];
return attacker.trySetStatus(effect, true, pokemon); return attacker.trySetStatus(effect, true, pokemon);
} }
@ -1617,8 +1617,8 @@ export class PostAttackApplyBattlerTagAbAttr extends PostAttackAbAttr {
applyPostAttack(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean { applyPostAttack(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean {
/**Battler tags inflicted by abilities post attacking are also considered additional effects.*/ /**Battler tags inflicted by abilities post attacking are also considered additional effects.*/
if (!attacker.hasAbilityWithAttr(IgnoreMoveEffectsAbAttr) && pokemon !== attacker && (!this.contactRequired || move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon)) && pokemon.randSeedInt(100) < this.chance(attacker, pokemon, move) && !pokemon.status) { if (!attacker.hasAbilityWithAttr(IgnoreMoveEffectsAbAttr) && pokemon !== attacker && (!this.contactRequired || move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon)) && pokemon.randSeedInt(100, undefined, "Random chance to apply a Battle Tag after attacking") < this.chance(attacker, pokemon, move) && !pokemon.status) {
const effect = this.effects.length === 1 ? this.effects[0] : this.effects[pokemon.randSeedInt(this.effects.length)]; const effect = this.effects.length === 1 ? this.effects[0] : this.effects[pokemon.randSeedInt(this.effects.length, undefined, "Selecting which tag to apply")];
return attacker.addTag(effect); return attacker.addTag(effect);
} }
@ -1640,7 +1640,7 @@ export class PostDefendStealHeldItemAbAttr extends PostDefendAbAttr {
if (hitResult < HitResult.NO_EFFECT && (!this.condition || this.condition(pokemon, attacker, move))) { if (hitResult < HitResult.NO_EFFECT && (!this.condition || this.condition(pokemon, attacker, move))) {
const heldItems = this.getTargetHeldItems(attacker).filter(i => i.isTransferrable); const heldItems = this.getTargetHeldItems(attacker).filter(i => i.isTransferrable);
if (heldItems.length) { if (heldItems.length) {
const stolenItem = heldItems[pokemon.randSeedInt(heldItems.length)]; const stolenItem = heldItems[pokemon.randSeedInt(heldItems.length, undefined, "Choosing an item to steal")];
pokemon.scene.tryTransferHeldItemModifier(stolenItem, pokemon, false).then(success => { pokemon.scene.tryTransferHeldItemModifier(stolenItem, pokemon, false).then(success => {
if (success) { if (success) {
pokemon.scene.queueMessage(i18next.t("abilityTriggers:postDefendStealHeldItem", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), attackerName: attacker.name, stolenItemType: stolenItem.type.name })); pokemon.scene.queueMessage(i18next.t("abilityTriggers:postDefendStealHeldItem", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), attackerName: attacker.name, stolenItemType: stolenItem.type.name }));
@ -2387,7 +2387,7 @@ export class ConfusionOnStatusEffectAbAttr extends PostAttackAbAttr {
*/ */
applyPostAttack(pokemon: Pokemon, passive: boolean, defender: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean { applyPostAttack(pokemon: Pokemon, passive: boolean, defender: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean {
if (this.effects.indexOf(args[0]) > -1 && !defender.isFainted()) { if (this.effects.indexOf(args[0]) > -1 && !defender.isFainted()) {
return defender.addTag(BattlerTagType.CONFUSED, pokemon.randSeedInt(3,2), move.id, defender.id); return defender.addTag(BattlerTagType.CONFUSED, pokemon.randSeedInt(3,2, "Duration of Confusion effect"), move.id, defender.id);
} }
return false; return false;
} }
@ -3951,7 +3951,7 @@ export class BypassSpeedChanceAbAttr extends AbAttr {
apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean { apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean {
const bypassSpeed = args[0] as Utils.BooleanHolder; const bypassSpeed = args[0] as Utils.BooleanHolder;
if (!bypassSpeed.value && pokemon.randSeedInt(100) < this.chance) { if (!bypassSpeed.value && pokemon.randSeedInt(100, undefined, "Chance of going first") < this.chance) {
const turnCommand = const turnCommand =
pokemon.scene.currentBattle.turnCommands[pokemon.getBattlerIndex()]; pokemon.scene.currentBattle.turnCommands[pokemon.getBattlerIndex()];
const isCommandFight = turnCommand?.command === Command.FIGHT; const isCommandFight = turnCommand?.command === Command.FIGHT;
@ -4035,7 +4035,7 @@ function applyAbAttrsInternalNoApply<TAttr extends AbAttr>(attrType: Constructor
if (!passive) { if (!passive) {
args[0].value = 0 args[0].value = 0
return resolve(); return resolve();
return applyAbAttrsInternal(attrType, pokemon, applyFunc, args, isAsync, showAbilityInstant, quiet, true).then(() => resolve()); //return applyAbAttrsInternal(attrType, pokemon, applyFunc, args, isAsync, showAbilityInstant, quiet, true).then(() => resolve());
} else { } else {
return resolve(); return resolve();
} }
@ -4049,12 +4049,13 @@ function applyAbAttrsInternalNoApply<TAttr extends AbAttr>(attrType: Constructor
if (!passive) { if (!passive) {
args[0].value = 0 args[0].value = 0
return resolve() return resolve()
return applyAbAttrsInternal(attrType, pokemon, applyFunc, args, isAsync, showAbilityInstant, quiet, true).then(() => resolve()); //return applyAbAttrsInternal(attrType, pokemon, applyFunc, args, isAsync, showAbilityInstant, quiet, true).then(() => resolve());
} else { } else {
return resolve(); return resolve();
} }
}; };
return resolve(); return resolve();
/*
const applyNextAbAttr = () => { const applyNextAbAttr = () => {
if (attrs.length) { if (attrs.length) {
applyAbAttr(attrs.shift()); applyAbAttr(attrs.shift());
@ -4108,6 +4109,7 @@ function applyAbAttrsInternalNoApply<TAttr extends AbAttr>(attrType: Constructor
} }
}; };
applyNextAbAttr(); applyNextAbAttr();
*/
}); });
} }

View File

@ -257,10 +257,10 @@ export class ConfusedTag extends BattlerTag {
pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, pokemon.getBattlerIndex(), undefined, CommonAnim.CONFUSION)); pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, pokemon.getBattlerIndex(), undefined, CommonAnim.CONFUSION));
// 1/3 chance of hitting self with a 40 base power move // 1/3 chance of hitting self with a 40 base power move
if (pokemon.randSeedInt(3) === 0) { if (pokemon.randSeedInt(3, undefined, "Self-hit confusion roll") === 0) {
const atk = pokemon.getBattleStat(Stat.ATK); const atk = pokemon.getBattleStat(Stat.ATK);
const def = pokemon.getBattleStat(Stat.DEF); const def = pokemon.getBattleStat(Stat.DEF);
const damage = Math.ceil(((((2 * pokemon.level / 5 + 2) * 40 * atk / def) / 50) + 2) * (pokemon.randSeedInt(15, 85) / 100)); const damage = Math.ceil(((((2 * pokemon.level / 5 + 2) * 40 * atk / def) / 50) + 2) * (pokemon.randSeedInt(15, 85, "Damage roll for Confusion") / 100));
pokemon.scene.queueMessage(i18next.t("battle:battlerTagsConfusedLapseHurtItself")); pokemon.scene.queueMessage(i18next.t("battle:battlerTagsConfusedLapseHurtItself"));
pokemon.damageAndUpdate(damage); pokemon.damageAndUpdate(damage);
pokemon.battleData.hitCount++; pokemon.battleData.hitCount++;
@ -362,7 +362,7 @@ export class InfatuatedTag extends BattlerTag {
); );
pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, pokemon.getBattlerIndex(), undefined, CommonAnim.ATTRACT)); pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, pokemon.getBattlerIndex(), undefined, CommonAnim.ATTRACT));
if (pokemon.randSeedInt(2)) { if (pokemon.randSeedInt(2, undefined, "Chance to fail attack from Infatuation")) {
pokemon.scene.queueMessage(i18next.t("battle:battlerTagsInfatuatedLapseImmobilize", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); pokemon.scene.queueMessage(i18next.t("battle:battlerTagsInfatuatedLapseImmobilize", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
(pokemon.scene.getCurrentPhase() as MovePhase).cancel(); (pokemon.scene.getCurrentPhase() as MovePhase).cancel();
} }
@ -492,7 +492,7 @@ export class FrenzyTag extends BattlerTag {
super.onRemove(pokemon); super.onRemove(pokemon);
if (this.turnCount < 2) { // Only add CONFUSED tag if a disruption occurs on the final confusion-inducing turn of FRENZY if (this.turnCount < 2) { // Only add CONFUSED tag if a disruption occurs on the final confusion-inducing turn of FRENZY
pokemon.addTag(BattlerTagType.CONFUSED, pokemon.randSeedIntRange(2, 4)); pokemon.addTag(BattlerTagType.CONFUSED, pokemon.randSeedIntRange(2, 4, "Frenzy confusion effect"));
} }
} }
} }

View File

@ -1933,7 +1933,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
} }
console.log(`crit stage: +${critLevel.value}`); console.log(`crit stage: +${critLevel.value}`);
const critChance = [24, 8, 2, 1][Math.max(0, Math.min(critLevel.value, 3))]; const critChance = [24, 8, 2, 1][Math.max(0, Math.min(critLevel.value, 3))];
isCritical = !source.getTag(BattlerTagType.NO_CRIT) && (critChance === 1 || !this.scene.randBattleSeedInt(critChance)); isCritical = !source.getTag(BattlerTagType.NO_CRIT) && (critChance === 1 || !this.scene.randBattleSeedInt(critChance, undefined, "Crit Chance"));
if (Overrides.NEVER_CRIT_OVERRIDE) { if (Overrides.NEVER_CRIT_OVERRIDE) {
isCritical = false; isCritical = false;
} }
@ -1985,7 +1985,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
if (!isTypeImmune) { if (!isTypeImmune) {
const levelMultiplier = (2 * source.level / 5 + 2); const levelMultiplier = (2 * source.level / 5 + 2);
const randomMultiplier = ((this.scene.randBattleSeedInt(16) + 85) / 100); const randomMultiplier = ((this.scene.randBattleSeedInt(16, undefined, "Random damage roll") + 85) / 100);
damage.value = Math.ceil((((levelMultiplier * power * sourceAtk.value / targetDef.value) / 50) + 2) damage.value = Math.ceil((((levelMultiplier * power * sourceAtk.value / targetDef.value) / 50) + 2)
* stabMultiplier.value * stabMultiplier.value
* typeMultiplier.value * typeMultiplier.value
@ -2688,7 +2688,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
let statusCureTurn: Utils.IntegerHolder; let statusCureTurn: Utils.IntegerHolder;
if (effect === StatusEffect.SLEEP) { if (effect === StatusEffect.SLEEP) {
statusCureTurn = new Utils.IntegerHolder(this.randSeedIntRange(2, 4)); statusCureTurn = new Utils.IntegerHolder(this.randSeedIntRange(2, 4, "Random sleep turns"));
applyAbAttrs(ReduceStatusEffectDurationAbAttr, this, null, effect, statusCureTurn); applyAbAttrs(ReduceStatusEffectDurationAbAttr, this, null, effect, statusCureTurn);
this.setFrameRate(4); this.setFrameRate(4);
@ -3100,14 +3100,14 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
fusionCanvas.remove(); fusionCanvas.remove();
} }
randSeedInt(range: integer, min: integer = 0): integer { randSeedInt(range: integer, min: integer = 0, reason: string = "Pokémon randSeedInt"): integer {
return this.scene.currentBattle return this.scene.currentBattle
? this.scene.randBattleSeedInt(range, min) ? this.scene.randBattleSeedInt(range, min, reason)
: Utils.randSeedInt(range, min); : Utils.randSeedInt(range, min, reason);
} }
randSeedIntRange(min: integer, max: integer): integer { randSeedIntRange(min: integer, max: integer, reason: string = "Pokémon randSeedInt"): integer {
return this.randSeedInt((max - min) + 1, min); return this.randSeedInt((max - min) + 1, min, reason);
} }
destroy(): void { destroy(): void {
@ -3701,7 +3701,7 @@ export class EnemyPokemon extends Pokemon {
} }
switch (this.aiType) { switch (this.aiType) {
case AiType.RANDOM: case AiType.RANDOM:
var i = this.scene.randBattleSeedInt(movePool.length) var i = this.scene.randBattleSeedInt(movePool.length, undefined, "Move selection roll (RANDOM)")
const moveId = movePool[i].moveId; const moveId = movePool[i].moveId;
this.flyout.setText(i) this.flyout.setText(i)
return { move: moveId, targets: this.getNextTargets(moveId) }; return { move: moveId, targets: this.getNextTargets(moveId) };
@ -3766,12 +3766,12 @@ export class EnemyPokemon extends Pokemon {
}); });
let r = 0; let r = 0;
if (this.aiType === AiType.SMART_RANDOM) { if (this.aiType === AiType.SMART_RANDOM) {
while (r < sortedMovePool.length - 1 && this.scene.randBattleSeedInt(8) >= 5) { while (r < sortedMovePool.length - 1 && this.scene.randBattleSeedInt(8, undefined, "Move selection roll (SMART_RANDOM)") >= 5) {
r++; r++;
} }
} else if (this.aiType === AiType.SMART) { } else if (this.aiType === AiType.SMART) {
while (r < sortedMovePool.length - 1 && (moveScores[movePool.indexOf(sortedMovePool[r + 1])] / moveScores[movePool.indexOf(sortedMovePool[r])]) >= 0 while (r < sortedMovePool.length - 1 && (moveScores[movePool.indexOf(sortedMovePool[r + 1])] / moveScores[movePool.indexOf(sortedMovePool[r])]) >= 0
&& this.scene.randBattleSeedInt(100) < Math.round((moveScores[movePool.indexOf(sortedMovePool[r + 1])] / moveScores[movePool.indexOf(sortedMovePool[r])]) * 50)) { && this.scene.randBattleSeedInt(100, undefined, "Move selection roll (SMART)") < Math.round((moveScores[movePool.indexOf(sortedMovePool[r + 1])] / moveScores[movePool.indexOf(sortedMovePool[r])]) * 50)) {
r++; r++;
} }
} }
@ -3836,7 +3836,7 @@ export class EnemyPokemon extends Pokemon {
return total; return total;
}, 0); }, 0);
const randValue = this.scene.randBattleSeedInt(totalWeight); const randValue = this.scene.randBattleSeedInt(totalWeight, undefined, "Random target selection");
let targetIndex: integer; let targetIndex: integer;
thresholds.every((t, i) => { thresholds.every((t, i) => {

View File

@ -1050,7 +1050,7 @@ export class SurviveDamageModifier extends PokemonHeldItemModifier {
const pokemon = args[0] as Pokemon; const pokemon = args[0] as Pokemon;
const surviveDamage = args[1] as Utils.BooleanHolder; const surviveDamage = args[1] as Utils.BooleanHolder;
if (!surviveDamage.value && pokemon.randSeedInt(10) < this.getStackCount()) { if (!surviveDamage.value && pokemon.randSeedInt(10, undefined, "Chance to endure an attack") < this.getStackCount()) {
surviveDamage.value = true; surviveDamage.value = true;
pokemon.scene.queueMessage(i18next.t("modifier:surviveDamageApply", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), typeName: this.type.name })); pokemon.scene.queueMessage(i18next.t("modifier:surviveDamageApply", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), typeName: this.type.name }));
@ -1086,7 +1086,7 @@ export class BypassSpeedChanceModifier extends PokemonHeldItemModifier {
const pokemon = args[0] as Pokemon; const pokemon = args[0] as Pokemon;
const bypassSpeed = args[1] as Utils.BooleanHolder; const bypassSpeed = args[1] as Utils.BooleanHolder;
if (!bypassSpeed.value && pokemon.randSeedInt(10) < this.getStackCount()) { if (!bypassSpeed.value && pokemon.randSeedInt(10, undefined, "Chance to activate Quick Claw") < this.getStackCount()) {
bypassSpeed.value = true; bypassSpeed.value = true;
const isCommandFight = pokemon.scene.currentBattle.turnCommands[pokemon.getBattlerIndex()]?.command === Command.FIGHT; const isCommandFight = pokemon.scene.currentBattle.turnCommands[pokemon.getBattlerIndex()]?.command === Command.FIGHT;
const hasQuickClaw = this.type instanceof ModifierTypes.PokemonHeldItemModifierType && this.type.id === "QUICK_CLAW"; const hasQuickClaw = this.type instanceof ModifierTypes.PokemonHeldItemModifierType && this.type.id === "QUICK_CLAW";
@ -1126,7 +1126,7 @@ export class FlinchChanceModifier extends PokemonHeldItemModifier {
const pokemon = args[0] as Pokemon; const pokemon = args[0] as Pokemon;
const flinched = args[1] as Utils.BooleanHolder; const flinched = args[1] as Utils.BooleanHolder;
if (!flinched.value && pokemon.randSeedInt(10) < (this.getStackCount() * this.getSecondaryChanceMultiplier(pokemon))) { if (!flinched.value && pokemon.randSeedInt(10, undefined, "Chance to flinch") < (this.getStackCount() * this.getSecondaryChanceMultiplier(pokemon))) {
flinched.value = true; flinched.value = true;
return true; return true;
} }
@ -1356,7 +1356,7 @@ export class PreserveBerryModifier extends PersistentModifier {
apply(args: any[]): boolean { apply(args: any[]): boolean {
if (!(args[1] as Utils.BooleanHolder).value) { if (!(args[1] as Utils.BooleanHolder).value) {
(args[1] as Utils.BooleanHolder).value = (args[0] as Pokemon).randSeedInt(10) < this.getStackCount() * 3; (args[1] as Utils.BooleanHolder).value = (args[0] as Pokemon).randSeedInt(10, undefined, "Chance to save a berry") < this.getStackCount() * 3;
} }
return true; return true;
@ -2284,7 +2284,7 @@ export abstract class HeldItemTransferModifier extends PokemonHeldItemModifier {
return false; return false;
} }
const targetPokemon = opponents[pokemon.randSeedInt(opponents.length)]; const targetPokemon = opponents[pokemon.randSeedInt(opponents.length, undefined, "Chance to steal/transfer an item")];
const transferredItemCount = this.getTransferredItemCount(); const transferredItemCount = this.getTransferredItemCount();
if (!transferredItemCount) { if (!transferredItemCount) {
@ -2310,7 +2310,7 @@ export abstract class HeldItemTransferModifier extends PokemonHeldItemModifier {
break; break;
} }
} }
const randItemIndex = pokemon.randSeedInt(itemModifiers.length); const randItemIndex = pokemon.randSeedInt(itemModifiers.length, undefined, "Choosing an item to steal");
const randItem = itemModifiers[randItemIndex]; const randItem = itemModifiers[randItemIndex];
heldItemTransferPromises.push(pokemon.scene.tryTransferHeldItemModifier(randItem, pokemon, false).then(success => { heldItemTransferPromises.push(pokemon.scene.tryTransferHeldItemModifier(randItem, pokemon, false).then(success => {
if (success) { if (success) {

View File

@ -4160,7 +4160,7 @@ export class MovePhase extends BattlePhase {
switch (this.pokemon.status.effect) { switch (this.pokemon.status.effect) {
case StatusEffect.PARALYSIS: case StatusEffect.PARALYSIS:
if (!this.pokemon.randSeedInt(4)) { if (!this.pokemon.randSeedInt(4, undefined, "Paralysis chance")) {
activated = true; activated = true;
this.cancelled = true; this.cancelled = true;
} }
@ -4172,7 +4172,7 @@ export class MovePhase extends BattlePhase {
this.cancelled = activated; this.cancelled = activated;
break; break;
case StatusEffect.FREEZE: case StatusEffect.FREEZE:
healed = !!this.move.getMove().findAttr(attr => attr instanceof HealStatusEffectAttr && attr.selfTarget && attr.isOfEffect(StatusEffect.FREEZE)) || !this.pokemon.randSeedInt(5); healed = !!this.move.getMove().findAttr(attr => attr instanceof HealStatusEffectAttr && attr.selfTarget && attr.isOfEffect(StatusEffect.FREEZE)) || !this.pokemon.randSeedInt(5, undefined, "Chance to thaw out from freeze");
activated = !healed; activated = !healed;
this.cancelled = activated; this.cancelled = activated;
break; break;
@ -4471,7 +4471,7 @@ export class MoveEffectPhase extends PokemonPhase {
} }
const accuracyMultiplier = user.getAccuracyMultiplier(target, this.move.getMove()); const accuracyMultiplier = user.getAccuracyMultiplier(target, this.move.getMove());
const rand = user.randSeedInt(100, 1); const rand = user.randSeedInt(100, 1, "Accuracy roll");
return rand <= moveAccuracy * accuracyMultiplier; return rand <= moveAccuracy * accuracyMultiplier;
} }
@ -4779,7 +4779,7 @@ export class StatChangePhase extends PokemonPhase {
getRandomStat(): BattleStat { getRandomStat(): BattleStat {
const allStats = Utils.getEnumValues(BattleStat); const allStats = Utils.getEnumValues(BattleStat);
return allStats[this.getPokemon().randSeedInt(BattleStat.SPD + 1)]; return allStats[this.getPokemon().randSeedInt(BattleStat.SPD + 1, undefined, "Randomly selecting a stat")];
} }
aggregateStatChanges(random: boolean = false): void { aggregateStatChanges(random: boolean = false): void {
@ -6382,7 +6382,7 @@ export class AttemptCapturePhase extends PokemonPhase {
} }
roll(y?: integer) { roll(y?: integer) {
var roll = (this.getPokemon() as EnemyPokemon).randSeedInt(65536) var roll = (this.getPokemon() as EnemyPokemon).randSeedInt(65536, undefined, "Capture roll")
if (y != undefined) { if (y != undefined) {
console.log(roll, y, roll < y) console.log(roll, y, roll < y)
} else { } else {
@ -6679,7 +6679,7 @@ export class AttemptRunPhase extends PokemonPhase {
const escapeChance = new Utils.IntegerHolder((((playerPokemon.getStat(Stat.SPD) * 128) / enemySpeed) + (30 * this.scene.currentBattle.escapeAttempts++)) % 256); const escapeChance = new Utils.IntegerHolder((((playerPokemon.getStat(Stat.SPD) * 128) / enemySpeed) + (30 * this.scene.currentBattle.escapeAttempts++)) % 256);
applyAbAttrs(RunSuccessAbAttr, playerPokemon, null, escapeChance); applyAbAttrs(RunSuccessAbAttr, playerPokemon, null, escapeChance);
if (playerPokemon.randSeedInt(256) < escapeChance.value) { if (playerPokemon.randSeedInt(256, undefined, "Run attempt") < escapeChance.value) {
this.scene.playSound("flee"); this.scene.playSound("flee");
LoggerTools.logShop(this.scene, this.scene.currentBattle.waveIndex, "Fled") LoggerTools.logShop(this.scene, this.scene.currentBattle.waveIndex, "Fled")
this.scene.queueMessage(i18next.t("battle:runAwaySuccess"), null, true, 500); this.scene.queueMessage(i18next.t("battle:runAwaySuccess"), null, true, 500);

View File

@ -76,18 +76,22 @@ export function padInt(value: integer, length: integer, padWith?: string): strin
* @param range The amount of possible numbers * @param range The amount of possible numbers
* @param min The starting number * @param min The starting number
*/ */
export function randInt(range: integer, min: integer = 0): integer { export function randInt(range: integer, min: integer = 0, reason?: string): integer {
if (range === 1) { if (range === 1) {
return min; return min;
} }
return Math.floor(Math.random() * range) + min; let V = Math.floor(Math.random() * range) + min;
//console.log(reason ? reason : "randInt", V)
return V;
} }
export function randSeedInt(range: integer, min: integer = 0): integer { export function randSeedInt(range: integer, min: integer = 0, reason?: string): integer {
if (range <= 1) { if (range <= 1) {
return min; return min;
} }
return Phaser.Math.RND.integerInRange(min, (range - 1) + min); let V = Phaser.Math.RND.integerInRange(min, (range - 1) + min);
//console.log(reason ? reason : "randSeedInt", V)
return V;
} }
/** /**
@ -95,26 +99,36 @@ export function randSeedInt(range: integer, min: integer = 0): integer {
* @param min The lowest number * @param min The lowest number
* @param max The highest number * @param max The highest number
*/ */
export function randIntRange(min: integer, max: integer): integer { export function randIntRange(min: integer, max: integer, reason?: string): integer {
return randInt(max - min, min); return randInt(max - min, min, reason ? reason : "randIntRange");
} }
export function randItem<T>(items: T[]): T { export function randItem<T>(items: T[], reason?: string): T {
return items.length === 1 return items.length === 1
? items[0] ? items[0]
: items[randInt(items.length)]; : items[randInt(items.length, undefined, reason ? reason : "randItem")];
} }
export function randSeedItem<T>(items: T[]): T { export function randSeedItem<T>(items: T[], reason?: string): T {
function rpick() {
let V = Phaser.Math.RND.pick(items)
//console.log(reason ? reason : "randSeedItem")
return V;
}
return items.length === 1 return items.length === 1
? items[0] ? items[0]
: Phaser.Math.RND.pick(items); : rpick();
} }
export function randSeedWeightedItem<T>(items: T[]): T { export function randSeedWeightedItem<T>(items: T[], reason?: string): T {
function rpick() {
let V = Phaser.Math.RND.weightedPick(items);
//console.log(reason ? reason : "randSeedWeightedItem")
return V;
}
return items.length === 1 return items.length === 1
? items[0] ? items[0]
: Phaser.Math.RND.weightedPick(items); : rpick();
} }
export function randSeedEasedWeightedItem<T>(items: T[], easingFunction: string = "Sine.easeIn"): T { export function randSeedEasedWeightedItem<T>(items: T[], easingFunction: string = "Sine.easeIn"): T {