mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-07-05 16:02:20 +02:00
Compare commits
8 Commits
1312d4f825
...
9013921523
Author | SHA1 | Date | |
---|---|---|---|
|
9013921523 | ||
|
a815b73d96 | ||
|
4cce8a1bfa | ||
|
5568def1a4 | ||
|
209a69d098 | ||
|
9c1a13eb54 | ||
|
a18d796e2e | ||
|
4fcc3ef9ff |
@ -146,13 +146,13 @@ body {
|
||||
margin-left: 10%;
|
||||
}
|
||||
|
||||
#touchControls:not([data-ui-mode='STARTER_SELECT']):not([data-ui-mode='SETTINGS']):not([data-ui-mode='SETTINGS_DISPLAY']):not([data-ui-mode='SETTINGS_AUDIO']):not([data-ui-mode='SETTINGS_GAMEPAD']):not([data-ui-mode='SETTINGS_KEYBOARD']) #apad .apadRectBtnContainer > .apadSqBtn,
|
||||
#touchControls:not([data-ui-mode='STARTER_SELECT']):not([data-ui-mode='SETTINGS']):not([data-ui-mode='SETTINGS_DISPLAY']):not([data-ui-mode='SETTINGS_AUDIO']):not([data-ui-mode='SETTINGS_GAMEPAD']):not([data-ui-mode='SETTINGS_KEYBOARD']) #apad .apadSqBtnContainer
|
||||
#touchControls:not([data-ui-mode='STARTER_SELECT']):not([data-ui-mode='SETTINGS']):not([data-ui-mode='SETTINGS_DISPLAY']):not([data-ui-mode='SETTINGS_AUDIO']):not([data-ui-mode='SETTINGS_GAMEPAD']):not([data-ui-mode='SETTINGS_KEYBOARD']) #apad .apadRectBtnContainer > .apadSqBtn:not(.apadBattle),
|
||||
#touchControls:not([data-ui-mode='STARTER_SELECT']):not([data-ui-mode='SETTINGS']):not([data-ui-mode='SETTINGS_DISPLAY']):not([data-ui-mode='SETTINGS_AUDIO']):not([data-ui-mode='SETTINGS_GAMEPAD']):not([data-ui-mode='SETTINGS_KEYBOARD']) #apad .apadSqBtnContainer > .apadSqBtn:not(.apadBattle)
|
||||
{
|
||||
display: none;
|
||||
}
|
||||
|
||||
#touchControls:not([data-ui-mode='COMMAND']):not([data-ui-mode='FIGHT']):not([data-ui-mode='BALL']):not([data-ui-mode='TARGET_SELECT']) #apad .apadBattle {
|
||||
#touchControls:not([data-ui-mode='COMMAND']):not([data-ui-mode='FIGHT']):not([data-ui-mode='BALL']):not([data-ui-mode='TARGET_SELECT']):not([data-ui-mode='MODIFIER_SELECT']) #apad .apadBattle {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
217
src/data/move.ts
217
src/data/move.ts
@ -42,7 +42,7 @@ export enum MoveTarget {
|
||||
/** {@link https://bulbapedia.bulbagarden.net/wiki/Category:Moves_that_target_all_adjacent_Pok%C3%A9mon Moves that target all adjacent Pokemon} */
|
||||
ALL_NEAR_OTHERS,
|
||||
NEAR_ENEMY,
|
||||
/** {@link https://bulbapedia.bulbagarden.net/wiki/Category:Moves_that_target_all_adjacent_foes Moves that taret all adjacent foes} */
|
||||
/** {@link https://bulbapedia.bulbagarden.net/wiki/Category:Moves_that_target_all_adjacent_foes Moves that target all adjacent foes} */
|
||||
ALL_NEAR_ENEMIES,
|
||||
RANDOM_NEAR_ENEMY,
|
||||
ALL_ENEMIES,
|
||||
@ -166,10 +166,22 @@ export default class Move implements Localizable {
|
||||
return this.attrs.some((attr) => attr instanceof attrType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes as input a boolean function and returns the first MoveAttr in attrs that matches true
|
||||
* @param attrPredicate
|
||||
* @returns the first {@linkcode MoveAttr} element in attrs that makes the input function return true
|
||||
*/
|
||||
findAttr(attrPredicate: (attr: MoveAttr) => boolean): MoveAttr {
|
||||
return this.attrs.find(attrPredicate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new MoveAttr to the move (appends to the attr array)
|
||||
* if the MoveAttr also comes with a condition, also adds that to the conditions array: {@linkcode MoveCondition}
|
||||
* @param AttrType {@linkcode MoveAttr} the constructor of a MoveAttr class
|
||||
* @param args the args needed to instantiate a the given class
|
||||
* @returns the called object {@linkcode Move}
|
||||
*/
|
||||
attr<T extends new (...args: any[]) => MoveAttr>(AttrType: T, ...args: ConstructorParameters<T>): this {
|
||||
const attr = new AttrType(...args);
|
||||
this.attrs.push(attr);
|
||||
@ -184,9 +196,16 @@ export default class Move implements Localizable {
|
||||
return this;
|
||||
}
|
||||
|
||||
addAttr(attr: MoveAttr): this {
|
||||
this.attrs.push(attr);
|
||||
let attrCondition = attr.getCondition();
|
||||
/**
|
||||
* Adds a new MoveAttr to the move (appends to the attr array)
|
||||
* if the MoveAttr also comes with a condition, also adds that to the conditions array: {@linkcode MoveCondition}
|
||||
* Almost identical to {@link attr}, except you are passing in a MoveAttr object, instead of a constructor and it's arguments
|
||||
* @param attrAdd {@linkcode MoveAttr} the attribute to add
|
||||
* @returns the called object {@linkcode Move}
|
||||
*/
|
||||
addAttr(attrAdd: MoveAttr): this {
|
||||
this.attrs.push(attrAdd);
|
||||
let attrCondition = attrAdd.getCondition();
|
||||
if (attrCondition) {
|
||||
if (typeof attrCondition === "function") {
|
||||
attrCondition = new MoveCondition(attrCondition);
|
||||
@ -197,15 +216,30 @@ export default class Move implements Localizable {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the move target of this move
|
||||
* @param moveTarget {@linkcode MoveTarget} the move target to set
|
||||
* @returns the called object {@linkcode Move}
|
||||
*/
|
||||
target(moveTarget: MoveTarget): this {
|
||||
this.moveTarget = moveTarget;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter function that returns if this Move has a MoveFlag
|
||||
* @param flag {@linkcode MoveFlags} to check
|
||||
* @returns boolean
|
||||
*/
|
||||
hasFlag(flag: MoveFlags): boolean {
|
||||
// internally it is taking the bitwise AND (MoveFlags are represented as bit-shifts) and returning False if result is 0 and true otherwise
|
||||
return !!(this.flags & flag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter function that returns if the move hits multiple targets
|
||||
* @returns boolean
|
||||
*/
|
||||
isMultiTarget(): boolean {
|
||||
switch (this.moveTarget) {
|
||||
case MoveTarget.ALL_OTHERS:
|
||||
@ -222,6 +256,11 @@ export default class Move implements Localizable {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter function that returns if the move targets itself or an ally
|
||||
* @returns boolean
|
||||
*/
|
||||
|
||||
isAllyTarget(): boolean {
|
||||
switch (this.moveTarget) {
|
||||
case MoveTarget.USER:
|
||||
@ -235,6 +274,12 @@ export default class Move implements Localizable {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the move is immune to certain types
|
||||
* currently only look at case of Grass types and powder moves
|
||||
* @param type {@linkcode Type} enum
|
||||
* @returns boolean
|
||||
*/
|
||||
isTypeImmune(type: Type): boolean {
|
||||
switch (type) {
|
||||
case Type.GRASS:
|
||||
@ -246,6 +291,11 @@ export default class Move implements Localizable {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a move condition to the move
|
||||
* @param condition {@linkcode MoveCondition} or {@linkcode MoveConditionFunc}, appends to conditions array a new MoveCondition object
|
||||
* @returns the called object {@linkcode Move}
|
||||
*/
|
||||
condition(condition: MoveCondition | MoveConditionFunc): this {
|
||||
if (typeof condition === "function") {
|
||||
condition = new MoveCondition(condition as MoveConditionFunc);
|
||||
@ -255,17 +305,31 @@ export default class Move implements Localizable {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the move as "partial": appends texts to the move name
|
||||
* @returns the called object {@linkcode Move}
|
||||
*/
|
||||
partial(): this {
|
||||
this.nameAppend += " (P)";
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the move as "unimplemented": appends texts to the move name
|
||||
* @returns the called object {@linkcode Move}
|
||||
*/
|
||||
unimplemented(): this {
|
||||
this.nameAppend += " (N)";
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the flags of the move
|
||||
* @param flag {@linkcode MoveFlags}
|
||||
* @param on a boolean, if True, then "ORs" the flag onto existing ones, if False then "XORs" the flag onto existing ones
|
||||
*/
|
||||
private setFlag(flag: MoveFlags, on: boolean): void {
|
||||
// bitwise OR and bitwise XOR respectively
|
||||
if (on) {
|
||||
this.flags |= flag;
|
||||
} else {
|
||||
@ -273,51 +337,110 @@ export default class Move implements Localizable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@linkcode MoveFlags.MAKES_CONTACT} flag for the calling Move
|
||||
* @param makesContact The value (boolean) to set the flag to
|
||||
* @returns The {@linkcode Move} that called this function
|
||||
*/
|
||||
makesContact(makesContact?: boolean): this {
|
||||
this.setFlag(MoveFlags.MAKES_CONTACT, makesContact);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@linkcode MoveFlags.IGNORE_PROTECT} flag for the calling Move
|
||||
* @param ignoresProtect The value (boolean) to set the flag to
|
||||
* example: @see {@linkcode Moves.CURSE}
|
||||
* @returns The {@linkcode Move} that called this function
|
||||
*/
|
||||
ignoresProtect(ignoresProtect?: boolean): this {
|
||||
this.setFlag(MoveFlags.IGNORE_PROTECT, ignoresProtect);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@linkcode MoveFlags.IGNORE_VIRTUAL} flag for the calling Move
|
||||
* @param ignoresVirtual The value (boolean) to set the flag to
|
||||
* example: @see {@linkcode Moves.NATURE_POWER}
|
||||
* @returns The {@linkcode Move} that called this function
|
||||
*/
|
||||
ignoresVirtual(ignoresVirtual?: boolean): this {
|
||||
this.setFlag(MoveFlags.IGNORE_VIRTUAL, ignoresVirtual);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@linkcode MoveFlags.SOUND_BASED} flag for the calling Move
|
||||
* @param soundBased The value (boolean) to set the flag to
|
||||
* example: @see {@linkcode Moves.UPROAR}
|
||||
* @returns The {@linkcode Move} that called this function
|
||||
*/
|
||||
soundBased(soundBased?: boolean): this {
|
||||
this.setFlag(MoveFlags.SOUND_BASED, soundBased);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@linkcode MoveFlags.HIDE_USER} flag for the calling Move
|
||||
* @param hidesUser The value (boolean) to set the flag to
|
||||
* example: @see {@linkcode Moves.TELEPORT}
|
||||
* @returns The {@linkcode Move} that called this function
|
||||
*/
|
||||
hidesUser(hidesUser?: boolean): this {
|
||||
this.setFlag(MoveFlags.HIDE_USER, hidesUser);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@linkcode MoveFlags.HIDE_TARGET} flag for the calling Move
|
||||
* @param hidesTarget The value (boolean) to set the flag to
|
||||
* example: @see {@linkcode Moves.WHIRLWIND}
|
||||
* @returns The {@linkcode Move} that called this function
|
||||
*/
|
||||
hidesTarget(hidesTarget?: boolean): this {
|
||||
this.setFlag(MoveFlags.HIDE_TARGET, hidesTarget);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@linkcode MoveFlags.BITING_MOVE} flag for the calling Move
|
||||
* @param bitingMove The value (boolean) to set the flag to
|
||||
* example: @see {@linkcode Moves.BITE}
|
||||
* @returns The {@linkcode Move} that called this function
|
||||
*/
|
||||
bitingMove(bitingMove?: boolean): this {
|
||||
this.setFlag(MoveFlags.BITING_MOVE, bitingMove);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@linkcode MoveFlags.PULSE_MOVE} flag for the calling Move
|
||||
* @param pulseMove The value (boolean) to set the flag to
|
||||
* example: @see {@linkcode Moves.WATER_PULSE}
|
||||
* @returns The {@linkcode Move} that called this function
|
||||
*/
|
||||
pulseMove(pulseMove?: boolean): this {
|
||||
this.setFlag(MoveFlags.PULSE_MOVE, pulseMove);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@linkcode MoveFlags.PUNCHING_MOVE} flag for the calling Move
|
||||
* @param punchingMove The value (boolean) to set the flag to
|
||||
* example: @see {@linkcode Moves.DRAIN_PUNCH}
|
||||
* @returns The {@linkcode Move} that called this function
|
||||
*/
|
||||
punchingMove(punchingMove?: boolean): this {
|
||||
this.setFlag(MoveFlags.PUNCHING_MOVE, punchingMove);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@linkcode MoveFlags.SLICING_MOVE} flag for the calling Move
|
||||
* @param slicingMove The value (boolean) to set the flag to
|
||||
* example: @see {@linkcode Moves.X_SCISSOR}
|
||||
* @returns The {@linkcode Move} that called this function
|
||||
*/
|
||||
slicingMove(slicingMove?: boolean): this {
|
||||
this.setFlag(MoveFlags.SLICING_MOVE, slicingMove);
|
||||
return this;
|
||||
@ -334,42 +457,92 @@ export default class Move implements Localizable {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@linkcode MoveFlags.BALLBOMB_MOVE} flag for the calling Move
|
||||
* @param ballBombMove The value (boolean) to set the flag to
|
||||
* example: @see {@linkcode Moves.ELECTRO_BALL}
|
||||
* @returns The {@linkcode Move} that called this function
|
||||
*/
|
||||
ballBombMove(ballBombMove?: boolean): this {
|
||||
this.setFlag(MoveFlags.BALLBOMB_MOVE, ballBombMove);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@linkcode MoveFlags.POWDER_MOVE} flag for the calling Move
|
||||
* @param powderMove The value (boolean) to set the flag to
|
||||
* example: @see {@linkcode Moves.STUN_SPORE}
|
||||
* @returns The {@linkcode Move} that called this function
|
||||
*/
|
||||
powderMove(powderMove?: boolean): this {
|
||||
this.setFlag(MoveFlags.POWDER_MOVE, powderMove);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@linkcode MoveFlags.DANCE_MOVE} flag for the calling Move
|
||||
* @param danceMove The value (boolean) to set the flag to
|
||||
* example: @see {@linkcode Moves.PETAL_DANCE}
|
||||
* @returns The {@linkcode Move} that called this function
|
||||
*/
|
||||
danceMove(danceMove?: boolean): this {
|
||||
this.setFlag(MoveFlags.DANCE_MOVE, danceMove);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@linkcode MoveFlags.WIND_MOVE} flag for the calling Move
|
||||
* @param windMove The value (boolean) to set the flag to
|
||||
* example: @see {@linkcode Moves.HURRICANE}
|
||||
* @returns The {@linkcode Move} that called this function
|
||||
*/
|
||||
windMove(windMove?: boolean): this {
|
||||
this.setFlag(MoveFlags.WIND_MOVE, windMove);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@linkcode MoveFlags.TRIAGE_MOVE} flag for the calling Move
|
||||
* @param triageMove The value (boolean) to set the flag to
|
||||
* example: @see {@linkcode Moves.ABSORB}
|
||||
* @returns The {@linkcode Move} that called this function
|
||||
*/
|
||||
triageMove(triageMove?: boolean): this {
|
||||
this.setFlag(MoveFlags.TRIAGE_MOVE, triageMove);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@linkcode MoveFlags.IGNORE_ABILITIES} flag for the calling Move
|
||||
* @param ignoresAbilities sThe value (boolean) to set the flag to
|
||||
* example: @see {@linkcode Moves.SUNSTEEL_STRIKE}
|
||||
* @returns The {@linkcode Move} that called this function
|
||||
*/
|
||||
ignoresAbilities(ignoresAbilities?: boolean): this {
|
||||
this.setFlag(MoveFlags.IGNORE_ABILITIES, ignoresAbilities);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@linkcode MoveFlags.CHECK_ALL_HITS} flag for the calling Move
|
||||
* @param checkAllHits The value (boolean) to set the flag to
|
||||
* example: @see {@linkcode Moves.TRIPLE_AXEL}
|
||||
* @returns The {@linkcode Move} that called this function
|
||||
*/
|
||||
checkAllHits(checkAllHits?: boolean): this {
|
||||
this.setFlag(MoveFlags.CHECK_ALL_HITS, checkAllHits);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the move flag applies to the pokemon(s) using/receiving the move
|
||||
* @param flag {@linkcode MoveFlags} MoveFlag to check on user and/or target
|
||||
* @param user {@linkcode Pokemon} the Pokemon using the move
|
||||
* @param target {@linkcode Pokemon} the Pokemon receiving the move
|
||||
* @returns boolean
|
||||
*/
|
||||
checkFlag(flag: MoveFlags, user: Pokemon, target: Pokemon): boolean {
|
||||
// special cases below, eg: if the move flag is MAKES_CONTACT, and the user pokemon has an ability that ignores contact (like "Long Reach"), then overrides and move does not make contact
|
||||
switch (flag) {
|
||||
case MoveFlags.MAKES_CONTACT:
|
||||
if (user.hasAbilityWithAttr(IgnoreContactAbAttr)) {
|
||||
@ -389,6 +562,13 @@ export default class Move implements Localizable {
|
||||
return !!(this.flags & flag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies each {@linkcode MoveCondition} of this move to the params
|
||||
* @param user {@linkcode Pokemon} to apply conditions to
|
||||
* @param target {@linkcode Pokemon} to apply conditions to
|
||||
* @param move {@linkcode Move} to apply conditions to
|
||||
* @returns boolean: false if any of the apply()'s return false, else true
|
||||
*/
|
||||
applyConditions(user: Pokemon, target: Pokemon, move: Move): boolean {
|
||||
for (const condition of this.conditions) {
|
||||
if (!condition.apply(user, target, move)) {
|
||||
@ -399,6 +579,14 @@ export default class Move implements Localizable {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sees if, given the target pokemon, a move fails on it (by looking at each {@linkcode MoveAttr} of this move
|
||||
* @param user {@linkcode Pokemon} using the move
|
||||
* @param target {@linkcode Pokemon} receiving the move
|
||||
* @param move {@linkcode Move} using the move
|
||||
* @param cancelled {@linkcode Utils.BooleanHolder} to hold boolean value
|
||||
* @returns string of the failed text, or null
|
||||
*/
|
||||
getFailedText(user: Pokemon, target: Pokemon, move: Move, cancelled: Utils.BooleanHolder): string | null {
|
||||
for (const attr of this.attrs) {
|
||||
const failedText = attr.getFailedText(user, target, move, cancelled);
|
||||
@ -409,6 +597,13 @@ export default class Move implements Localizable {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the userBenefitScore across all the attributes and conditions
|
||||
* @param user {@linkcode Pokemon} using the move
|
||||
* @param target {@linkcode Pokemon} receiving the move
|
||||
* @param move {@linkcode Move} using the move
|
||||
* @returns integer representing the total benefitScore
|
||||
*/
|
||||
getUserBenefitScore(user: Pokemon, target: Pokemon, move: Move): integer {
|
||||
let score = 0;
|
||||
|
||||
@ -423,10 +618,18 @@ export default class Move implements Localizable {
|
||||
return score;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the targetBenefitScore across all the attributes
|
||||
* @param user {@linkcode Pokemon} using the move
|
||||
* @param target {@linkcode Pokemon} receiving the move
|
||||
* @param move {@linkcode Move} using the move
|
||||
* @returns integer representing the total benefitScore
|
||||
*/
|
||||
getTargetBenefitScore(user: Pokemon, target: Pokemon, move: Move): integer {
|
||||
let score = 0;
|
||||
|
||||
for (const attr of this.attrs) {
|
||||
// conditionals to check if the move is self targeting (if so then you are applying the move to yourself, not the target)
|
||||
score += attr.getTargetBenefitScore(user, !attr.selfTarget ? target : user, move) * (target !== user && attr.selfTarget ? -1 : 1);
|
||||
}
|
||||
|
||||
@ -6683,7 +6886,11 @@ export function initMoves() {
|
||||
.condition((user, target, move) => user.battleData.berriesEaten.length > 0),
|
||||
new StatusMove(Moves.ROTOTILLER, Type.GROUND, -1, 10, 100, 0, 6)
|
||||
.target(MoveTarget.ALL)
|
||||
.unimplemented(),
|
||||
.condition((user,target,move) => {
|
||||
// If any fielded pokémon is grass-type and grounded.
|
||||
return [...user.scene.getEnemyParty(),...user.scene.getParty()].some((poke) => poke.isOfType(Type.GRASS) && poke.isGrounded());
|
||||
})
|
||||
.attr(StatChangeAttr, [BattleStat.ATK, BattleStat.SPATK], 1, false, (user, target, move) => target.isOfType(Type.GRASS) && target.isGrounded()),
|
||||
new StatusMove(Moves.STICKY_WEB, Type.BUG, -1, 20, -1, 0, 6)
|
||||
.attr(AddArenaTrapTagAttr, ArenaTagType.STICKY_WEB)
|
||||
.target(MoveTarget.ENEMY_SIDE),
|
||||
|
@ -1286,7 +1286,7 @@ export function initSpecies() {
|
||||
new PokemonSpecies(Species.PELIPPER, 3, false, false, false, "Water Bird Pokémon", Type.WATER, Type.FLYING, 1.2, 28, Abilities.KEEN_EYE, Abilities.DRIZZLE, Abilities.RAIN_DISH, 440, 60, 50, 100, 95, 70, 65, 45, 50, 154, GrowthRate.MEDIUM_FAST, 50, false),
|
||||
new PokemonSpecies(Species.RALTS, 3, false, false, false, "Feeling Pokémon", Type.PSYCHIC, Type.FAIRY, 0.4, 6.6, Abilities.SYNCHRONIZE, Abilities.TRACE, Abilities.TELEPATHY, 198, 28, 25, 25, 45, 35, 40, 235, 35, 40, GrowthRate.SLOW, 50, false),
|
||||
new PokemonSpecies(Species.KIRLIA, 3, false, false, false, "Emotion Pokémon", Type.PSYCHIC, Type.FAIRY, 0.8, 20.2, Abilities.SYNCHRONIZE, Abilities.TRACE, Abilities.TELEPATHY, 278, 38, 35, 35, 65, 55, 50, 120, 35, 97, GrowthRate.SLOW, 50, false),
|
||||
new PokemonSpecies(Species.GARDEVOIR, 3, false, false, false, "Embrace Pokémon", Type.PSYCHIC, Type.FAIRY, 1.6, 48.4, Abilities.SYNCHRONIZE, Abilities.TRACE, Abilities.TELEPATHY, 518, 68, 65, 65, 125, 115, 80, 45, 35, 259, GrowthRate.SLOW, 0, false, true,
|
||||
new PokemonSpecies(Species.GARDEVOIR, 3, false, false, false, "Embrace Pokémon", Type.PSYCHIC, Type.FAIRY, 1.6, 48.4, Abilities.SYNCHRONIZE, Abilities.TRACE, Abilities.TELEPATHY, 518, 68, 65, 65, 125, 115, 80, 45, 35, 259, GrowthRate.SLOW, 50, false, true,
|
||||
new PokemonForm("Normal", "", Type.PSYCHIC, Type.FAIRY, 1.6, 48.4, Abilities.SYNCHRONIZE, Abilities.TRACE, Abilities.TELEPATHY, 518, 68, 65, 65, 125, 115, 80, 45, 35, 259, false, null, true),
|
||||
new PokemonForm("Mega", SpeciesFormKey.MEGA, Type.PSYCHIC, Type.FAIRY, 1.6, 48.4, Abilities.PIXILATE, Abilities.PIXILATE, Abilities.PIXILATE, 618, 68, 85, 65, 165, 135, 100, 45, 35, 259),
|
||||
),
|
||||
@ -1404,7 +1404,7 @@ export function initSpecies() {
|
||||
),
|
||||
new PokemonSpecies(Species.WYNAUT, 3, false, false, false, "Bright Pokémon", Type.PSYCHIC, null, 0.6, 14, Abilities.SHADOW_TAG, Abilities.NONE, Abilities.TELEPATHY, 260, 95, 23, 48, 23, 48, 23, 125, 50, 52, GrowthRate.MEDIUM_FAST, 50, false),
|
||||
new PokemonSpecies(Species.SNORUNT, 3, false, false, false, "Snow Hat Pokémon", Type.ICE, null, 0.7, 16.8, Abilities.INNER_FOCUS, Abilities.ICE_BODY, Abilities.MOODY, 300, 50, 50, 50, 50, 50, 50, 190, 50, 60, GrowthRate.MEDIUM_FAST, 50, false),
|
||||
new PokemonSpecies(Species.GLALIE, 3, false, false, false, "Face Pokémon", Type.ICE, null, 1.5, 256.5, Abilities.INNER_FOCUS, Abilities.ICE_BODY, Abilities.MOODY, 480, 80, 80, 80, 80, 80, 80, 75, 50, 168, GrowthRate.MEDIUM_FAST, 100, false, true,
|
||||
new PokemonSpecies(Species.GLALIE, 3, false, false, false, "Face Pokémon", Type.ICE, null, 1.5, 256.5, Abilities.INNER_FOCUS, Abilities.ICE_BODY, Abilities.MOODY, 480, 80, 80, 80, 80, 80, 80, 75, 50, 168, GrowthRate.MEDIUM_FAST, 50, false, true,
|
||||
new PokemonForm("Normal", "", Type.ICE, null, 1.5, 256.5, Abilities.INNER_FOCUS, Abilities.ICE_BODY, Abilities.MOODY, 480, 80, 80, 80, 80, 80, 80, 75, 50, 168, false, null, true),
|
||||
new PokemonForm("Mega", SpeciesFormKey.MEGA, Type.ICE, null, 2.1, 350.2, Abilities.REFRIGERATE, Abilities.REFRIGERATE, Abilities.REFRIGERATE, 580, 80, 120, 80, 120, 80, 100, 75, 50, 168),
|
||||
),
|
||||
@ -1829,7 +1829,7 @@ export function initSpecies() {
|
||||
new PokemonForm("Ordinary Form", "ordinary", Type.WATER, Type.FIGHTING, 1.4, 48.5, Abilities.JUSTIFIED, Abilities.NONE, Abilities.NONE, 580, 91, 72, 90, 129, 90, 108, 3, 35, 290, false, null, true),
|
||||
new PokemonForm("Resolute", "resolute", Type.WATER, Type.FIGHTING, 1.4, 48.5, Abilities.JUSTIFIED, Abilities.NONE, Abilities.NONE, 580, 91, 72, 90, 129, 90, 108, 3, 35, 290),
|
||||
),
|
||||
new PokemonSpecies(Species.MELOETTA, 5, false, false, true, "Melody Pokémon", Type.NORMAL, Type.PSYCHIC, 0.6, 6.5, Abilities.SERENE_GRACE, Abilities.NONE, Abilities.NONE, 600, 100, 77, 77, 128, 128, 90, 3, 100, 270, GrowthRate.SLOW, 0, false, true,
|
||||
new PokemonSpecies(Species.MELOETTA, 5, false, false, true, "Melody Pokémon", Type.NORMAL, Type.PSYCHIC, 0.6, 6.5, Abilities.SERENE_GRACE, Abilities.NONE, Abilities.NONE, 600, 100, 77, 77, 128, 128, 90, 3, 100, 270, GrowthRate.SLOW, null, false, true,
|
||||
new PokemonForm("Aria Forme", "aria", Type.NORMAL, Type.PSYCHIC, 0.6, 6.5, Abilities.SERENE_GRACE, Abilities.NONE, Abilities.NONE, 600, 100, 77, 77, 128, 128, 90, 3, 100, 270, false, null, true),
|
||||
new PokemonForm("Pirouette Forme", "pirouette", Type.NORMAL, Type.FIGHTING, 0.6, 6.5, Abilities.SERENE_GRACE, Abilities.NONE, Abilities.NONE, 600, 100, 128, 90, 77, 77, 128, 3, 100, 270),
|
||||
),
|
||||
|
@ -48,7 +48,7 @@ export interface InterfaceConfig {
|
||||
custom?: MappingLayout;
|
||||
}
|
||||
|
||||
const repeatInputDelayMillis = 250;
|
||||
const repeatInputDelayMillis = 500;
|
||||
|
||||
// Phaser.Input.Gamepad.GamepadPlugin#refreshPads
|
||||
declare module "phaser" {
|
||||
@ -88,7 +88,6 @@ declare module "phaser" {
|
||||
* providing a unified interface for all input-related interactions.
|
||||
*/
|
||||
export class InputsController {
|
||||
private buttonKeys: Phaser.Input.Keyboard.Key[][];
|
||||
private gamepads: Array<Phaser.Input.Gamepad.Gamepad> = new Array();
|
||||
private scene: BattleScene;
|
||||
public events: Phaser.Events.EventEmitter;
|
||||
@ -123,7 +122,6 @@ export class InputsController {
|
||||
constructor(scene: BattleScene) {
|
||||
this.scene = scene;
|
||||
this.time = this.scene.time;
|
||||
this.buttonKeys = [];
|
||||
this.selectedDevice = {
|
||||
[Device.GAMEPAD]: null,
|
||||
[Device.KEYBOARD]: "default"
|
||||
|
@ -93,7 +93,7 @@ export const modifierType: ModifierTypeTranslationEntries = {
|
||||
description: "기술의 명중률이 {{accuracyAmount}} 증가 (최대 100)",
|
||||
},
|
||||
"PokemonMultiHitModifierType": {
|
||||
description: "공격이 가진 갯수에 따라 60/75/82.5%의 위력으로 한번 더 명중",
|
||||
description: "지닌 개수(최대 3개)마다 추가 공격을 하는 대신, 공격력이 60%(1개)/75%(2개)/82.5%(3개)만큼 감소합니다.",
|
||||
},
|
||||
"TmModifierType": {
|
||||
name: "No.{{moveId}} {{moveName}}",
|
||||
|
@ -633,11 +633,12 @@ export abstract class FieldPhase extends BattlePhase {
|
||||
const playerField = this.scene.getPlayerField().filter(p => p.isActive()) as Pokemon[];
|
||||
const enemyField = this.scene.getEnemyField().filter(p => p.isActive()) as Pokemon[];
|
||||
|
||||
let orderedTargets: Pokemon[] = playerField.concat(enemyField).sort((a: Pokemon, b: Pokemon) => {
|
||||
// We shuffle the list before sorting so speed ties produce random results
|
||||
let orderedTargets: Pokemon[] = Utils.randSeedShuffle(playerField.concat(enemyField)).sort((a: Pokemon, b: Pokemon) => {
|
||||
const aSpeed = a?.getBattleStat(Stat.SPD) || 0;
|
||||
const bSpeed = b?.getBattleStat(Stat.SPD) || 0;
|
||||
|
||||
return aSpeed < bSpeed ? 1 : aSpeed > bSpeed ? -1 : !this.scene.randBattleSeedInt(2) ? -1 : 1;
|
||||
return bSpeed - aSpeed;
|
||||
});
|
||||
|
||||
const speedReversed = new Utils.BooleanHolder(false);
|
||||
|
17
src/utils.ts
17
src/utils.ts
@ -127,6 +127,23 @@ export function randSeedEasedWeightedItem<T>(items: T[], easingFunction: string
|
||||
return items[Math.floor(easedValue * items.length)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Shuffle a list using the seeded rng. Utilises the Fisher-Yates algorithm.
|
||||
* @param {Array} items An array of items.
|
||||
* @returns {Array} A new shuffled array of items.
|
||||
*/
|
||||
export function randSeedShuffle<T>(items: T[]): T[] {
|
||||
if (items.length <= 1) {
|
||||
return items;
|
||||
}
|
||||
const newArray = items.slice(0);
|
||||
for (let i = items.length - 1; i > 0; i--) {
|
||||
const j = Phaser.Math.RND.integerInRange(0, i);
|
||||
[newArray[i], newArray[j]] = [newArray[j], newArray[i]];
|
||||
}
|
||||
return newArray;
|
||||
}
|
||||
|
||||
export function getFrameMs(frameCount: integer): integer {
|
||||
return Math.floor((1 / 60) * 1000 * frameCount);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user