Refactor single-use items

This adds a `boosts` property to items that runs in `useItem`.
This allows it to be added to `datasearch` or similar plugins.
The item activation messages are now as accurate as in-game.
The Gem activation message is also consolidated in `useItem`.
This commit is contained in:
The Immortal 2020-01-28 13:21:23 +04:00
parent 0e9e68db71
commit 68e0bcb75f
4 changed files with 114 additions and 123 deletions

View File

@ -42,10 +42,13 @@ let BattleItems = {
basePower: 30,
},
onAfterDamage(damage, target, source, move) {
if (move.type === 'Water' && target.useItem()) {
this.boost({spa: 1});
if (move.type === 'Water') {
target.useItem();
}
},
boosts: {
spa: 1,
},
num: 545,
gen: 5,
desc: "Raises holder's Sp. Atk by 1 stage if hit by a Water-type attack. Single use.",
@ -76,10 +79,13 @@ let BattleItems = {
basePower: 30,
},
onAfterBoost(boost, target, source, effect) {
if (effect.id === 'intimidate' && target.useItem()) {
this.boost({spe: 1});
if (effect.id === 'intimidate') {
target.useItem();
}
},
boosts: {
spe: 1,
},
num: 846,
gen: 7,
desc: "Raises holder's Speed by 1 stage if it gets affected by Intimidate. Single use.",
@ -649,11 +655,8 @@ let BattleItems = {
isGem: true,
onSourceTryPrimaryHit(target, source, move) {
if (target === source || move.category === 'Status') return;
if (move.type === 'Bug') {
if (source.useItem()) {
this.add('-enditem', source, 'Bug Gem', '[from] gem', '[move] ' + move.name);
source.addVolatile('gem');
}
if (move.type === 'Bug' && source.useItem()) {
source.addVolatile('gem');
}
},
num: 558,
@ -734,10 +737,13 @@ let BattleItems = {
basePower: 30,
},
onAfterDamage(damage, target, source, move) {
if (move.type === 'Electric' && target.useItem()) {
this.boost({atk: 1});
if (move.type === 'Electric') {
target.useItem();
}
},
boosts: {
atk: 1,
},
num: 546,
gen: 5,
desc: "Raises holder's Attack by 1 if hit by an Electric-type attack. Single use.",
@ -1170,11 +1176,8 @@ let BattleItems = {
isGem: true,
onSourceTryPrimaryHit(target, source, move) {
if (target === source || move.category === 'Status') return;
if (move.type === 'Dark') {
if (source.useItem()) {
this.add('-enditem', source, 'Dark Gem', '[from] gem', '[move] ' + move.name);
source.addVolatile('gem');
}
if (move.type === 'Dark' && source.useItem()) {
source.addVolatile('gem');
}
},
num: 562,
@ -1394,11 +1397,8 @@ let BattleItems = {
isGem: true,
onSourceTryPrimaryHit(target, source, move) {
if (target === source || move.category === 'Status') return;
if (move.type === 'Dragon') {
if (source.useItem()) {
this.add('-enditem', source, 'Dragon Gem', '[from] gem', '[move] ' + move.name);
source.addVolatile('gem');
}
if (move.type === 'Dragon' && source.useItem()) {
source.addVolatile('gem');
}
},
num: 561,
@ -1632,11 +1632,8 @@ let BattleItems = {
isGem: true,
onSourceTryPrimaryHit(target, source, move) {
if (target === source || move.category === 'Status' || ['firepledge', 'grasspledge', 'waterpledge'].includes(move.id)) return;
if (move.type === 'Electric') {
if (source.useItem()) {
this.add('-enditem', source, 'Electric Gem', '[from] gem', '[move] ' + move.name);
source.addVolatile('gem');
}
if (move.type === 'Electric' && source.useItem()) {
source.addVolatile('gem');
}
},
num: 550,
@ -1669,16 +1666,19 @@ let BattleItems = {
basePower: 10,
},
onStart(pokemon) {
if (!pokemon.ignoringItem() && this.field.isTerrain('electricterrain') && pokemon.useItem()) {
this.boost({def: 1});
if (!pokemon.ignoringItem() && this.field.isTerrain('electricterrain')) {
pokemon.useItem();
}
},
onAnyTerrainStart() {
const pokemon = this.effectData.target;
if (this.field.isTerrain('electricterrain') && pokemon.useItem()) {
this.boost({def: 1}, pokemon);
if (this.field.isTerrain('electricterrain')) {
pokemon.useItem();
}
},
boosts: {
def: 1,
},
num: 881,
gen: 7,
desc: "If the terrain is Electric Terrain, raises holder's Defense by 1 stage. Single use.",
@ -1794,11 +1794,8 @@ let BattleItems = {
isGem: true,
onSourceTryPrimaryHit(target, source, move) {
if (target === source || move.category === 'Status') return;
if (move.type === 'Fairy') {
if (source.useItem()) {
this.add('-enditem', source, 'Fairy Gem', '[from] gem', '[move] ' + move.name);
source.addVolatile('gem');
}
if (move.type === 'Fairy' && source.useItem()) {
source.addVolatile('gem');
}
},
num: 715,
@ -1839,11 +1836,8 @@ let BattleItems = {
isGem: true,
onSourceTryPrimaryHit(target, source, move) {
if (target === source || move.category === 'Status') return;
if (move.type === 'Fighting') {
if (source.useItem()) {
this.add('-enditem', source, 'Fighting Gem', '[from] gem', '[move] ' + move.name);
source.addVolatile('gem');
}
if (move.type === 'Fighting' && source.useItem()) {
source.addVolatile('gem');
}
},
num: 553,
@ -1916,11 +1910,8 @@ let BattleItems = {
isGem: true,
onSourceTryPrimaryHit(target, source, move) {
if (target === source || move.category === 'Status' || ['firepledge', 'grasspledge', 'waterpledge'].includes(move.id)) return;
if (move.type === 'Fire') {
if (source.useItem()) {
this.add('-enditem', source, 'Fire Gem', '[from] gem', '[move] ' + move.name);
source.addVolatile('gem');
}
if (move.type === 'Fire' && source.useItem()) {
source.addVolatile('gem');
}
},
num: 548,
@ -2064,11 +2055,8 @@ let BattleItems = {
isGem: true,
onSourceTryPrimaryHit(target, source, move) {
if (target === source || move.category === 'Status') return;
if (move.type === 'Flying') {
if (source.useItem()) {
this.add('-enditem', source, 'Flying Gem', '[from] gem', '[move] ' + move.name);
source.addVolatile('gem');
}
if (move.type === 'Flying' && source.useItem()) {
source.addVolatile('gem');
}
},
num: 556,
@ -2305,11 +2293,8 @@ let BattleItems = {
isGem: true,
onSourceTryPrimaryHit(target, source, move) {
if (target === source || move.category === 'Status') return;
if (move.type === 'Ghost') {
if (source.useItem()) {
this.add('-enditem', source, 'Ghost Gem', '[from] gem', '[move] ' + move.name);
source.addVolatile('gem');
}
if (move.type === 'Ghost' && source.useItem()) {
source.addVolatile('gem');
}
},
num: 560,
@ -2382,11 +2367,8 @@ let BattleItems = {
isGem: true,
onSourceTryPrimaryHit(target, source, move) {
if (target === source || move.category === 'Status' || ['firepledge', 'grasspledge', 'waterpledge'].includes(move.id)) return;
if (move.type === 'Grass') {
if (source.useItem()) {
this.add('-enditem', source, 'Grass Gem', '[from] gem', '[move] ' + move.name);
source.addVolatile('gem');
}
if (move.type === 'Grass' && source.useItem()) {
source.addVolatile('gem');
}
},
num: 551,
@ -2433,16 +2415,19 @@ let BattleItems = {
basePower: 10,
},
onStart(pokemon) {
if (!pokemon.ignoringItem() && this.field.isTerrain('grassyterrain') && pokemon.useItem()) {
this.boost({def: 1});
if (!pokemon.ignoringItem() && this.field.isTerrain('grassyterrain')) {
pokemon.useItem();
}
},
onAnyTerrainStart() {
const pokemon = this.effectData.target;
if (this.field.isTerrain('grassyterrain') && pokemon.useItem()) {
this.boost({def: 1}, pokemon);
if (this.field.isTerrain('grassyterrain')) {
pokemon.useItem();
}
},
boosts: {
def: 1,
},
num: 884,
gen: 7,
desc: "If the terrain is Grassy Terrain, raises holder's Defense by 1 stage. Single use.",
@ -2514,11 +2499,8 @@ let BattleItems = {
isGem: true,
onSourceTryPrimaryHit(target, source, move) {
if (target === source || move.category === 'Status') return;
if (move.type === 'Ground') {
if (source.useItem()) {
this.add('-enditem', source, 'Ground Gem', '[from] gem', '[move] ' + move.name);
source.addVolatile('gem');
}
if (move.type === 'Ground' && source.useItem()) {
source.addVolatile('gem');
}
},
num: 555,
@ -2746,11 +2728,8 @@ let BattleItems = {
isGem: true,
onSourceTryPrimaryHit(target, source, move) {
if (target === source || move.category === 'Status') return;
if (move.type === 'Ice') {
if (source.useItem()) {
this.add('-enditem', source, 'Ice Gem', '[from] gem', '[move] ' + move.name);
source.addVolatile('gem');
}
if (move.type === 'Ice' && source.useItem()) {
source.addVolatile('gem');
}
},
num: 552,
@ -3426,10 +3405,13 @@ let BattleItems = {
basePower: 30,
},
onAfterDamage(damage, target, source, move) {
if (move.type === 'Water' && target.useItem()) {
this.boost({spd: 1});
if (move.type === 'Water') {
target.useItem();
}
},
boosts: {
spd: 1,
},
num: 648,
gen: 6,
desc: "Raises holder's Sp. Def by 1 stage if hit by a Water-type attack. Single use.",
@ -3975,16 +3957,19 @@ let BattleItems = {
basePower: 10,
},
onStart(pokemon) {
if (!pokemon.ignoringItem() && this.field.isTerrain('mistyterrain') && pokemon.useItem()) {
this.boost({spd: 1});
if (!pokemon.ignoringItem() && this.field.isTerrain('mistyterrain')) {
pokemon.useItem();
}
},
onAnyTerrainStart() {
const pokemon = this.effectData.target;
if (this.field.isTerrain('mistyterrain') && pokemon.useItem()) {
this.boost({spd: 1}, pokemon);
if (this.field.isTerrain('mistyterrain')) {
pokemon.useItem();
}
},
boosts: {
spd: 1,
},
num: 883,
gen: 7,
desc: "If the terrain is Misty Terrain, raises holder's Sp. Def by 1 stage. Single use.",
@ -4116,11 +4101,8 @@ let BattleItems = {
isGem: true,
onSourceTryPrimaryHit(target, source, move) {
if (target === source || move.category === 'Status' || ['firepledge', 'grasspledge', 'waterpledge'].includes(move.id)) return;
if (move.type === 'Normal') {
if (source.useItem()) {
this.add('-enditem', source, 'Normal Gem', '[from] gem', '[move] ' + move.name);
source.addVolatile('gem');
}
if (move.type === 'Normal' && source.useItem()) {
source.addVolatile('gem');
}
},
num: 564,
@ -4492,11 +4474,8 @@ let BattleItems = {
isGem: true,
onSourceTryPrimaryHit(target, source, move) {
if (target === source || move.category === 'Status') return;
if (move.type === 'Poison') {
if (source.useItem()) {
this.add('-enditem', source, 'Poison Gem', '[from] gem', '[move] ' + move.name);
source.addVolatile('gem');
}
if (move.type === 'Poison' && source.useItem()) {
source.addVolatile('gem');
}
},
num: 554,
@ -4765,11 +4744,8 @@ let BattleItems = {
isGem: true,
onSourceTryPrimaryHit(target, source, move) {
if (target === source || move.category === 'Status') return;
if (move.type === 'Psychic') {
if (source.useItem()) {
this.add('-enditem', source, 'Psychic Gem', '[from] gem', '[move] ' + move.name);
source.addVolatile('gem');
}
if (move.type === 'Psychic' && source.useItem()) {
source.addVolatile('gem');
}
},
num: 557,
@ -4802,16 +4778,19 @@ let BattleItems = {
basePower: 10,
},
onStart(pokemon) {
if (!pokemon.ignoringItem() && this.field.isTerrain('psychicterrain') && pokemon.useItem()) {
this.boost({spd: 1});
if (!pokemon.ignoringItem() && this.field.isTerrain('psychicterrain')) {
pokemon.useItem();
}
},
onAnyTerrainStart() {
const pokemon = this.effectData.target;
if (this.field.isTerrain('psychicterrain') && pokemon.useItem()) {
this.boost({spd: 1}, pokemon);
if (this.field.isTerrain('psychicterrain')) {
pokemon.useItem();
}
},
boosts: {
spd: 1,
},
num: 882,
gen: 7,
desc: "If the terrain is Psychic Terrain, raises holder's Sp. Def by 1 stage. Single use.",
@ -5109,11 +5088,8 @@ let BattleItems = {
isGem: true,
onSourceTryPrimaryHit(target, source, move) {
if (target === source || move.category === 'Status') return;
if (move.type === 'Rock') {
if (source.useItem()) {
this.add('-enditem', source, 'Rock Gem', '[from] gem', '[move] ' + move.name);
source.addVolatile('gem');
}
if (move.type === 'Rock' && source.useItem()) {
source.addVolatile('gem');
}
},
num: 559,
@ -5194,10 +5170,13 @@ let BattleItems = {
basePower: 100,
},
onUpdate(pokemon) {
if (this.field.getPseudoWeather('trickroom') && pokemon.useItem()) {
this.boost({spe: -1}, pokemon, pokemon);
if (this.field.getPseudoWeather('trickroom')) {
pokemon.useItem();
}
},
boosts: {
spe: -1,
},
num: 1122,
gen: 8,
desc: "If Trick Room is active, lowers holder's Speed by 1 stage. Single use.",
@ -5734,10 +5713,13 @@ let BattleItems = {
basePower: 30,
},
onAfterDamage(damage, target, source, move) {
if (move.type === 'Ice' && target.useItem()) {
this.boost({atk: 1});
if (move.type === 'Ice') {
target.useItem();
}
},
boosts: {
atk: 1,
},
num: 649,
gen: 6,
desc: "Raises holder's Attack by 1 if hit by an Ice-type attack. Single use.",
@ -5943,11 +5925,8 @@ let BattleItems = {
isGem: true,
onSourceTryPrimaryHit(target, source, move) {
if (target === source || move.category === 'Status') return;
if (move.type === 'Steel') {
if (source.useItem()) {
this.add('-enditem', source, 'Steel Gem', '[from] gem', '[move] ' + move.name);
source.addVolatile('gem');
}
if (move.type === 'Steel' && source.useItem()) {
source.addVolatile('gem');
}
},
num: 563,
@ -6198,10 +6177,13 @@ let BattleItems = {
basePower: 30,
},
onAfterMoveSecondarySelf(target, source, move) {
if (move.flags['sound'] && target.useItem()) {
this.boost({spa: 1}); // TODO: Find exact value, and whether this activates before or after use
if (move.flags['sound']) {
target.useItem();
}
},
boosts: {
spa: 1,
},
num: 1118,
gen: 8,
desc: "Raises holder's Special Attack by 1 stage after using a sound move. Single use.",
@ -6391,11 +6373,8 @@ let BattleItems = {
isGem: true,
onSourceTryPrimaryHit(target, source, move) {
if (target === source || move.category === 'Status' || ['firepledge', 'grasspledge', 'waterpledge'].includes(move.id)) return;
if (move.type === 'Water') {
if (source.useItem()) {
this.add('-enditem', source, 'Water Gem', '[from] gem', '[move] ' + move.name);
source.addVolatile('gem');
}
if (move.type === 'Water' && source.useItem()) {
source.addVolatile('gem');
}
},
num: 549,
@ -6487,10 +6466,14 @@ let BattleItems = {
},
onHitPriority: 1,
onHit(target, source, move) {
if (target.hp && move.category !== 'Status' && !move.damage && !move.damageCallback && target.getMoveHitData(move).typeMod > 0 && target.useItem()) {
this.boost({atk: 2, spa: 2});
if (target.hp && move.category !== 'Status' && !move.damage && !move.damageCallback && target.getMoveHitData(move).typeMod > 0) {
target.useItem();
}
},
boosts: {
atk: 2,
spa: 2,
},
num: 639,
gen: 6,
desc: "If holder is hit super effectively, raises Attack, Sp. Atk by 2 stages. Single use.",

View File

@ -1637,6 +1637,8 @@ export class Battle {
if (!effect) break;
if (effect.effectType === 'Move') {
this.add(msg, target, boostName, boostBy);
} else if (effect.effectType === 'Item') {
this.add(msg, target, boostName, boostBy, '[from] item: ' + effect.name);
} else {
if (effect.effectType === 'Ability' && !boosted) {
this.add('-ability', target, effect.name, 'boost');

View File

@ -782,6 +782,7 @@ interface ItemData extends EffectData, ItemEventMethods, EventMethods {
zMoveFrom?: string
zMoveType?: string
itemUser?: string[]
boosts?: SparseBoostsTable | false
}
interface ModdedItemData extends Partial<ItemData>, ModdedEffectData {

View File

@ -1419,9 +1419,14 @@ export class Pokemon {
this.battle.add('-enditem', this, item, '[of] ' + source);
break;
default:
if (!item.isGem) {
if (item.isGem) {
this.battle.add('-enditem', this, item, '[from] gem');
} else {
this.battle.add('-enditem', this, item);
}
if (item.boosts) {
this.battle.boost(item.boosts, this, source, item);
}
break;
}