mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-07-20 23:32:19 +02:00
Merge branch 'beta' into tera-summary-screen
This commit is contained in:
commit
84ae4d9660
@ -5152,6 +5152,10 @@ function applySingleAbAttrs<TAttr extends AbAttr>(
|
|||||||
showAbilityInstant: boolean = false,
|
showAbilityInstant: boolean = false,
|
||||||
messages: string[] = []
|
messages: string[] = []
|
||||||
) {
|
) {
|
||||||
|
if (!pokemon?.canApplyAbility(passive) || (passive && (pokemon.getPassiveAbility().id === pokemon.getAbility().id))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const ability = passive ? pokemon.getPassiveAbility() : pokemon.getAbility();
|
const ability = passive ? pokemon.getPassiveAbility() : pokemon.getAbility();
|
||||||
if (gainedMidTurn && ability.getAttrs(attrType).some(attr => attr instanceof PostSummonAbAttr && !attr.shouldActivateOnGain())) {
|
if (gainedMidTurn && ability.getAttrs(attrType).some(attr => attr instanceof PostSummonAbAttr && !attr.shouldActivateOnGain())) {
|
||||||
return;
|
return;
|
||||||
@ -5445,13 +5449,11 @@ function applyAbAttrsInternal<TAttr extends AbAttr>(
|
|||||||
gainedMidTurn: boolean = false
|
gainedMidTurn: boolean = false
|
||||||
) {
|
) {
|
||||||
for (const passive of [ false, true ]) {
|
for (const passive of [ false, true ]) {
|
||||||
if (!pokemon?.canApplyAbility(passive) || (passive && (pokemon.getPassiveAbility().id === pokemon.getAbility().id))) {
|
if (pokemon) {
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
applySingleAbAttrs(pokemon, passive, attrType, applyFunc, args, gainedMidTurn, simulated, showAbilityInstant, messages);
|
applySingleAbAttrs(pokemon, passive, attrType, applyFunc, args, gainedMidTurn, simulated, showAbilityInstant, messages);
|
||||||
globalScene.clearPhaseQueueSplice();
|
globalScene.clearPhaseQueueSplice();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function applyAbAttrs(
|
export function applyAbAttrs(
|
||||||
|
@ -1230,10 +1230,12 @@ export class FairyLockTag extends ArenaTag {
|
|||||||
*/
|
*/
|
||||||
export class SuppressAbilitiesTag extends ArenaTag {
|
export class SuppressAbilitiesTag extends ArenaTag {
|
||||||
private sourceCount: number;
|
private sourceCount: number;
|
||||||
|
private beingRemoved: boolean;
|
||||||
|
|
||||||
constructor(sourceId: number) {
|
constructor(sourceId: number) {
|
||||||
super(ArenaTagType.NEUTRALIZING_GAS, 0, undefined, sourceId);
|
super(ArenaTagType.NEUTRALIZING_GAS, 0, undefined, sourceId);
|
||||||
this.sourceCount = 1;
|
this.sourceCount = 1;
|
||||||
|
this.beingRemoved = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override onAdd(arena: Arena): void {
|
public override onAdd(arena: Arena): void {
|
||||||
@ -1267,6 +1269,7 @@ export class SuppressAbilitiesTag extends ArenaTag {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public override onRemove(arena: Arena, quiet: boolean = false) {
|
public override onRemove(arena: Arena, quiet: boolean = false) {
|
||||||
|
this.beingRemoved = true;
|
||||||
if (!quiet) {
|
if (!quiet) {
|
||||||
globalScene.queueMessage(i18next.t("arenaTag:neutralizingGasOnRemove"));
|
globalScene.queueMessage(i18next.t("arenaTag:neutralizingGasOnRemove"));
|
||||||
}
|
}
|
||||||
@ -1282,6 +1285,10 @@ export class SuppressAbilitiesTag extends ArenaTag {
|
|||||||
public shouldApplyToSelf(): boolean {
|
public shouldApplyToSelf(): boolean {
|
||||||
return this.sourceCount > 1;
|
return this.sourceCount > 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public isBeingRemoved() {
|
||||||
|
return this.beingRemoved;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: swap `sourceMove` and `sourceId` and make `sourceMove` an optional parameter
|
// TODO: swap `sourceMove` and `sourceId` and make `sourceMove` an optional parameter
|
||||||
|
@ -1866,11 +1866,14 @@ export class HalfSacrificialAttr extends MoveEffectAttr {
|
|||||||
export class AddSubstituteAttr extends MoveEffectAttr {
|
export class AddSubstituteAttr extends MoveEffectAttr {
|
||||||
/** The ratio of the user's max HP that is required to apply this effect */
|
/** The ratio of the user's max HP that is required to apply this effect */
|
||||||
private hpCost: number;
|
private hpCost: number;
|
||||||
|
/** Whether the damage taken should be rounded up (Shed Tail rounds up) */
|
||||||
|
private roundUp: boolean;
|
||||||
|
|
||||||
constructor(hpCost: number = 0.25) {
|
constructor(hpCost: number, roundUp: boolean) {
|
||||||
super(true);
|
super(true);
|
||||||
|
|
||||||
this.hpCost = hpCost;
|
this.hpCost = hpCost;
|
||||||
|
this.roundUp = roundUp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1886,7 +1889,8 @@ export class AddSubstituteAttr extends MoveEffectAttr {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
user.damageAndUpdate(Math.floor(user.getMaxHp() * this.hpCost), HitResult.OTHER, false, true, true);
|
const damageTaken = this.roundUp ? Math.ceil(user.getMaxHp() * this.hpCost) : Math.floor(user.getMaxHp() * this.hpCost);
|
||||||
|
user.damageAndUpdate(damageTaken, HitResult.OTHER, false, true, true);
|
||||||
user.addTag(BattlerTagType.SUBSTITUTE, 0, move.id, user.id);
|
user.addTag(BattlerTagType.SUBSTITUTE, 0, move.id, user.id);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1899,7 +1903,7 @@ export class AddSubstituteAttr extends MoveEffectAttr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getCondition(): MoveConditionFunc {
|
getCondition(): MoveConditionFunc {
|
||||||
return (user, target, move) => !user.getTag(SubstituteTag) && user.hp > Math.floor(user.getMaxHp() * this.hpCost) && user.getMaxHp() > 1;
|
return (user, target, move) => !user.getTag(SubstituteTag) && user.hp > (this.roundUp ? Math.ceil(user.getMaxHp() * this.hpCost) : Math.floor(user.getMaxHp() * this.hpCost)) && user.getMaxHp() > 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -9036,7 +9040,7 @@ export function initMoves() {
|
|||||||
.attr(HighCritAttr)
|
.attr(HighCritAttr)
|
||||||
.slicingMove(),
|
.slicingMove(),
|
||||||
new SelfStatusMove(Moves.SUBSTITUTE, Type.NORMAL, -1, 10, -1, 0, 1)
|
new SelfStatusMove(Moves.SUBSTITUTE, Type.NORMAL, -1, 10, -1, 0, 1)
|
||||||
.attr(AddSubstituteAttr),
|
.attr(AddSubstituteAttr, 0.25, false),
|
||||||
new AttackMove(Moves.STRUGGLE, Type.NORMAL, MoveCategory.PHYSICAL, 50, -1, 1, -1, 0, 1)
|
new AttackMove(Moves.STRUGGLE, Type.NORMAL, MoveCategory.PHYSICAL, 50, -1, 1, -1, 0, 1)
|
||||||
.attr(RecoilAttr, true, 0.25, true)
|
.attr(RecoilAttr, true, 0.25, true)
|
||||||
.attr(TypelessAttr)
|
.attr(TypelessAttr)
|
||||||
@ -11382,7 +11386,7 @@ export function initMoves() {
|
|||||||
.attr(MovePowerMultiplierAttr, (user, target, move) => target.getAttackTypeEffectiveness(move.type, user) >= 2 ? 5461 / 4096 : 1)
|
.attr(MovePowerMultiplierAttr, (user, target, move) => target.getAttackTypeEffectiveness(move.type, user) >= 2 ? 5461 / 4096 : 1)
|
||||||
.makesContact(),
|
.makesContact(),
|
||||||
new SelfStatusMove(Moves.SHED_TAIL, Type.NORMAL, -1, 10, -1, 0, 9)
|
new SelfStatusMove(Moves.SHED_TAIL, Type.NORMAL, -1, 10, -1, 0, 9)
|
||||||
.attr(AddSubstituteAttr, 0.5)
|
.attr(AddSubstituteAttr, 0.5, true)
|
||||||
.attr(ForceSwitchOutAttr, true, SwitchType.SHED_TAIL)
|
.attr(ForceSwitchOutAttr, true, SwitchType.SHED_TAIL)
|
||||||
.condition(failIfLastInPartyCondition),
|
.condition(failIfLastInPartyCondition),
|
||||||
new SelfStatusMove(Moves.CHILLY_RECEPTION, Type.ICE, -1, 10, -1, 0, 9)
|
new SelfStatusMove(Moves.CHILLY_RECEPTION, Type.ICE, -1, 10, -1, 0, 9)
|
||||||
|
@ -1501,8 +1501,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
* Suppresses an ability and calls its onlose attributes
|
* Suppresses an ability and calls its onlose attributes
|
||||||
*/
|
*/
|
||||||
public suppressAbility() {
|
public suppressAbility() {
|
||||||
this.summonData.abilitySuppressed = true;
|
|
||||||
[ true, false ].forEach((passive) => applyOnLoseAbAttrs(this, passive));
|
[ true, false ].forEach((passive) => applyOnLoseAbAttrs(this, passive));
|
||||||
|
this.summonData.abilitySuppressed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1563,7 +1563,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const suppressAbilitiesTag = arena.getTag(ArenaTagType.NEUTRALIZING_GAS) as SuppressAbilitiesTag;
|
const suppressAbilitiesTag = arena.getTag(ArenaTagType.NEUTRALIZING_GAS) as SuppressAbilitiesTag;
|
||||||
if (this.isOnField() && suppressAbilitiesTag) {
|
if (this.isOnField() && suppressAbilitiesTag && !suppressAbilitiesTag.isBeingRemoved()) {
|
||||||
const thisAbilitySuppressing = ability.hasAttr(PreLeaveFieldRemoveSuppressAbilitiesSourceAbAttr);
|
const thisAbilitySuppressing = ability.hasAttr(PreLeaveFieldRemoveSuppressAbilitiesSourceAbAttr);
|
||||||
const hasSuppressingAbility = this.hasAbilityWithAttr(PreLeaveFieldRemoveSuppressAbilitiesSourceAbAttr, false);
|
const hasSuppressingAbility = this.hasAbilityWithAttr(PreLeaveFieldRemoveSuppressAbilitiesSourceAbAttr, false);
|
||||||
// Neutralizing gas is up - suppress abilities unless they are unsuppressable or this pokemon is responsible for the gas
|
// Neutralizing gas is up - suppress abilities unless they are unsuppressable or this pokemon is responsible for the gas
|
||||||
|
@ -629,6 +629,8 @@ export class DropDown extends Phaser.GameObjects.Container {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.onChange();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,6 +86,15 @@ export class FilterBar extends Phaser.GameObjects.Container {
|
|||||||
return this.dropDowns[this.columns.indexOf(col)];
|
return this.dropDowns[this.columns.indexOf(col)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the DropDownColumn associated to a given index
|
||||||
|
* @param index the index of the column to retrieve
|
||||||
|
* @returns the associated DropDownColumn if it exists, undefined otherwise
|
||||||
|
*/
|
||||||
|
public getColumn(index: number): DropDownColumn {
|
||||||
|
return this.columns[index];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Highlight the labels of the FilterBar if the filters are different from their default values
|
* Highlight the labels of the FilterBar if the filters are different from their default values
|
||||||
*/
|
*/
|
||||||
@ -185,6 +194,11 @@ export class FilterBar extends Phaser.GameObjects.Container {
|
|||||||
return this.getFilter(col).getVals();
|
return this.getFilter(col).getVals();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public resetSelection(col: DropDownColumn): void {
|
||||||
|
this.dropDowns[col].resetToDefault();
|
||||||
|
this.updateFilterLabels();
|
||||||
|
}
|
||||||
|
|
||||||
setValsToDefault(): void {
|
setValsToDefault(): void {
|
||||||
for (const dropDown of this.dropDowns) {
|
for (const dropDown of this.dropDowns) {
|
||||||
dropDown.resetToDefault();
|
dropDown.resetToDefault();
|
||||||
|
@ -898,16 +898,11 @@ export default class PokedexUiHandler extends MessageUiHandler {
|
|||||||
if (this.filterMode && this.filterBar.openDropDown) {
|
if (this.filterMode && this.filterBar.openDropDown) {
|
||||||
// CANCEL with a filter menu open > close it
|
// CANCEL with a filter menu open > close it
|
||||||
this.filterBar.toggleDropDown(this.filterBarCursor);
|
this.filterBar.toggleDropDown(this.filterBarCursor);
|
||||||
|
|
||||||
// if there are possible pokemon go the first one of the list
|
|
||||||
if (numberOfStarters > 0) {
|
|
||||||
this.setFilterMode(false);
|
|
||||||
this.scrollCursor = 0;
|
|
||||||
this.updateScroll();
|
|
||||||
this.setCursor(0);
|
|
||||||
}
|
|
||||||
success = true;
|
success = true;
|
||||||
|
} else if (this.filterMode && !this.filterBar.getFilter(this.filterBarCursor).hasDefaultValues()) {
|
||||||
|
this.filterBar.resetSelection(this.filterBarCursor);
|
||||||
|
this.updateStarters();
|
||||||
|
success = true;
|
||||||
} else if (this.filterTextMode && !(this.filterText.getValue(this.filterTextCursor) === this.filterText.defaultText)) {
|
} else if (this.filterTextMode && !(this.filterText.getValue(this.filterTextCursor) === this.filterText.defaultText)) {
|
||||||
this.filterText.resetSelection(this.filterTextCursor);
|
this.filterText.resetSelection(this.filterTextCursor);
|
||||||
success = true;
|
success = true;
|
||||||
|
@ -1080,10 +1080,18 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
/**
|
/**
|
||||||
* Set the selections for all filters to their default starting value
|
* Set the selections for all filters to their default starting value
|
||||||
*/
|
*/
|
||||||
resetFilters() : void {
|
public resetFilters(): void {
|
||||||
|
this.filterBar.setValsToDefault();
|
||||||
|
this.resetCaughtDropdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set default value for the caught dropdown, which only shows caught mons
|
||||||
|
*/
|
||||||
|
public resetCaughtDropdown(): void {
|
||||||
const caughtDropDown: DropDown = this.filterBar.getFilter(DropDownColumn.CAUGHT);
|
const caughtDropDown: DropDown = this.filterBar.getFilter(DropDownColumn.CAUGHT);
|
||||||
|
|
||||||
this.filterBar.setValsToDefault();
|
caughtDropDown.resetToDefault();
|
||||||
|
|
||||||
// initial setting, in caught filter, select the options excluding the uncaught option
|
// initial setting, in caught filter, select the options excluding the uncaught option
|
||||||
for (let i = 0; i < caughtDropDown.options.length; i++) {
|
for (let i = 0; i < caughtDropDown.options.length; i++) {
|
||||||
@ -1323,16 +1331,15 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
if (this.filterMode && this.filterBar.openDropDown) {
|
if (this.filterMode && this.filterBar.openDropDown) {
|
||||||
// CANCEL with a filter menu open > close it
|
// CANCEL with a filter menu open > close it
|
||||||
this.filterBar.toggleDropDown(this.filterBarCursor);
|
this.filterBar.toggleDropDown(this.filterBarCursor);
|
||||||
|
|
||||||
// if there are possible starters go the first one of the list
|
|
||||||
if (numberOfStarters > 0) {
|
|
||||||
this.setFilterMode(false);
|
|
||||||
this.scrollCursor = 0;
|
|
||||||
this.updateScroll();
|
|
||||||
this.setCursor(0);
|
|
||||||
}
|
|
||||||
success = true;
|
success = true;
|
||||||
|
} else if (this.filterMode && !this.filterBar.getFilter(this.filterBar.getColumn(this.filterBarCursor)).hasDefaultValues()) {
|
||||||
|
if (this.filterBar.getColumn(this.filterBarCursor) === DropDownColumn.CAUGHT) {
|
||||||
|
this.resetCaughtDropdown();
|
||||||
|
} else {
|
||||||
|
this.filterBar.resetSelection(this.filterBarCursor);
|
||||||
|
}
|
||||||
|
this.updateStarters();
|
||||||
|
success = true;
|
||||||
} else if (this.statsMode) {
|
} else if (this.statsMode) {
|
||||||
this.toggleStatsMode(false);
|
this.toggleStatsMode(false);
|
||||||
success = true;
|
success = true;
|
||||||
|
@ -46,11 +46,8 @@ describe("Moves - Shed Tail", () => {
|
|||||||
|
|
||||||
expect(feebas).not.toBe(magikarp);
|
expect(feebas).not.toBe(magikarp);
|
||||||
expect(feebas.hp).toBe(feebas.getMaxHp());
|
expect(feebas.hp).toBe(feebas.getMaxHp());
|
||||||
// Note: Shed Tail's HP cost is currently not accurate to mainline, as it
|
// Note: Altered the test to be consistent with the correct HP cost :yipeevee_static:
|
||||||
// should cost ceil(maxHP / 2) instead of max(floor(maxHp / 2), 1). The current
|
expect(magikarp.hp).toBe(Math.floor(magikarp.getMaxHp() / 2));
|
||||||
// implementation is consistent with Substitute's HP cost logic, but that's not
|
|
||||||
// the case in mainline for some reason :regiDespair:.
|
|
||||||
expect(magikarp.hp).toBe(Math.ceil(magikarp.getMaxHp() / 2));
|
|
||||||
expect(substituteTag).toBeDefined();
|
expect(substituteTag).toBeDefined();
|
||||||
expect(substituteTag?.hp).toBe(Math.floor(magikarp.getMaxHp() / 4));
|
expect(substituteTag?.hp).toBe(Math.floor(magikarp.getMaxHp() / 4));
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user