Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Ability] Implement Unburden #4534

Open
wants to merge 14 commits into
base: beta
Choose a base branch
from
Open
117 changes: 116 additions & 1 deletion src/data/ability.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1663,6 +1663,7 @@ export class PostAttackStealHeldItemAbAttr extends PostAttackAbAttr {
const stolenItem = heldItems[pokemon.randSeedInt(heldItems.length)];
pokemon.scene.tryTransferHeldItemModifier(stolenItem, pokemon, false).then(success => {
if (success) {
defender.turnData.itemsLost += 1;
pokemon.scene.queueMessage(i18next.t("abilityTriggers:postAttackStealHeldItem", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), defenderName: defender.name, stolenItemType: stolenItem.type.name }));
}
resolve(success);
Expand Down Expand Up @@ -1756,6 +1757,7 @@ export class PostDefendStealHeldItemAbAttr extends PostDefendAbAttr {
const stolenItem = heldItems[pokemon.randSeedInt(heldItems.length)];
pokemon.scene.tryTransferHeldItemModifier(stolenItem, pokemon, false).then(success => {
if (success) {
attacker.turnData.itemsLost += 1;
pokemon.scene.queueMessage(i18next.t("abilityTriggers:postDefendStealHeldItem", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), attackerName: attacker.name, stolenItemType: stolenItem.type.name }));
}
resolve(success);
Expand Down Expand Up @@ -3806,6 +3808,117 @@ export class PostDancingMoveAbAttr extends PostMoveUsedAbAttr {
}
}

/**
* Ability attribute for Unburden, triggers when a Pokemon consumes a berry they are holding
* @extends PostTurnAbAttr
* @see {@linkcode applyPostTurn}
* @see {@linkcode getCondition}
*/
export class UnburdenBerryRemovedAbAttr extends PostTurnAbAttr {

/**
*
* @param {Pokemon} pokemon the {@linkcode Pokemon} with this ability
* @param passive n/a
* @param simulated whether the ability is being simulated
* @param args n/a
* @returns `true` if the ability is applied
*/
applyPostTurn(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean {
if (simulated) {
return simulated;
}

if (pokemon.getTag(BattlerTagType.UNBURDEN)) {
return false;
}

pokemon.addTag(BattlerTagType.UNBURDEN);
return true;
}

getCondition(): AbAttrCondition {
return (pokemon: Pokemon) => pokemon.battleData.berriesEaten.length !== 0;
muscode13 marked this conversation as resolved.
Show resolved Hide resolved
}

}

/**
* Ability attribute for Unburden, triggers upon an item being lost while defending (Knock Off, Thief, Pluck)
* @extends PostDefendAbAttr
* @see {@linkcode applyPostDefend}
* @see {@linkcode getCondition}
*/
export class UnburdenDefendingItemRemovedAbAttr extends PostDefendAbAttr {

/**
*
* @param {Pokemon} pokemon the {@linkcode Pokemon} with this ability
* @param passive n/a
* @param simulated whether the ability is being simulated
* @param attacker n/a
* @param move n/a
* @param hitResult n/a
* @param args n/a
* @returns `true` if the ability is applied
*/
applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean {
if (simulated) {
return simulated;
}

if (pokemon.getTag(BattlerTagType.UNBURDEN)) {
return false;
}

pokemon.addTag(BattlerTagType.UNBURDEN);
return true;
}

getCondition(): AbAttrCondition {
return (pokemon: Pokemon) => pokemon.turnData.itemsLost > 0;
}

}

/**
* Ability attribute for Unburden, triggers upon an item being lost while attacking (Pickpocket)
muscode13 marked this conversation as resolved.
Show resolved Hide resolved
* @extends PostAttackAbAttr
* @see {@linkcode applyPostAttackAfterMoveTypeCheck}
* @see {@linkcode getCondition}
*/
export class UnburdenAttackingItemRemovedAbAttr extends PostAttackAbAttr {

/**
*
* @param {Pokemon} pokemon the {@linkcode Pokemon} with this ability
* @param passive n/a
* @param simulated whether the ability is being simulated
* @param defender n/a
* @param move n/a
* @param hitResult n/a
* @param args n/a
* @returns `true` if the ability is applied
*/
applyPostAttackAfterMoveTypeCheck(pokemon: Pokemon, passive: boolean, simulated: boolean, defender: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean {
if (simulated) {
return simulated;
}

if (pokemon.getTag(BattlerTagType.UNBURDEN)) {
return false;
}

pokemon.addTag(BattlerTagType.UNBURDEN);
return true;
}

getCondition(): AbAttrCondition {
return (pokemon: Pokemon) => pokemon.turnData.itemsLost > 0;
}

}

export class StatStageChangeMultiplierAbAttr extends AbAttr {
private multiplier: integer;

Expand Down Expand Up @@ -5117,7 +5230,9 @@ export function initAbilities() {
new Ability(Abilities.ANGER_POINT, 4)
.attr(PostDefendCritStatStageChangeAbAttr, Stat.ATK, 6),
new Ability(Abilities.UNBURDEN, 4)
.unimplemented(),
.attr(UnburdenBerryRemovedAbAttr)
.attr(UnburdenAttackingItemRemovedAbAttr)
.attr(UnburdenDefendingItemRemovedAbAttr),
muscode13 marked this conversation as resolved.
Show resolved Hide resolved
new Ability(Abilities.HEATPROOF, 4)
.attr(ReceivedTypeDamageMultiplierAbAttr, Type.FIRE, 0.5)
.attr(ReduceBurnDamageAbAttr, 0.5)
Expand Down
18 changes: 18 additions & 0 deletions src/data/battler-tags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1558,6 +1558,22 @@ export class AbilityBattlerTag extends BattlerTag {
}
}

/**
* Tag used by Unburden to double speed
* @extends AbilityBattlerTag
*/
export class UnburdenTag extends AbilityBattlerTag {
muscode13 marked this conversation as resolved.
Show resolved Hide resolved
constructor() {
super(BattlerTagType.UNBURDEN, Abilities.UNBURDEN, BattlerTagLapseType.CUSTOM, 1);
}
onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon);
}
onRemove(pokemon: Pokemon): void {
super.onRemove(pokemon);
}
}

export class TruantTag extends AbilityBattlerTag {
constructor() {
super(BattlerTagType.TRUANT, Abilities.TRUANT, BattlerTagLapseType.MOVE, 1);
Expand Down Expand Up @@ -2881,6 +2897,8 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: number, source
return new ThroatChoppedTag();
case BattlerTagType.GORILLA_TACTICS:
return new GorillaTacticsTag();
case BattlerTagType.UNBURDEN:
return new UnburdenTag();
case BattlerTagType.SUBSTITUTE:
return new SubstituteTag(sourceMove, sourceId);
case BattlerTagType.AUTOTOMIZED:
Expand Down
3 changes: 3 additions & 0 deletions src/data/move.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2175,6 +2175,7 @@ export class StealHeldItemChanceAttr extends MoveEffectAttr {
const stolenItem = tierHeldItems[user.randSeedInt(tierHeldItems.length)];
user.scene.tryTransferHeldItemModifier(stolenItem, user, false).then(success => {
if (success) {
target.turnData.itemsLost += 1;
user.scene.queueMessage(i18next.t("moveTriggers:stoleItem", { pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target), itemName: stolenItem.type.name }));
}
resolve(success);
Expand Down Expand Up @@ -2256,6 +2257,7 @@ export class RemoveHeldItemAttr extends MoveEffectAttr {
// Decrease item amount and update icon
!--removedItem.stackCount;
target.scene.updateModifiers(target.isPlayer());
target.turnData.itemsLost += 1;

if (this.berriesOnly) {
user.scene.queueMessage(i18next.t("moveTriggers:incineratedItem", { pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target), itemName: removedItem.type.name }));
Expand Down Expand Up @@ -2370,6 +2372,7 @@ export class StealEatBerryAttr extends EatBerryAttr {
}
// if the target has berries, pick a random berry and steal it
this.chosenBerry = heldBerries[user.randSeedInt(heldBerries.length)];
target.turnData.itemsLost += 1;
const message = i18next.t("battle:stealEatBerry", { pokemonName: user.name, targetName: target.name, berryName: this.chosenBerry.type.name });
user.scene.queueMessage(message);
this.reduceBerryModifier(target);
Expand Down
1 change: 1 addition & 0 deletions src/enums/battler-tag-type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ export enum BattlerTagType {
DRAGON_CHEER = "DRAGON_CHEER",
NO_RETREAT = "NO_RETREAT",
GORILLA_TACTICS = "GORILLA_TACTICS",
UNBURDEN = "UNBURDEN",
THROAT_CHOPPED = "THROAT_CHOPPED",
TAR_SHOT = "TAR_SHOT",
BURNED_UP = "BURNED_UP",
Expand Down
4 changes: 4 additions & 0 deletions src/field/pokemon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -949,6 +949,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
if (this.status && this.status.effect === StatusEffect.PARALYSIS) {
ret >>= 1;
}
if (this.getTag(BattlerTagType.UNBURDEN)) {
muscode13 marked this conversation as resolved.
Show resolved Hide resolved
ret *= 2;
}
break;
}

Expand Down Expand Up @@ -5060,6 +5063,7 @@ export class PokemonTurnData {
public statStagesIncreased: boolean = false;
public statStagesDecreased: boolean = false;
public moveEffectiveness: TypeDamageMultiplier | null = null;
public itemsLost: number = 0;
public combiningPledge?: Moves;
}

Expand Down
1 change: 1 addition & 0 deletions src/modifier/modifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3125,6 +3125,7 @@ export abstract class HeldItemTransferModifier extends PokemonHeldItemModifier {
const randItem = itemModifiers[randItemIndex];
heldItemTransferPromises.push(pokemon.scene.tryTransferHeldItemModifier(randItem, pokemon, false).then(success => {
if (success) {
targetPokemon.turnData.itemsLost += 1;
transferredModifierTypes.push(randItem.type);
itemModifiers.splice(randItemIndex, 1);
}
Expand Down
Loading