Fix issues with Sticky Hold ability
parent
2bb1676d82
commit
40a4d4cf13
|
@ -1209,7 +1209,7 @@ export default class BattleScene extends Phaser.Scene {
|
||||||
this.phaseQueue.push(new TurnInitPhase(this));
|
this.phaseQueue.push(new TurnInitPhase(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
addModifier(modifier: Modifier, ignoreUpdate?: boolean, playSound?: boolean, virtual?: boolean): Promise<void> {
|
addModifier(modifier: Modifier, ignoreUpdate?: boolean, playSound?: boolean, virtual?: boolean, instant?: boolean): Promise<void> {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
const soundName = modifier.type.soundName;
|
const soundName = modifier.type.soundName;
|
||||||
this.validateAchvs(ModifierAchv, modifier);
|
this.validateAchvs(ModifierAchv, modifier);
|
||||||
|
@ -1220,11 +1220,11 @@ export default class BattleScene extends Phaser.Scene {
|
||||||
} else if (!virtual) {
|
} else if (!virtual) {
|
||||||
const defaultModifierType = getDefaultModifierTypeForTier(modifier.type.tier);
|
const defaultModifierType = getDefaultModifierTypeForTier(modifier.type.tier);
|
||||||
this.queueMessage(`The stack for this item is full.\n You will receive ${defaultModifierType.name} instead.`, null, true);
|
this.queueMessage(`The stack for this item is full.\n You will receive ${defaultModifierType.name} instead.`, null, true);
|
||||||
return this.addModifier(defaultModifierType.newModifier(), ignoreUpdate, playSound).then(() => resolve());
|
return this.addModifier(defaultModifierType.newModifier(), ignoreUpdate, playSound, false, instant).then(() => resolve());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ignoreUpdate && !virtual)
|
if (!ignoreUpdate && !virtual)
|
||||||
return this.updateModifiers().then(() => resolve());
|
return this.updateModifiers(true, instant).then(() => resolve());
|
||||||
} else if (modifier instanceof ConsumableModifier) {
|
} else if (modifier instanceof ConsumableModifier) {
|
||||||
if (playSound && !this.sound.get(soundName))
|
if (playSound && !this.sound.get(soundName))
|
||||||
this.playSound(soundName);
|
this.playSound(soundName);
|
||||||
|
@ -1248,7 +1248,7 @@ export default class BattleScene extends Phaser.Scene {
|
||||||
modifier.apply(args);
|
modifier.apply(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Promise.allSettled(this.party.map(p => p.updateInfo())).then(() => resolve());
|
return Promise.allSettled(this.party.map(p => p.updateInfo(instant))).then(() => resolve());
|
||||||
} else {
|
} else {
|
||||||
const args = [ this ];
|
const args = [ this ];
|
||||||
if (modifier.shouldApply(args))
|
if (modifier.shouldApply(args))
|
||||||
|
@ -1260,61 +1260,58 @@ export default class BattleScene extends Phaser.Scene {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
addEnemyModifier(itemModifier: PersistentModifier, ignoreUpdate?: boolean): Promise<void> {
|
addEnemyModifier(itemModifier: PersistentModifier, ignoreUpdate?: boolean, instant?: boolean): Promise<void> {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
itemModifier.add(this.enemyModifiers, false, this);
|
itemModifier.add(this.enemyModifiers, false, this);
|
||||||
if (!ignoreUpdate)
|
if (!ignoreUpdate)
|
||||||
this.updateModifiers(false).then(() => resolve());
|
this.updateModifiers(false, instant).then(() => resolve());
|
||||||
else
|
else
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
tryTransferHeldItemModifier(itemModifier: PokemonHeldItemModifier, target: Pokemon, transferStack: boolean, playSound: boolean): Promise<boolean> {
|
tryTransferHeldItemModifier(itemModifier: PokemonHeldItemModifier, target: Pokemon, transferStack: boolean, playSound: boolean, instant?: boolean): Promise<boolean> {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
const source = itemModifier.getPokemon(target.scene);
|
const source = itemModifier.getPokemon(target.scene);
|
||||||
const cancelled = new Utils.BooleanHolder(false);
|
const cancelled = new Utils.BooleanHolder(false);
|
||||||
applyAbAttrs(BlockItemTheftAbAttr, target, cancelled);
|
applyAbAttrs(BlockItemTheftAbAttr, source, cancelled).then(() => {
|
||||||
if (cancelled.value) {
|
if (cancelled.value)
|
||||||
resolve(false);
|
return resolve(false);
|
||||||
return;
|
const newItemModifier = itemModifier.clone() as PokemonHeldItemModifier;
|
||||||
}
|
newItemModifier.pokemonId = target.id;
|
||||||
const newItemModifier = itemModifier.clone() as PokemonHeldItemModifier;
|
const matchingModifier = target.scene.findModifier(m => m instanceof PokemonHeldItemModifier
|
||||||
newItemModifier.pokemonId = target.id;
|
&& (m as PokemonHeldItemModifier).matchType(itemModifier) && m.pokemonId === target.id, target.isPlayer()) as PokemonHeldItemModifier;
|
||||||
const matchingModifier = target.scene.findModifier(m => m instanceof PokemonHeldItemModifier
|
let removeOld = true;
|
||||||
&& (m as PokemonHeldItemModifier).matchType(itemModifier) && m.pokemonId === target.id, target.isPlayer()) as PokemonHeldItemModifier;
|
if (matchingModifier) {
|
||||||
let removeOld = true;
|
const maxStackCount = matchingModifier.getMaxStackCount(source.scene);
|
||||||
if (matchingModifier) {
|
if (matchingModifier.stackCount >= maxStackCount)
|
||||||
const maxStackCount = matchingModifier.getMaxStackCount(source.scene);
|
return resolve(false);
|
||||||
if (matchingModifier.stackCount >= maxStackCount) {
|
const countTaken = transferStack ? Math.min(itemModifier.stackCount, maxStackCount - matchingModifier.stackCount) : 1;
|
||||||
resolve(false);
|
itemModifier.stackCount -= countTaken;
|
||||||
|
newItemModifier.stackCount = matchingModifier.stackCount + countTaken;
|
||||||
|
removeOld = !itemModifier.stackCount;
|
||||||
|
} else if (!transferStack) {
|
||||||
|
newItemModifier.stackCount = 1;
|
||||||
|
removeOld = !(--itemModifier.stackCount);
|
||||||
|
}
|
||||||
|
if (!removeOld || this.removeModifier(itemModifier, !source.isPlayer())) {
|
||||||
|
const addModifier = () => {
|
||||||
|
if (!matchingModifier || this.removeModifier(matchingModifier, !target.isPlayer())) {
|
||||||
|
if (target.isPlayer())
|
||||||
|
this.addModifier(newItemModifier, false, playSound, false, instant).then(() => resolve(true));
|
||||||
|
else
|
||||||
|
this.addEnemyModifier(newItemModifier, false, instant).then(() => resolve(true));
|
||||||
|
} else
|
||||||
|
resolve(false);
|
||||||
|
};
|
||||||
|
if (source.isPlayer() !== target.isPlayer())
|
||||||
|
this.updateModifiers(source.isPlayer(), instant).then(() => addModifier());
|
||||||
|
else
|
||||||
|
addModifier();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const countTaken = transferStack ? Math.min(itemModifier.stackCount, maxStackCount - matchingModifier.stackCount) : 1;
|
resolve(false);
|
||||||
itemModifier.stackCount -= countTaken;
|
});
|
||||||
newItemModifier.stackCount = matchingModifier.stackCount + countTaken;
|
|
||||||
removeOld = !itemModifier.stackCount;
|
|
||||||
} else if (!transferStack) {
|
|
||||||
newItemModifier.stackCount = 1;
|
|
||||||
removeOld = !(--itemModifier.stackCount);
|
|
||||||
}
|
|
||||||
if (!removeOld || this.removeModifier(itemModifier, !source.isPlayer())) {
|
|
||||||
const addModifier = () => {
|
|
||||||
if (!matchingModifier || this.removeModifier(matchingModifier, !target.isPlayer())) {
|
|
||||||
if (target.isPlayer())
|
|
||||||
this.addModifier(newItemModifier, false, playSound).then(() => resolve(true));
|
|
||||||
else
|
|
||||||
this.addEnemyModifier(newItemModifier).then(() => resolve(true));
|
|
||||||
} else
|
|
||||||
resolve(false);
|
|
||||||
};
|
|
||||||
if (source.isPlayer() !== target.isPlayer())
|
|
||||||
this.updateModifiers(source.isPlayer()).then(() => addModifier());
|
|
||||||
else
|
|
||||||
addModifier();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
resolve(false);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1366,7 +1363,7 @@ export default class BattleScene extends Phaser.Scene {
|
||||||
this.updateModifiers(false).then(() => this.updateUIPositions());
|
this.updateModifiers(false).then(() => this.updateUIPositions());
|
||||||
}
|
}
|
||||||
|
|
||||||
updateModifiers(player?: boolean): Promise<void> {
|
updateModifiers(player?: boolean, instant?: boolean): Promise<void> {
|
||||||
if (player === undefined)
|
if (player === undefined)
|
||||||
player = true;
|
player = true;
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
|
@ -1387,7 +1384,7 @@ export default class BattleScene extends Phaser.Scene {
|
||||||
modifiers.splice(modifiers.indexOf(modifier), 1);
|
modifiers.splice(modifiers.indexOf(modifier), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.updatePartyForModifiers(player ? this.getParty() : this.getEnemyParty()).then(() => {
|
this.updatePartyForModifiers(player ? this.getParty() : this.getEnemyParty(), instant).then(() => {
|
||||||
(player ? this.modifierBar : this.enemyModifierBar).updateModifiers(modifiers);
|
(player ? this.modifierBar : this.enemyModifierBar).updateModifiers(modifiers);
|
||||||
if (!player)
|
if (!player)
|
||||||
this.updateUIPositions();
|
this.updateUIPositions();
|
||||||
|
@ -1396,11 +1393,11 @@ export default class BattleScene extends Phaser.Scene {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
updatePartyForModifiers(party: Pokemon[]): Promise<void> {
|
updatePartyForModifiers(party: Pokemon[], instant?: boolean): Promise<void> {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
Promise.allSettled(party.map(p => {
|
Promise.allSettled(party.map(p => {
|
||||||
p.calculateStats();
|
p.calculateStats();
|
||||||
return p.updateInfo();
|
return p.updateInfo(instant);
|
||||||
})).then(() => resolve());
|
})).then(() => resolve());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ export class Ability {
|
||||||
public name: string;
|
public name: string;
|
||||||
public description: string;
|
public description: string;
|
||||||
public generation: integer;
|
public generation: integer;
|
||||||
|
public isPassive: boolean;
|
||||||
public attrs: AbAttr[];
|
public attrs: AbAttr[];
|
||||||
public conditions: AbAttrCondition[];
|
public conditions: AbAttrCondition[];
|
||||||
|
|
||||||
|
@ -44,6 +45,11 @@ export class Ability {
|
||||||
return !!this.getAttrs(attrType).length;
|
return !!this.getAttrs(attrType).length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
passive(): Ability {
|
||||||
|
this.isPassive = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
condition(condition: AbAttrCondition): Ability {
|
condition(condition: AbAttrCondition): Ability {
|
||||||
this.conditions.push(condition);
|
this.conditions.push(condition);
|
||||||
|
|
||||||
|
@ -1508,7 +1514,8 @@ export function initAbilities() {
|
||||||
new Ability(Abilities.MINUS, "Minus (N)", "Boosts the Sp. Atk stat of the Pokémon if an ally with the Plus or Minus Ability is also in battle.", 3),
|
new Ability(Abilities.MINUS, "Minus (N)", "Boosts the Sp. Atk stat of the Pokémon if an ally with the Plus or Minus Ability is also in battle.", 3),
|
||||||
new Ability(Abilities.FORECAST, "Forecast (N)", "The Pokémon transforms with the weather to change its type to Water, Fire, or Ice.", 3),
|
new Ability(Abilities.FORECAST, "Forecast (N)", "The Pokémon transforms with the weather to change its type to Water, Fire, or Ice.", 3),
|
||||||
new Ability(Abilities.STICKY_HOLD, "Sticky Hold", "Items held by the Pokémon are stuck fast and cannot be removed by other Pokémon.", 3)
|
new Ability(Abilities.STICKY_HOLD, "Sticky Hold", "Items held by the Pokémon are stuck fast and cannot be removed by other Pokémon.", 3)
|
||||||
.attr(BlockItemTheftAbAttr),
|
.attr(BlockItemTheftAbAttr)
|
||||||
|
.passive(),
|
||||||
new Ability(Abilities.SHED_SKIN, "Shed Skin (N)", "The Pokémon may heal its own status conditions by shedding its skin.", 3),
|
new Ability(Abilities.SHED_SKIN, "Shed Skin (N)", "The Pokémon may heal its own status conditions by shedding its skin.", 3),
|
||||||
new Ability(Abilities.GUTS, "Guts (N)", "It's so gutsy that having a status condition boosts the Pokémon's Attack stat.", 3),
|
new Ability(Abilities.GUTS, "Guts (N)", "It's so gutsy that having a status condition boosts the Pokémon's Attack stat.", 3),
|
||||||
new Ability(Abilities.MARVEL_SCALE, "Marvel Scale (N)", "The Pokémon's marvelous scales boost the Defense stat if it has a status condition.", 3),
|
new Ability(Abilities.MARVEL_SCALE, "Marvel Scale (N)", "The Pokémon's marvelous scales boost the Defense stat if it has a status condition.", 3),
|
||||||
|
|
|
@ -1398,20 +1398,26 @@ export abstract class HeldItemTransferModifier extends PokemonHeldItemModifier {
|
||||||
const transferredModifierTypes: ModifierTypes.ModifierType[] = [];
|
const transferredModifierTypes: ModifierTypes.ModifierType[] = [];
|
||||||
const itemModifiers = pokemon.scene.findModifiers(m => m instanceof PokemonHeldItemModifier
|
const itemModifiers = pokemon.scene.findModifiers(m => m instanceof PokemonHeldItemModifier
|
||||||
&& (m as PokemonHeldItemModifier).pokemonId === targetPokemon.id && m.getTransferrable(withinParty), targetPokemon.isPlayer()) as PokemonHeldItemModifier[];
|
&& (m as PokemonHeldItemModifier).pokemonId === targetPokemon.id && m.getTransferrable(withinParty), targetPokemon.isPlayer()) as PokemonHeldItemModifier[];
|
||||||
|
|
||||||
|
let heldItemTransferPromises: Promise<void>[] = [];
|
||||||
|
|
||||||
for (let i = 0; i < transferredItemCount; i++) {
|
for (let i = 0; i < transferredItemCount; i++) {
|
||||||
if (!itemModifiers.length)
|
if (!itemModifiers.length)
|
||||||
break;
|
break;
|
||||||
const randItemIndex = Utils.randInt(itemModifiers.length);
|
const randItemIndex = Utils.randInt(itemModifiers.length);
|
||||||
const randItem = itemModifiers[randItemIndex];
|
const randItem = itemModifiers[randItemIndex];
|
||||||
if (pokemon.scene.tryTransferHeldItemModifier(randItem, pokemon, false, false)) {
|
heldItemTransferPromises.push(pokemon.scene.tryTransferHeldItemModifier(randItem, pokemon, false, false, true).then(success => {
|
||||||
transferredModifierTypes.push(randItem.type);
|
if (success) {
|
||||||
itemModifiers.splice(randItemIndex, 1);
|
transferredModifierTypes.push(randItem.type);
|
||||||
}
|
itemModifiers.splice(randItemIndex, 1);
|
||||||
|
}
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let mt of transferredModifierTypes)
|
Promise.all(heldItemTransferPromises).then(() => {
|
||||||
pokemon.scene.queueMessage(this.getTransferMessage(pokemon, targetPokemon, mt));
|
for (let mt of transferredModifierTypes)
|
||||||
|
pokemon.scene.queueMessage(this.getTransferMessage(pokemon, targetPokemon, mt));
|
||||||
|
});
|
||||||
|
|
||||||
return !!transferredModifierTypes.length;
|
return !!transferredModifierTypes.length;
|
||||||
}
|
}
|
||||||
|
@ -1447,7 +1453,7 @@ export class TurnHeldItemTransferModifier extends HeldItemTransferModifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
getMaxHeldItemCount(pokemon: Pokemon): integer {
|
getMaxHeldItemCount(pokemon: Pokemon): integer {
|
||||||
return 3;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -608,7 +608,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||||
}
|
}
|
||||||
|
|
||||||
canApplyAbility(): boolean {
|
canApplyAbility(): boolean {
|
||||||
return this.hp && !this.getAbility().conditions.find(condition => !condition(this));
|
const ability = this.getAbility();
|
||||||
|
return (this.hp || ability.isPassive) && !this.getAbility().conditions.find(condition => !condition(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
getWeight(): number {
|
getWeight(): number {
|
||||||
|
|
Loading…
Reference in New Issue