mirror of
https://github.com/smogon/pokemon-showdown-client.git
synced 2026-04-25 16:14:01 -05:00
7027 lines
234 KiB
JavaScript
7027 lines
234 KiB
JavaScript
/*
|
||
|
||
License: GPLv2
|
||
<http://www.gnu.org/licenses/gpl-2.0.html>
|
||
|
||
*/
|
||
|
||
// par: -webkit-filter: sepia(100%) hue-rotate(373deg) saturate(592%);
|
||
// -webkit-filter: sepia(100%) hue-rotate(22deg) saturate(820%) brightness(29%);
|
||
// psn: -webkit-filter: sepia(100%) hue-rotate(618deg) saturate(285%);
|
||
// brn: -webkit-filter: sepia(100%) hue-rotate(311deg) saturate(469%);
|
||
// slp: -webkit-filter: grayscale(100%);
|
||
// frz: -webkit-filter: sepia(100%) hue-rotate(154deg) saturate(759%) brightness(23%);
|
||
|
||
$.extend($.easing, {
|
||
ballisticUp: function (x, t, b, c, d) {
|
||
return -3 * x * x + 4 * x;
|
||
},
|
||
ballisticDown: function (x, t, b, c, d) {
|
||
x = 1 - x;
|
||
return 1 - (-3 * x * x + 4 * x);
|
||
},
|
||
quadUp: function (x, t, b, c, d) {
|
||
x = 1 - x;
|
||
return 1 - (x * x);
|
||
},
|
||
quadDown: function (x, t, b, c, d) {
|
||
return x * x;
|
||
}
|
||
});
|
||
|
||
var BattleSoundLibrary = (function () {
|
||
function BattleSoundLibrary() {
|
||
// effects
|
||
this.effectCache = {};
|
||
|
||
// bgm
|
||
this.bgmCache = {};
|
||
this.bgm = null;
|
||
|
||
// misc
|
||
this.soundPlaceholder = {
|
||
play: function () { return this; },
|
||
pause: function () { return this; },
|
||
stop: function () { return this; },
|
||
resume: function () { return this; },
|
||
setVolume: function () { return this; },
|
||
onposition: function () { return this; }
|
||
};
|
||
}
|
||
|
||
// options
|
||
BattleSoundLibrary.prototype.effectVolume = 50;
|
||
BattleSoundLibrary.prototype.bgmVolume = 50;
|
||
BattleSoundLibrary.prototype.muted = false;
|
||
|
||
BattleSoundLibrary.prototype.loadEffect = function (url) {
|
||
if (this.effectCache[url] && this.effectCache[url] !== this.soundPlaceholder) {
|
||
return this.effectCache[url];
|
||
}
|
||
try {
|
||
this.effectCache[url] = soundManager.createSound({
|
||
id: url,
|
||
url: Tools.resourcePrefix + url,
|
||
volume: this.effectVolume
|
||
});
|
||
} catch (e) {}
|
||
if (!this.effectCache[url]) {
|
||
this.effectCache[url] = this.soundPlaceholder;
|
||
}
|
||
return this.effectCache[url];
|
||
};
|
||
BattleSoundLibrary.prototype.playEffect = function (url) {
|
||
if (!this.muted) this.loadEffect(url).setVolume(this.effectVolume).play();
|
||
};
|
||
|
||
BattleSoundLibrary.prototype.loadBgm = function (url, loopstart, loopend) {
|
||
if (this.bgmCache[url]) {
|
||
if (this.bgmCache[url] !== this.soundPlaceholder || loopstart === undefined) {
|
||
return this.bgmCache[url];
|
||
}
|
||
}
|
||
try {
|
||
this.bgmCache[url] = soundManager.createSound({
|
||
id: url,
|
||
url: Tools.resourcePrefix + url,
|
||
volume: this.bgmVolume
|
||
});
|
||
} catch (e) {}
|
||
if (!this.bgmCache[url]) {
|
||
// couldn't load
|
||
// suppress crash
|
||
return (this.bgmCache[url] = this.soundPlaceholder);
|
||
}
|
||
this.bgmCache[url].onposition(loopend, function (evP) {
|
||
this.setPosition(this.position - (loopend - loopstart));
|
||
});
|
||
return this.bgmCache[url];
|
||
};
|
||
BattleSoundLibrary.prototype.playBgm = function (url, loopstart, loopstop) {
|
||
if (this.bgm === this.loadBgm(url, loopstart, loopstop)) {
|
||
if (!this.bgm.paused && this.bgm.playState) {
|
||
return;
|
||
}
|
||
} else {
|
||
this.stopBgm();
|
||
}
|
||
try {
|
||
this.bgm = this.loadBgm(url, loopstart, loopstop).setVolume(this.bgmVolume);
|
||
if (!this.muted) {
|
||
if (this.bgm.paused) {
|
||
this.bgm.resume();
|
||
} else {
|
||
this.bgm.play();
|
||
}
|
||
}
|
||
} catch (e) {}
|
||
};
|
||
BattleSoundLibrary.prototype.pauseBgm = function () {
|
||
if (this.bgm) {
|
||
this.bgm.pause();
|
||
}
|
||
};
|
||
BattleSoundLibrary.prototype.stopBgm = function () {
|
||
if (this.bgm) {
|
||
this.bgm.stop();
|
||
this.bgm = null;
|
||
}
|
||
};
|
||
|
||
// setting
|
||
BattleSoundLibrary.prototype.setMute = function (muted) {
|
||
muted = !!muted;
|
||
if (this.muted == muted) return;
|
||
this.muted = muted;
|
||
if (muted) {
|
||
if (this.bgm) this.bgm.pause();
|
||
} else {
|
||
if (this.bgm) this.bgm.play();
|
||
}
|
||
};
|
||
|
||
function loudnessPercentToAmplitudePercent(loudnessPercent) {
|
||
// 10 dB is perceived as approximately twice as loud
|
||
var decibels = 10 * Math.log(loudnessPercent / 100) / Math.log(2);
|
||
return Math.pow(10, decibels / 20) * 100;
|
||
}
|
||
BattleSoundLibrary.prototype.setBgmVolume = function (bgmVolume) {
|
||
this.bgmVolume = loudnessPercentToAmplitudePercent(bgmVolume);
|
||
if (this.bgm) {
|
||
try {
|
||
this.bgm.setVolume(this.bgmVolume);
|
||
} catch (e) {}
|
||
}
|
||
};
|
||
BattleSoundLibrary.prototype.setEffectVolume = function (effectVolume) {
|
||
this.effectVolume = loudnessPercentToAmplitudePercent(effectVolume);
|
||
};
|
||
|
||
return BattleSoundLibrary;
|
||
})();
|
||
|
||
var BattleSound = new BattleSoundLibrary();
|
||
|
||
var Pokemon = (function () {
|
||
function Pokemon(species, side) {
|
||
this.side = side;
|
||
|
||
this.atk = 0;
|
||
this.def = 0;
|
||
this.spa = 0;
|
||
this.spd = 0;
|
||
this.spe = 0;
|
||
|
||
this.atkStat = 0;
|
||
this.defStat = 0;
|
||
this.spaStat = 0;
|
||
this.spdStat = 0;
|
||
this.speStat = 0;
|
||
|
||
this.boosts = {};
|
||
|
||
this.hp = 0;
|
||
this.maxhp = 0;
|
||
this.hpcolor = '';
|
||
this.moves = [];
|
||
this.ability = '';
|
||
this.baseAbility = '';
|
||
this.item = '';
|
||
this.itemEffect = '';
|
||
this.prevItem = '';
|
||
this.prevItemEffect = '';
|
||
this.species = species;
|
||
this.fainted = false;
|
||
this.zerohp = false;
|
||
|
||
this.status = '';
|
||
this.statusStage = 0;
|
||
this.volatiles = {};
|
||
this.turnstatuses = {};
|
||
this.movestatuses = {};
|
||
this.lastmove = '';
|
||
|
||
// [[moveName, ppUsed]]
|
||
this.moveTrack = [];
|
||
|
||
this.name = '';
|
||
this.species = '';
|
||
this.id = '';
|
||
this.statbarElem = null;
|
||
}
|
||
|
||
Pokemon.prototype.getHPColor = function () {
|
||
if (this.hpcolor) return this.hpcolor;
|
||
var ratio = this.hp / this.maxhp;
|
||
if (ratio > 0.5) return 'g';
|
||
if (ratio > 0.2) return 'y';
|
||
return 'r';
|
||
};
|
||
Pokemon.prototype.getHPColorClass = function () {
|
||
switch (this.getHPColor()) {
|
||
case 'y': return ' hpbar-yellow';
|
||
case 'r': return ' hpbar-red';
|
||
}
|
||
return '';
|
||
};
|
||
Pokemon.prototype.getPixelRange = function (pixels, color) {
|
||
var epsilon = 0.5 / 714;
|
||
|
||
if (pixels === 0) return [0, 0];
|
||
if (pixels === 1) return [0 + epsilon, 2 / 48 - epsilon];
|
||
if (pixels === 9) {
|
||
if (color === 'y') { // ratio is > 0.2
|
||
return [0.2 + epsilon, 10 / 48 - epsilon];
|
||
} else { // ratio is <= 0.2
|
||
return [9 / 48, 0.2];
|
||
}
|
||
}
|
||
if (pixels === 24) {
|
||
if (color === 'g') { // ratio is > 0.5
|
||
return [0.5 + epsilon, 25 / 48 - epsilon];
|
||
} else { // ratio is exactly 0.5
|
||
return [0.5, 0.5];
|
||
}
|
||
}
|
||
if (pixels === 48) return [1, 1];
|
||
|
||
return [pixels / 48, (pixels + 1) / 48 - epsilon];
|
||
};
|
||
Pokemon.prototype.getFormattedRange = function (range, precision, separator) {
|
||
if (range[0] === range[1]) {
|
||
var percentage = Math.abs(range[0] * 100);
|
||
if (Math.floor(percentage) === percentage) {
|
||
return percentage + '%';
|
||
}
|
||
return percentage.toFixed(precision) + '%';
|
||
}
|
||
var lower, upper;
|
||
if (precision === 0) {
|
||
lower = Math.floor(range[0] * 100);
|
||
upper = Math.ceil(range[1] * 100);
|
||
} else {
|
||
lower = (range[0] * 100).toFixed(precision);
|
||
upper = (range[1] * 100).toFixed(precision);
|
||
}
|
||
return lower + separator + upper + '%';
|
||
};
|
||
// Returns [min, max] damage dealt as a proportion of total HP from 0 to 1
|
||
Pokemon.prototype.getDamageRange = function (damage) {
|
||
if (damage[1] !== 48) {
|
||
var ratio = damage[0] / damage[1];
|
||
return [ratio, ratio];
|
||
} else if (damage[3] === undefined) {
|
||
// wrong pixel damage.
|
||
// this case exists for backward compatibility only.
|
||
return [damage[2] / 100, damage[2] / 100];
|
||
}
|
||
// pixel damage
|
||
var oldrange = this.getPixelRange(damage[3], damage[4]);
|
||
var newrange = this.getPixelRange(damage[3] + damage[0], this.hpcolor);
|
||
if (damage[0] === 0) {
|
||
// no change in displayed pixel width
|
||
return [0, newrange[1] - newrange[0]];
|
||
}
|
||
if (oldrange[0] < newrange[0]) { // swap order
|
||
var r = oldrange;
|
||
oldrange = newrange;
|
||
newrange = r;
|
||
}
|
||
return [oldrange[0] - newrange[1], oldrange[1] - newrange[0]];
|
||
};
|
||
Pokemon.prototype.healthParse = function (hpstring, parsedamage, heal) {
|
||
// returns [delta, denominator, percent(, oldnum, oldcolor)] or false
|
||
if (!hpstring || !hpstring.length) return false;
|
||
var parenIndex = hpstring.lastIndexOf('(');
|
||
if (parenIndex >= 0) {
|
||
// old style damage and health reporting
|
||
if (parsedamage) {
|
||
var damage = parseFloat(hpstring);
|
||
// unusual check preseved for backward compatbility
|
||
if (isNaN(damage)) damage = 50;
|
||
if (heal) {
|
||
this.hp += this.maxhp * damage / 100;
|
||
if (this.hp > this.maxhp) this.hp = this.maxhp;
|
||
} else {
|
||
this.hp -= this.maxhp * damage / 100;
|
||
}
|
||
// parse the absolute health information
|
||
var ret = this.healthParse(hpstring);
|
||
if (ret && (ret[1] === 100)) {
|
||
// support for old replays with nearest-100th damage and health
|
||
return [damage, 100, damage];
|
||
}
|
||
// complicated expressions preserved for backward compatibility
|
||
var percent = Math.round(Math.ceil(damage * 48 / 100) / 48 * 100);
|
||
var pixels = Math.ceil(damage * 48 / 100);
|
||
return [pixels, 48, percent];
|
||
}
|
||
if (hpstring.substr(hpstring.length - 1) !== ')') {
|
||
return false;
|
||
}
|
||
hpstring = hpstring.substr(parenIndex + 1, hpstring.length - parenIndex - 2);
|
||
}
|
||
|
||
var oldhp = (this.zerohp || this.fainted) ? 0 : (this.hp || 1);
|
||
var oldmaxhp = this.maxhp;
|
||
var oldwidth = this.hpWidth(100);
|
||
var oldcolor = this.hpcolor;
|
||
|
||
this.side.battle.parseHealth(hpstring, this);
|
||
if (oldmaxhp === 0) { // max hp not known before parsing this message
|
||
oldmaxhp = oldhp = this.maxhp;
|
||
}
|
||
|
||
var oldnum = oldhp ? (Math.floor(oldhp / oldmaxhp * this.maxhp) || 1) : 0;
|
||
var delta = this.hp - oldnum;
|
||
var deltawidth = this.hpWidth(100) - oldwidth;
|
||
return [delta, this.maxhp, deltawidth, oldnum, oldcolor];
|
||
};
|
||
Pokemon.prototype.checkDetails = function (details) {
|
||
if (!details) return false;
|
||
if (details === this.details) return true;
|
||
if (!this.needsReplace) return false;
|
||
// the actual forme was hidden on Team Preview
|
||
details = details.replace(/-[A-Za-z0-9]+(, |$)/, '$1');
|
||
return (details === this.details.replace(/-\*(, |$)/, '$1'));
|
||
};
|
||
Pokemon.prototype.getIdent = function () {
|
||
var slots = ['a', 'b', 'c', 'd', 'e', 'f'];
|
||
return this.ident.substr(0, 2) + slots[this.slot] + this.ident.substr(2);
|
||
};
|
||
Pokemon.prototype.removeVolatile = function (volatile) {
|
||
if (!this.hasVolatile(volatile)) return;
|
||
if (volatile === 'formechange') {
|
||
this.sprite.removeTransform();
|
||
}
|
||
if (this.volatiles[volatile][1]) this.volatiles[volatile][1].remove();
|
||
delete this.volatiles[volatile];
|
||
};
|
||
Pokemon.prototype.addVolatile = function (volatile) {
|
||
var battle = this.side.battle;
|
||
if (this.hasVolatile(volatile)) return;
|
||
this.volatiles[volatile] = [volatile, null];
|
||
if (volatile === 'leechseed') {
|
||
this.side.battle.spriteElemsFront[this.side.n].append('<img src="' + Tools.fxPrefix + 'energyball.png" style="display:none;position:absolute" />');
|
||
var curelem = this.side.battle.spriteElemsFront[this.side.n].children().last();
|
||
curelem.css(battle.pos({
|
||
display: 'block',
|
||
x: this.sprite.x - 30,
|
||
y: this.sprite.y - 40,
|
||
z: this.sprite.z,
|
||
scale: .2,
|
||
opacity: .6
|
||
}, BattleEffects.energyball));
|
||
var elem = curelem;
|
||
|
||
this.side.battle.spriteElemsFront[this.side.n].append('<img src="' + Tools.fxPrefix + 'energyball.png" style="display:none;position:absolute" />');
|
||
curelem = this.side.battle.spriteElemsFront[this.side.n].children().last();
|
||
curelem.css(battle.pos({
|
||
display: 'block',
|
||
x: this.sprite.x + 40,
|
||
y: this.sprite.y - 35,
|
||
z: this.sprite.z,
|
||
scale: .2,
|
||
opacity: .6
|
||
}, BattleEffects.energyball));
|
||
elem = elem.add(curelem);
|
||
|
||
this.side.battle.spriteElemsFront[this.side.n].append('<img src="' + Tools.fxPrefix + 'energyball.png" style="display:none;position:absolute" />');
|
||
curelem = this.side.battle.spriteElemsFront[this.side.n].children().last();
|
||
curelem.css(battle.pos({
|
||
display: 'block',
|
||
x: this.sprite.x + 20,
|
||
y: this.sprite.y - 25,
|
||
z: this.sprite.z,
|
||
scale: .2,
|
||
opacity: .6
|
||
}, BattleEffects.energyball));
|
||
elem = elem.add(curelem);
|
||
this.volatiles[volatile][1] = elem;
|
||
}
|
||
};
|
||
Pokemon.prototype.hasVolatile = function (volatile) {
|
||
return !!this.volatiles[volatile];
|
||
};
|
||
Pokemon.prototype.removeTurnstatus = function (volatile) {
|
||
if (!this.hasTurnstatus(volatile)) return;
|
||
if (this.turnstatuses[volatile][1]) this.turnstatuses[volatile][1].remove();
|
||
delete this.turnstatuses[volatile];
|
||
};
|
||
Pokemon.prototype.addTurnstatus = function (volatile) {
|
||
volatile = toId(volatile);
|
||
var battle = this.side.battle;
|
||
if (this.hasTurnstatus(volatile)) {
|
||
if ((volatile === 'protect' || volatile === 'magiccoat') && !battle.fastForward) {
|
||
this.turnstatuses[volatile][1].css(battle.pos({
|
||
x: this.sprite.x,
|
||
y: this.sprite.y,
|
||
z: this.sprite.behind(-15),
|
||
xscale: 1 * 1.2,
|
||
yscale: .7 * 1.2,
|
||
opacity: 1
|
||
}, BattleEffects.none), 300).animate(battle.pos({
|
||
x: this.sprite.x,
|
||
y: this.sprite.y,
|
||
z: this.sprite.behind(-15),
|
||
xscale: 1,
|
||
yscale: .7,
|
||
opacity: .4
|
||
}, BattleEffects.none), 300);
|
||
}
|
||
return;
|
||
}
|
||
this.turnstatuses[volatile] = [volatile, null];
|
||
if (volatile === 'protect' || volatile === 'magiccoat') {
|
||
this.side.battle.spriteElemsFront[this.side.n].append('<div class="turnstatus-protect" style="display:none;position:absolute" />');
|
||
var elem = this.side.battle.spriteElemsFront[this.side.n].children().last();
|
||
if (!battle.fastForward) {
|
||
elem.css(battle.pos({
|
||
display: 'block',
|
||
x: this.sprite.x,
|
||
y: this.sprite.y,
|
||
z: this.sprite.behind(-15),
|
||
xscale: 1,
|
||
yscale: 0,
|
||
opacity: .1
|
||
}, BattleEffects.none)).animate(battle.pos({
|
||
x: this.sprite.x,
|
||
y: this.sprite.y,
|
||
z: this.sprite.behind(-15),
|
||
xscale: 1,
|
||
yscale: .7,
|
||
opacity: .9
|
||
}, BattleEffects.none), 300).animate({
|
||
opacity: .4
|
||
}, 300);
|
||
} else {
|
||
elem.css(battle.pos({
|
||
display: 'block',
|
||
x: this.sprite.x,
|
||
y: this.sprite.y,
|
||
z: this.sprite.behind(-15),
|
||
xscale: 1,
|
||
yscale: .7,
|
||
opacity: .4
|
||
}, BattleEffects.none));
|
||
}
|
||
this.turnstatuses[volatile][1] = elem;
|
||
}
|
||
};
|
||
Pokemon.prototype.hasTurnstatus = function (volatile) {
|
||
return !!this.turnstatuses[volatile];
|
||
};
|
||
Pokemon.prototype.clearTurnstatuses = function () {
|
||
for (var i in this.turnstatuses) {
|
||
this.removeTurnstatus(i);
|
||
}
|
||
this.turnstatuses = {};
|
||
};
|
||
Pokemon.prototype.removeMovestatus = function (volatile) {
|
||
if (!this.hasMovestatus(volatile)) return;
|
||
if (this.movestatuses[volatile][1]) this.movestatuses[volatile][1].remove();
|
||
delete this.movestatuses[volatile];
|
||
};
|
||
Pokemon.prototype.addMovestatus = function (volatile) {
|
||
volatile = toId(volatile);
|
||
if (this.hasMovestatus(volatile)) return;
|
||
this.movestatuses[volatile] = [volatile, null];
|
||
};
|
||
Pokemon.prototype.hasMovestatus = function (volatile) {
|
||
return !!this.movestatuses[volatile];
|
||
};
|
||
Pokemon.prototype.clearMovestatuses = function () {
|
||
for (var i in this.movestatuses) {
|
||
this.removeMovestatus(i);
|
||
}
|
||
this.movestatuses = {};
|
||
};
|
||
Pokemon.prototype.clearVolatiles = function () {
|
||
for (var i in this.volatiles) {
|
||
this.removeVolatile(i);
|
||
}
|
||
this.volatiles = {};
|
||
this.clearTurnstatuses();
|
||
this.clearMovestatuses();
|
||
};
|
||
Pokemon.prototype.markMove = function (moveName, pp, recursionSource) {
|
||
if (recursionSource === this.ident) return;
|
||
if (pp === undefined) pp = 1;
|
||
moveName = Tools.getMove(moveName).name;
|
||
if (moveName === 'Struggle') return;
|
||
if (this.volatiles.transform) {
|
||
// make sure there is no infinite recursion if both Pokemon are transformed into each other
|
||
if (!recursionSource) recursionSource = this.ident;
|
||
this.volatiles.transform[2].markMove(moveName, 0, recursionSource);
|
||
moveName = '*' + moveName;
|
||
}
|
||
for (var i = 0; i < this.moveTrack.length; i++) {
|
||
if (moveName === this.moveTrack[i][0]) {
|
||
this.moveTrack[i][1] += pp;
|
||
return;
|
||
}
|
||
}
|
||
this.moveTrack.push([moveName, pp]);
|
||
};
|
||
Pokemon.prototype.markAbility = function (ability, isNotBase) {
|
||
ability = Tools.getAbility(ability).name;
|
||
this.ability = ability;
|
||
if (!this.baseAbility && !isNotBase) {
|
||
this.baseAbility = ability;
|
||
}
|
||
};
|
||
Pokemon.prototype.htmlName = function () {
|
||
return '<span class="battle-nickname' + (this.side.n === 0 ? '' : '-foe') + '" title="' + this.species + '">' + Tools.escapeHTML(this.name) + '</span>';
|
||
};
|
||
Pokemon.prototype.getName = function (shortName) {
|
||
if (this.side.n === 0) {
|
||
return this.htmlName();
|
||
} else {
|
||
return (shortName ? "Opposing " : "The opposing ") + this.htmlName();
|
||
}
|
||
};
|
||
Pokemon.prototype.getLowerName = function (shortName) {
|
||
if (this.side.n === 0) {
|
||
return this.htmlName();
|
||
} else {
|
||
return (shortName ? "opposing " : "the opposing ") + this.htmlName();
|
||
}
|
||
};
|
||
Pokemon.prototype.getTitle = function () {
|
||
var titlestring = '(' + this.ability + ') ';
|
||
|
||
for (var i = 0; i < this.moves.length; i++) {
|
||
if (i != 0) titlestring += ' / ';
|
||
titlestring += Tools.getMove(this.moves[i]).name;
|
||
}
|
||
return titlestring;
|
||
};
|
||
Pokemon.prototype.getFullName = function (plaintext) {
|
||
var name = this.side && this.side.n && (this.side.battle.ignoreOpponent || this.side.battle.ignoreNicks) ? this.species : Tools.escapeHTML(this.name);
|
||
if (name !== this.species) {
|
||
if (plaintext) {
|
||
name += ' (' + this.species + ')';
|
||
} else {
|
||
name = '<span class="battle-nickname' + (this.side && this.side.n === 0 ? '' : '-foe') + '" title="' + this.species + '">' + name + ' <small>(' + this.species + ')</small>' + '</span>';
|
||
}
|
||
}
|
||
if (plaintext) {
|
||
if (this === this.side.active[0]) {
|
||
name += ' (active)';
|
||
} else if (this.fainted) {
|
||
name += ' (fainted)';
|
||
} else {
|
||
var statustext = '';
|
||
if (this.hp !== this.maxhp) {
|
||
statustext += this.hpDisplay();
|
||
}
|
||
if (this.status) {
|
||
if (statustext) statustext += '|';
|
||
statustext += this.status;
|
||
}
|
||
if (statustext) {
|
||
name += ' (' + statustext + ')';
|
||
}
|
||
}
|
||
}
|
||
return name;
|
||
};
|
||
Pokemon.prototype.getBoost = function (boostStat) {
|
||
var boostStatTable = {
|
||
atk: 'Atk',
|
||
def: 'Def',
|
||
spa: 'SpA',
|
||
spd: 'SpD',
|
||
spe: 'Spe',
|
||
accuracy: 'Accuracy',
|
||
evasion: 'Evasion',
|
||
spc: 'Spc'
|
||
};
|
||
if (!this.boosts[boostStat]) {
|
||
return '1× ' + boostStatTable[boostStat];
|
||
}
|
||
if (this.boosts[boostStat] > 6) this.boosts[boostStat] = 6;
|
||
if (this.boosts[boostStat] < -6) this.boosts[boostStat] = -6;
|
||
if (boostStat === 'accuracy' || boostStat === 'evasion') {
|
||
if (this.boosts[boostStat] > 0) {
|
||
var goodBoostTable = ['1×', '1.33×', '1.67×', '2×', '2.33×', '2.67×', '3×'];
|
||
//var goodBoostTable = ['Normal', '+1', '+2', '+3', '+4', '+5', '+6'];
|
||
return '' + goodBoostTable[this.boosts[boostStat]] + ' ' + boostStatTable[boostStat];
|
||
}
|
||
var badBoostTable = ['1×', '0.75×', '0.6×', '0.5×', '0.43×', '0.38×', '0.33×'];
|
||
//var badBoostTable = ['Normal', '−1', '−2', '−3', '−4', '−5', '−6'];
|
||
return '' + badBoostTable[-this.boosts[boostStat]] + ' ' + boostStatTable[boostStat];
|
||
}
|
||
if (this.boosts[boostStat] > 0) {
|
||
var goodBoostTable = ['1×', '1.5×', '2×', '2.5×', '3×', '3.5×', '4×'];
|
||
//var goodBoostTable = ['Normal', '+1', '+2', '+3', '+4', '+5', '+6'];
|
||
return '' + goodBoostTable[this.boosts[boostStat]] + ' ' + boostStatTable[boostStat];
|
||
}
|
||
var badBoostTable = ['1×', '0.67×', '0.5×', '0.4×', '0.33×', '0.29×', '0.25×'];
|
||
//var badBoostTable = ['Normal', '−1', '−2', '−3', '−4', '−5', '−6'];
|
||
return '' + badBoostTable[-this.boosts[boostStat]] + ' ' + boostStatTable[boostStat];
|
||
};
|
||
Pokemon.prototype.getBoostType = function (boostStat) {
|
||
if (!this.boosts[boostStat]) return 'neutral';
|
||
if (this.boosts[boostStat] > 0) return 'good';
|
||
return 'bad';
|
||
};
|
||
Pokemon.prototype.clearVolatile = function () {
|
||
this.ability = this.baseAbility;
|
||
this.atk = this.atkStat;
|
||
this.def = this.defStat;
|
||
this.spa = this.spaStat;
|
||
this.spd = this.spdStat;
|
||
this.spe = this.speStat;
|
||
this.boosts = {};
|
||
this.clearVolatiles();
|
||
for (var i = 0; i < this.moveTrack.length; i++) {
|
||
if (this.moveTrack[i][0].charAt(0) === '*') {
|
||
this.moveTrack.splice(i, 1);
|
||
i--;
|
||
}
|
||
}
|
||
//this.lastmove = '';
|
||
this.statusStage = 0;
|
||
};
|
||
Pokemon.prototype.copyVolatileFrom = function (pokemon, copyAll) {
|
||
this.boosts = pokemon.boosts;
|
||
this.volatiles = pokemon.volatiles;
|
||
//this.lastmove = pokemon.lastmove; // I think
|
||
if (!copyAll) {
|
||
this.removeVolatile('airballoon');
|
||
this.removeVolatile('attract');
|
||
this.removeVolatile('autotomize');
|
||
this.removeVolatile('disable');
|
||
this.removeVolatile('encore');
|
||
this.removeVolatile('foresight');
|
||
this.removeVolatile('imprison');
|
||
this.removeVolatile('mimic');
|
||
this.removeVolatile('miracleeye');
|
||
this.removeVolatile('nightmare');
|
||
this.removeVolatile('smackdown');
|
||
this.removeVolatile('stockpile1');
|
||
this.removeVolatile('stockpile2');
|
||
this.removeVolatile('stockpile3');
|
||
this.removeVolatile('torment');
|
||
this.removeVolatile('typeadd');
|
||
this.removeVolatile('typechange');
|
||
this.removeVolatile('yawn');
|
||
}
|
||
this.removeVolatile('transform');
|
||
this.removeVolatile('formechange');
|
||
|
||
pokemon.atk = pokemon.atkStat;
|
||
pokemon.def = pokemon.defStat;
|
||
pokemon.spa = pokemon.spaStat;
|
||
pokemon.spd = pokemon.spdStat;
|
||
pokemon.spe = pokemon.speStat;
|
||
pokemon.boosts = {};
|
||
pokemon.volatiles = {};
|
||
pokemon.sprite.removeTransform();
|
||
pokemon.statusStage = 0;
|
||
};
|
||
Pokemon.prototype.copyTypesFrom = function (pokemon) {
|
||
this.addVolatile('typechange');
|
||
if (pokemon.volatiles.typechange) {
|
||
this.volatiles.typechange[2] = pokemon.volatiles.typechange[2];
|
||
} else if (pokemon.volatiles.formechange) {
|
||
var template = Tools.getTemplate(pokemon.volatiles.formechange[2]);
|
||
this.volatiles.typechange[2] = template.types ? template.types.join('/') : '';
|
||
} else {
|
||
this.volatiles.typechange[2] = (
|
||
window.BattleTeambuilderTable &&
|
||
window.BattleTeambuilderTable['gen' + this.side.battle.gen] &&
|
||
window.BattleTeambuilderTable['gen' + this.side.battle.gen].overrideType[toId(pokemon.species)]
|
||
) || (pokemon.types ? pokemon.types.join('/') : '');
|
||
}
|
||
if (pokemon.volatiles.typeadd) {
|
||
this.addVolatile('typeadd');
|
||
this.volatiles.typeadd[2] = pokemon.volatiles.typeadd[2];
|
||
} else {
|
||
this.removeVolatile('typeadd');
|
||
}
|
||
};
|
||
Pokemon.prototype.reset = function () {
|
||
this.clearVolatile();
|
||
this.hp = this.maxhp;
|
||
this.zerohp = false;
|
||
this.fainted = false;
|
||
this.needsReplace = (this.details.indexOf('-*') >= 0);
|
||
this.status = '';
|
||
this.moveTrack = [];
|
||
this.name = this.name || this.species;
|
||
};
|
||
// This function is used for two things:
|
||
// 1) The percentage to display beside the HP bar.
|
||
// 2) The width to draw an HP bar.
|
||
//
|
||
// This function is NOT used in the calculation of any other displayed
|
||
// percentages or ranges, which have their own, more complex, formulae.
|
||
Pokemon.prototype.hpWidth = function (maxWidth) {
|
||
if (this.fainted || this.zerohp) return 0;
|
||
|
||
// special case for low health...
|
||
if (this.hp == 1 && this.maxhp > 10) return 1;
|
||
|
||
if (this.maxhp === 48) {
|
||
// Draw the health bar to the middle of the range.
|
||
// This affects the width of the visual health bar *only*; it
|
||
// does not affect the ranges displayed in any way.
|
||
var range = this.getPixelRange(this.hp, this.hpcolor);
|
||
var ratio = (range[0] + range[1]) / 2;
|
||
return Math.round(maxWidth * ratio) || 1;
|
||
}
|
||
var percentage = Math.ceil(100 * this.hp / this.maxhp);
|
||
if ((percentage === 100) && (this.hp < this.maxhp)) {
|
||
percentage = 99;
|
||
}
|
||
return percentage * maxWidth / 100;
|
||
};
|
||
Pokemon.prototype.hpDisplay = function (precision) {
|
||
if (precision === undefined) precision = 1;
|
||
if (this.maxhp === 100) return this.hp + '%';
|
||
if (this.maxhp !== 48) return (this.hp / this.maxhp * 100).toFixed(precision) + '%';
|
||
var range = this.getPixelRange(this.hp, this.hpcolor);
|
||
return this.getFormattedRange(range, precision, '–');
|
||
};
|
||
Pokemon.prototype.destroy = function () {
|
||
if (this.sprite) this.sprite.destroy();
|
||
delete this.side;
|
||
};
|
||
|
||
return Pokemon;
|
||
})();
|
||
|
||
var Sprite = (function () {
|
||
function Sprite(spriteData, x, y, z, battle, siden) {
|
||
this.battle = battle;
|
||
this.siden = siden;
|
||
this.forme = '';
|
||
this.elem = null;
|
||
this.cryurl = '';
|
||
var sp = null;
|
||
if (spriteData) {
|
||
sp = spriteData;
|
||
battle.spriteElems[siden].append('<img src="' + sp.url + '" style="display:none;position:absolute" />');
|
||
this.elem = battle.spriteElems[siden].children().last();
|
||
this.cryurl = spriteData.cryurl;
|
||
} else {
|
||
sp = {
|
||
w: 0,
|
||
h: 0,
|
||
url: ''
|
||
};
|
||
}
|
||
this.sp = sp;
|
||
this.subsp = null;
|
||
this.oldsp = null;
|
||
this.subElem = null;
|
||
this.iw = sp.w;
|
||
this.ih = sp.h;
|
||
this.w = 0;
|
||
this.h = 0;
|
||
this.x = x;
|
||
this.y = y;
|
||
this.z = z;
|
||
this.statbarOffset = 0;
|
||
var pos = battle.pos({
|
||
x: x,
|
||
y: y,
|
||
z: z
|
||
}, {
|
||
w: 0,
|
||
h: 96
|
||
});
|
||
this.top = parseInt(pos.top + 40, 10);
|
||
this.left = parseInt(pos.left, 10);
|
||
this.isBackSprite = !siden;
|
||
this.duringMove = false;
|
||
this.isMissedPokemon = false;
|
||
|
||
if (!spriteData) {
|
||
this.delay = function () {};
|
||
this.anim = function () {};
|
||
}
|
||
}
|
||
|
||
Sprite.prototype.behindx = function (offset) {
|
||
return this.x + (this.isBackSprite ? -1 : 1) * offset;
|
||
};
|
||
Sprite.prototype.behindy = function (offset) {
|
||
return this.y + (this.isBackSprite ? 1 : -1) * offset;
|
||
};
|
||
Sprite.prototype.leftof = function (offset) {
|
||
return this.x + (this.isBackSprite ? -1 : 1) * offset;
|
||
};
|
||
Sprite.prototype.behind = function (offset) {
|
||
return this.z + (this.isBackSprite ? -1 : 1) * offset;
|
||
};
|
||
Sprite.prototype.animTransform = function (species, isCustomAnim) {
|
||
if (!this.oldsp) this.oldsp = this.sp;
|
||
if (species.volatiles && species.volatiles.formechange) species = species.volatiles.formechange[2];
|
||
var sp = Tools.getSpriteData(species, this.isBackSprite ? 0 : 1, {
|
||
afd: this.battle.tier === "[Seasonal] Fools Festival",
|
||
gen: this.battle.gen
|
||
});
|
||
this.cryurl = sp.cryurl;
|
||
var doCry = false;
|
||
this.sp = sp;
|
||
var self = this;
|
||
var battle = this.battle;
|
||
if (battle.fastForward) {
|
||
this.elem.attr('src', sp.url);
|
||
this.elem.css(battle.pos({
|
||
x: self.x,
|
||
y: self.y,
|
||
z: self.z,
|
||
opacity: 1
|
||
}, sp));
|
||
return;
|
||
}
|
||
if (isCustomAnim) {
|
||
if (species.id === 'kyogreprimal') {
|
||
BattleOtherAnims.primalalpha.anim(battle, [self]);
|
||
doCry = true;
|
||
} else if (species.id === 'groudonprimal') {
|
||
BattleOtherAnims.primalomega.anim(battle, [self]);
|
||
doCry = true;
|
||
} else if (species.id === 'zygardecomplete') {
|
||
BattleOtherAnims.powerconstruct.anim(battle, [self]);
|
||
} else if (species.id === 'wishiwashischool' || species.id === 'greninjaash') {
|
||
BattleOtherAnims.schoolingin.anim(battle, [self]);
|
||
} else if (species.id === 'wishiwashi') {
|
||
BattleOtherAnims.schoolingout.anim(battle, [self]);
|
||
} else if (species.id === 'mimikyubusted') {
|
||
// standard animation
|
||
} else {
|
||
BattleOtherAnims.megaevo.anim(battle, [self]);
|
||
doCry = true;
|
||
}
|
||
}
|
||
this.elem.animate(this.battle.pos({
|
||
x: this.x,
|
||
y: this.y,
|
||
z: this.z,
|
||
yscale: 0,
|
||
xscale: 0,
|
||
opacity: 0.3
|
||
}, this.oldsp), 300, function () {
|
||
if (self.cryurl && doCry) {
|
||
//self.battle.logConsole('cry: ' + self.cryurl);
|
||
BattleSound.playEffect(self.cryurl);
|
||
}
|
||
self.elem.attr('src', sp.url);
|
||
self.elem.animate(battle.pos({
|
||
x: self.x,
|
||
y: self.y,
|
||
z: self.z,
|
||
opacity: 1
|
||
}, sp), 300);
|
||
});
|
||
this.battle.activityWait(500);
|
||
};
|
||
Sprite.prototype.destroy = function () {
|
||
if (this.elem) this.elem.remove();
|
||
if (this.subElem) this.subElem.remove();
|
||
delete this.battle;
|
||
};
|
||
Sprite.prototype.removeTransform = function (species) {
|
||
if (this.oldsp) {
|
||
var sp = this.oldsp;
|
||
this.cryurl = sp.cryurl;
|
||
this.sp = sp;
|
||
this.oldsp = null;
|
||
this.elem.attr('src', sp.url);
|
||
this.elem.css(this.battle.pos({
|
||
x: this.x,
|
||
y: this.y,
|
||
z: (this.subElem ? this.behind(30) : this.z),
|
||
opacity: (this.subElem ? .3 : 1)
|
||
}, sp));
|
||
}
|
||
};
|
||
Sprite.prototype.animSub = function (instant) {
|
||
var subsp = Tools.getSpriteData('substitute', this.siden, {
|
||
afd: this.battle.tier === "[Seasonal] Fools Festival",
|
||
gen: this.battle.gen
|
||
});
|
||
this.subsp = subsp;
|
||
this.iw = subsp.w;
|
||
this.ih = subsp.h;
|
||
this.battle.spriteElemsFront[this.siden].append('<img src="' + subsp.url + '" style="display:none;position:absolute"' + (subsp.pixelated ? ' class="pixelated"' : '') + ' />');
|
||
this.subElem = this.battle.spriteElemsFront[this.siden].children().last();
|
||
|
||
//temp//this.subElem.css({position: 'absolute', display: 'block'});
|
||
this.subElem.css({
|
||
position: 'absolute',
|
||
opacity: 0,
|
||
display: 'block'
|
||
});
|
||
if (instant || this.battle.fastForward) {
|
||
this.subElem.css(this.battle.pos({
|
||
x: this.x,
|
||
y: this.y,
|
||
z: this.z,
|
||
opacity: 1
|
||
}, subsp));
|
||
this.animReset();
|
||
return;
|
||
}
|
||
this.selfAnim({}, 500);
|
||
this.subElem.css(this.battle.pos({
|
||
x: this.x,
|
||
y: this.y + 50,
|
||
z: this.z,
|
||
opacity: 0
|
||
}, subsp));
|
||
this.subElem.animate(this.battle.pos({
|
||
x: this.x,
|
||
y: this.y,
|
||
z: this.z
|
||
}, subsp), 500);
|
||
this.battle.activityWait(this.subElem);
|
||
};
|
||
Sprite.prototype.animSubFade = function () {
|
||
if (!this.subElem) return;
|
||
if (this.battle.activityDelay) {
|
||
this.elem.delay(this.battle.activityDelay);
|
||
this.subElem.delay(this.battle.activityDelay);
|
||
}
|
||
if (this.battle.fastForward) {
|
||
this.subElem.remove();
|
||
} else {
|
||
this.subElem.animate(this.battle.pos({
|
||
x: this.x,
|
||
y: this.y - 50,
|
||
z: this.z,
|
||
opacity: 0
|
||
}, this.subsp), 500);
|
||
}
|
||
|
||
this.subElem = null;
|
||
this.selfAnim({}, 500);
|
||
this.iw = this.sp.w;
|
||
this.ih = this.sp.h;
|
||
if (!this.battle.fastForward) this.battle.activityWait(this.elem);
|
||
};
|
||
Sprite.prototype.beforeMove = function () {
|
||
if (this.subElem && !this.duringMove && !this.battle.fastForward) {
|
||
this.duringMove = true;
|
||
this.selfAnim({}, 300);
|
||
this.subElem.animate(this.battle.pos({
|
||
x: this.leftof(-50),
|
||
y: this.y,
|
||
z: this.z,
|
||
opacity: 0.5
|
||
}, this.subsp), 300);
|
||
if (this.battle.sides[this.isBackSprite ? 1 : 0].active[0]) {
|
||
this.battle.sides[this.isBackSprite ? 1 : 0].active[0].sprite.delay(300);
|
||
}
|
||
this.battle.animationDelay = 500;
|
||
this.battle.activityWait(this.elem);
|
||
|
||
return true;
|
||
}
|
||
return false;
|
||
};
|
||
Sprite.prototype.afterMove = function () {
|
||
if (this.subElem && this.duringMove && !this.battle.fastForward) {
|
||
this.subElem.delay(300);
|
||
this.duringMove = false;
|
||
var self = this;
|
||
this.elem.add(this.subElem).promise().done(function () {
|
||
if (!self.subElem || !self.elem) return;
|
||
self.selfAnim({}, 300);
|
||
self.subElem.animate(self.battle.pos({
|
||
x: self.x,
|
||
y: self.y,
|
||
z: self.z,
|
||
opacity: 1
|
||
}, self.subsp), 300);
|
||
});
|
||
return true;
|
||
}
|
||
this.duringMove = false;
|
||
return false;
|
||
};
|
||
Sprite.prototype.removeSub = function () {
|
||
if (this.subElem) {
|
||
if (this.battle.fastForward) {
|
||
this.subElem.remove();
|
||
} else {
|
||
var temp = this.subElem;
|
||
this.subElem.animate({
|
||
opacity: 0
|
||
}, function () {
|
||
temp.remove();
|
||
});
|
||
}
|
||
this.subElem = null;
|
||
}
|
||
};
|
||
Sprite.prototype.animReset = function () {
|
||
if (this.subElem) {
|
||
this.elem.stop(true, false);
|
||
this.subElem.stop(true, false);
|
||
this.elem.css(this.battle.pos({
|
||
x: this.x,
|
||
y: this.y,
|
||
z: this.behind(30),
|
||
opacity: .3
|
||
}, this.sp));
|
||
this.subElem.css(this.battle.pos({
|
||
x: this.x,
|
||
y: this.y,
|
||
z: this.z
|
||
}, this.subsp));
|
||
} else {
|
||
this.elem.stop(true, false);
|
||
this.elem.css(this.battle.pos({
|
||
x: this.x,
|
||
y: this.y,
|
||
z: this.z
|
||
}, this.sp));
|
||
}
|
||
};
|
||
Sprite.prototype.animSummon = function (slot, instant) {
|
||
if (!Tools.prefs('nopastgens') && this.battle.gen <= 4 && this.battle.gameType === 'doubles') {
|
||
this.x = (slot - 0.52) * (this.isBackSprite ? -1 : 1) * -55;
|
||
this.y = (this.isBackSprite ? -1 : 1) + 1;
|
||
this.statbarOffset = 0;
|
||
if (!this.isBackSprite) this.statbarOffset = 30 * slot;
|
||
if (this.isBackSprite) this.statbarOffset = -28 * slot;
|
||
} else {
|
||
this.x = slot * (this.isBackSprite ? -1 : 1) * -50;
|
||
this.y = slot * (this.isBackSprite ? -1 : 1) * 10;
|
||
this.statbarOffset = 0;
|
||
if (!this.isBackSprite) this.statbarOffset = 17 * slot;
|
||
if (this.isBackSprite) this.statbarOffset = -7 * slot;
|
||
}
|
||
|
||
// make sure element is in the right z-order
|
||
if (!slot && this.isBackSprite || slot && !this.isBackSprite) {
|
||
this.elem.prependTo(this.elem.parent());
|
||
} else {
|
||
this.elem.appendTo(this.elem.parent());
|
||
}
|
||
|
||
var pos = this.battle.pos(this, {
|
||
w: 0,
|
||
h: 96
|
||
});
|
||
this.top = parseInt(pos.top + 40, 10);
|
||
this.left = parseInt(pos.left, 10);
|
||
|
||
this.anim();
|
||
this.w = this.sp.w;
|
||
this.h = this.sp.h;
|
||
this.elem.css({
|
||
// 'z-index': (this.isBackSprite ? 1+slot : 4-slot),
|
||
position: 'absolute',
|
||
display: 'block'
|
||
});
|
||
if (this.battle.fastForward || instant) {
|
||
this.elem.css(this.battle.pos({
|
||
opacity: 1,
|
||
x: this.x,
|
||
y: this.y,
|
||
z: this.z
|
||
}, this.sp));
|
||
return;
|
||
}
|
||
if (this.cryurl) {
|
||
//this.battle.logConsole('cry: ' + this.cryurl);
|
||
BattleSound.playEffect(this.cryurl);
|
||
}
|
||
this.elem.css(this.battle.pos({
|
||
x: this.x,
|
||
y: this.y - 10,
|
||
z: this.z,
|
||
scale: 0,
|
||
opacity: 0
|
||
}, this.sp));
|
||
this.battle.showEffect('pokeball', {
|
||
opacity: 0,
|
||
x: this.x,
|
||
y: this.y + 30,
|
||
z: this.behind(50),
|
||
scale: .7
|
||
}, {
|
||
opacity: 1,
|
||
x: this.x,
|
||
y: this.y - 10,
|
||
z: this.z,
|
||
time: 300
|
||
}, 'ballistic2', 'fade');
|
||
this.elem.delay(300).animate(this.battle.pos({
|
||
x: this.x,
|
||
y: this.y + 30,
|
||
z: this.z
|
||
}, this.sp), 400).animate(this.battle.posT({
|
||
x: this.x,
|
||
y: this.y,
|
||
z: this.z
|
||
}, this.sp, 'accel'), 300);
|
||
this.battle.activityWait(this.elem);
|
||
if (!this.battle.fastForward && this.sp.shiny) BattleOtherAnims.shiny.anim(this.battle, [this]);
|
||
};
|
||
Sprite.prototype.animDragIn = function (slot) {
|
||
if (this.battle.fastForward) return this.animSummon(slot, true);
|
||
|
||
if (!Tools.prefs('nopastgens') && this.battle.gen <= 4 && this.battle.gameType === 'doubles') {
|
||
this.x = (slot - 0.52) * (this.isBackSprite ? -1 : 1) * -55;
|
||
this.y = (this.isBackSprite ? -1 : 1) + 1;
|
||
this.statbarOffset = 0;
|
||
if (!this.isBackSprite) this.statbarOffset = 30 * slot;
|
||
if (this.isBackSprite) this.statbarOffset = -28 * slot;
|
||
} else {
|
||
this.x = slot * (this.isBackSprite ? -1 : 1) * -50;
|
||
this.y = slot * (this.isBackSprite ? -1 : 1) * 10;
|
||
this.statbarOffset = 0;
|
||
if (!this.isBackSprite) this.statbarOffset = 17 * slot;
|
||
if (this.isBackSprite) this.statbarOffset = -7 * slot;
|
||
}
|
||
|
||
// make sure element is in the right z-order
|
||
if (!slot && this.isBackSprite || slot && !this.isBackSprite) {
|
||
this.elem.prependTo(this.elem.parent());
|
||
} else {
|
||
this.elem.appendTo(this.elem.parent());
|
||
}
|
||
|
||
var pos = this.battle.pos(this, {
|
||
w: 0,
|
||
h: 96
|
||
});
|
||
this.top = parseInt(pos.top + 40, 10);
|
||
this.left = parseInt(pos.left, 10);
|
||
|
||
this.anim();
|
||
this.elem.css({
|
||
// 'z-index': (this.isBackSprite ? 1+slot : 4-slot),
|
||
position: 'absolute',
|
||
opacity: 0,
|
||
display: 'block'
|
||
});
|
||
this.elem.css(this.battle.pos({
|
||
x: this.leftof(-50),
|
||
y: this.y,
|
||
z: this.z,
|
||
opacity: 0
|
||
}, this.sp));
|
||
this.elem.delay(300).animate(this.battle.posT({
|
||
x: this.x,
|
||
y: this.y,
|
||
z: this.z
|
||
}, this.sp, 'decel'), 400);
|
||
if (!this.battle.fastForward && this.sp.shiny) BattleOtherAnims.shiny.anim(this.battle, [this]);
|
||
this.w = this.sp.w;
|
||
this.h = this.sp.h;
|
||
this.battle.activityWait(this.elem);
|
||
this.battle.animationDelay = 700;
|
||
};
|
||
Sprite.prototype.animDragOut = function () {
|
||
this.removeSub();
|
||
if (this.battle.fastForward) return this.animUnsummon(true);
|
||
this.elem.animate(this.battle.posT({
|
||
x: this.leftof(50),
|
||
y: this.y,
|
||
z: this.z,
|
||
opacity: 0
|
||
}, this.sp, 'accel'), 400);
|
||
};
|
||
Sprite.prototype.animUnsummon = function (instant) {
|
||
this.removeSub();
|
||
if (this.battle.fastForward || instant) {
|
||
this.elem.css('display', 'none');
|
||
return;
|
||
}
|
||
this.anim({
|
||
x: this.x,
|
||
y: this.y - 40,
|
||
z: this.z,
|
||
scale: 0,
|
||
opacity: 0,
|
||
time: 400
|
||
});
|
||
this.battle.showEffect('pokeball', {
|
||
opacity: 1,
|
||
x: this.x,
|
||
y: this.y - 40,
|
||
z: this.z,
|
||
scale: .7,
|
||
time: 300
|
||
}, {
|
||
opacity: 0,
|
||
x: this.x,
|
||
y: this.y,
|
||
z: this.behind(50),
|
||
time: 700
|
||
}, 'ballistic2');
|
||
this.battle.activityWait(this.elem);
|
||
};
|
||
Sprite.prototype.animFaint = function () {
|
||
this.removeSub();
|
||
if (this.battle.fastForward) {
|
||
this.elem.remove();
|
||
this.elem = null;
|
||
return;
|
||
}
|
||
if (this.cryurl) {
|
||
//this.battle.logConsole('cry: ' + this.cryurl);
|
||
BattleSound.playEffect(this.cryurl);
|
||
}
|
||
this.anim({
|
||
y: this.y - 80,
|
||
opacity: 0
|
||
}, 'accel');
|
||
this.battle.activityWait(this.elem);
|
||
var self = this;
|
||
this.elem.promise().done(function () {
|
||
self.elem.remove();
|
||
self.elem = null;
|
||
});
|
||
};
|
||
Sprite.prototype.delay = function (time) {
|
||
this.elem.delay(time);
|
||
if (this.subElem) {
|
||
this.subElem.delay(time);
|
||
}
|
||
return this;
|
||
};
|
||
Sprite.prototype.selfAnim = function (end, transition) {
|
||
if (!end) return;
|
||
end = $.extend({
|
||
x: this.x,
|
||
y: this.y,
|
||
z: this.z,
|
||
scale: 1,
|
||
opacity: 1,
|
||
time: 500
|
||
}, end);
|
||
if (this.subElem && !this.duringMove) {
|
||
end.z += (this.isBackSprite ? -1 : 1) * 30;
|
||
end.opacity *= .3;
|
||
}
|
||
if (this.battle.fastForward) {
|
||
this.elem.css(this.battle.pos(end, this.sp));
|
||
return;
|
||
}
|
||
this.elem.animate(this.battle.posT(end, this.sp, transition, this), end.time);
|
||
};
|
||
Sprite.prototype.anim = function (end, transition) {
|
||
if (!end) return;
|
||
end = $.extend({
|
||
x: this.x,
|
||
y: this.y,
|
||
z: this.z,
|
||
scale: 1,
|
||
opacity: 1,
|
||
time: 500
|
||
}, end);
|
||
if (this.subElem && !this.duringMove) {
|
||
this.subElem.animate(this.battle.posT(end, this.subsp, transition, this), end.time);
|
||
} else {
|
||
this.elem.animate(this.battle.posT(end, this.sp, transition, this), end.time);
|
||
}
|
||
};
|
||
|
||
return Sprite;
|
||
})();
|
||
|
||
var Side = (function () {
|
||
function Side(battle, n) {
|
||
this.battle = battle;
|
||
this.name = '';
|
||
this.id = '';
|
||
this.initialized = false;
|
||
this.n = n;
|
||
this.foe = null;
|
||
this.spriteid = 262;
|
||
this.totalPokemon = 6;
|
||
|
||
if (n == 0) {
|
||
this.x = 0;
|
||
this.y = 0;
|
||
this.z = 0;
|
||
} else {
|
||
this.x = 0;
|
||
this.y = 0;
|
||
this.z = 200;
|
||
}
|
||
this.missedPokemon = {
|
||
sprite: new Sprite(null, this.leftof(-100), this.y, this.z, this.battle, this.n)
|
||
};
|
||
this.missedPokemon.sprite.isMissedPokemon = true;
|
||
|
||
this.sideConditions = {};
|
||
this.wisher = null;
|
||
|
||
this.active = [null];
|
||
this.lastPokemon = null;
|
||
this.pokemon = [];
|
||
}
|
||
|
||
Side.prototype.rollSprites = function () {
|
||
var sprites = [1, 2, 101, 102, 169, 170];
|
||
this.spriteid = sprites[Math.floor(Math.random() * sprites.length)];
|
||
};
|
||
|
||
Side.prototype.behindx = function (offset) {
|
||
return this.x + (!this.n ? -1 : 1) * offset;
|
||
};
|
||
Side.prototype.behindy = function (offset) {
|
||
return this.y + (!this.n ? 1 : -1) * offset;
|
||
};
|
||
Side.prototype.leftof = function (offset) {
|
||
return (!this.n ? -1 : 1) * offset;
|
||
};
|
||
Side.prototype.behind = function (offset) {
|
||
return this.z + (!this.n ? -1 : 1) * offset;
|
||
};
|
||
|
||
Side.prototype.reset = function () {
|
||
this.pokemon = [];
|
||
this.updateSprites();
|
||
this.sideConditions = {};
|
||
};
|
||
Side.prototype.updateSprites = function () {
|
||
this.z = (this.n ? 200 : 0);
|
||
this.missedPokemon.sprite.destroy();
|
||
this.missedPokemon = {
|
||
sprite: new Sprite(null, this.leftof(-100), this.y, this.z, this.battle, this.n)
|
||
};
|
||
this.missedPokemon.sprite.isMissedPokemon = true;
|
||
for (var i = 0; i < this.pokemon.length; i++) {
|
||
var poke = this.pokemon[i];
|
||
poke.sprite.destroy();
|
||
poke.sprite = new Sprite(Tools.getSpriteData(poke, this.n, {
|
||
afd: this.battle.tier === "[Seasonal] Fools Festival",
|
||
gen: this.battle.gen
|
||
}), this.x, this.y, this.z, this.battle, this.n);
|
||
}
|
||
};
|
||
Side.prototype.setSprite = function (spriteid) {
|
||
this.spriteid = spriteid;
|
||
this.updateSidebar();
|
||
};
|
||
Side.prototype.setName = function (name, spriteid) {
|
||
if (name) this.name = (name || '');
|
||
this.id = toId(this.name);
|
||
if (spriteid) {
|
||
this.spriteid = spriteid;
|
||
} else {
|
||
this.rollSprites();
|
||
if (this.foe && this.spriteid === this.foe.spriteid) this.rollSprites();
|
||
}
|
||
this.initialized = true;
|
||
if (!name) {
|
||
this.initialized = false;
|
||
}
|
||
this.updateSidebar();
|
||
if (this.battle.stagnateCallback) this.battle.stagnateCallback(this.battle);
|
||
};
|
||
Side.prototype.getTeamName = function () {
|
||
if (this === this.battle.mySide) return "Your team";
|
||
return "The opposing team";
|
||
};
|
||
Side.prototype.getLowerTeamName = function () {
|
||
if (this === this.battle.mySide) return "your team";
|
||
return "the opposing team";
|
||
};
|
||
Side.prototype.updateSidebar = function () {
|
||
var pokemonhtml = '';
|
||
var noShow = this.battle.hardcoreMode && this.battle.gen < 7;
|
||
for (var i = 0; i < 6; i++) {
|
||
var poke = this.pokemon[i];
|
||
if (i >= this.totalPokemon) {
|
||
pokemonhtml += '<span class="picon" style="' + Tools.getPokemonIcon('pokeball-none') + '"></span>';
|
||
} else if (noShow && poke && poke.fainted) {
|
||
pokemonhtml += '<span class="picon" style="' + Tools.getPokemonIcon('pokeball-fainted') + '" title="Fainted"></span>';
|
||
} else if (noShow && poke && poke.status) {
|
||
pokemonhtml += '<span class="picon" style="' + Tools.getPokemonIcon('pokeball-statused') + '" title="Status"></span>';
|
||
} else if (noShow) {
|
||
pokemonhtml += '<span class="picon" style="' + Tools.getPokemonIcon('pokeball') + '" title="Non-statused"></span>';
|
||
} else if (!poke) {
|
||
pokemonhtml += '<span class="picon" style="' + Tools.getPokemonIcon('pokeball') + '" title="Not revealed"></span>';
|
||
} else if (!poke.ident && this.battle.teamPreviewCount && this.battle.teamPreviewCount < this.pokemon.length) {
|
||
pokemonhtml += '<span class="picon" style="' + Tools.getPokemonIcon(poke, !this.n) + ';opacity:0.6" title="' + poke.getFullName(true) + '"></span>';
|
||
} else {
|
||
pokemonhtml += '<span class="picon" style="' + Tools.getPokemonIcon(poke, !this.n) + '" title="' + poke.getFullName(true) + '"></span>';
|
||
}
|
||
if (i % 3 === 2) pokemonhtml += '</div><div class="teamicons">';
|
||
}
|
||
pokemonhtml = '<div class="teamicons">' + pokemonhtml + '</div>';
|
||
if (this.n === 1) {
|
||
if (this.initialized) {
|
||
this.battle.rightbarElem.html('<div class="trainer"><strong>' + Tools.escapeHTML(this.name) + '</strong><div class="trainersprite" style="background-image:url(' + Tools.resolveAvatar(this.spriteid) + ')"></div>' + pokemonhtml + '</div>').find('.trainer').css('opacity', 1);
|
||
} else {
|
||
this.battle.rightbarElem.find('.trainer').css('opacity', 0.4);
|
||
}
|
||
} else {
|
||
if (this.initialized) {
|
||
this.battle.leftbarElem.html('<div class="trainer"><strong>' + Tools.escapeHTML(this.name) + '</strong><div class="trainersprite" style="background-image:url(' + Tools.resolveAvatar(this.spriteid) + ')"></div>' + pokemonhtml + '</div>').find('.trainer').css('opacity', 1);
|
||
} else {
|
||
this.battle.leftbarElem.find('.trainer').css('opacity', 0.4);
|
||
}
|
||
}
|
||
};
|
||
Side.prototype.addSideCondition = function (effect) {
|
||
var elem, curelem;
|
||
var condition = effect.id;
|
||
if (this.sideConditions[condition]) {
|
||
if (condition === 'spikes' || condition === 'toxicspikes') {
|
||
this.sideConditions[condition][2]++;
|
||
if (condition === 'spikes' && this.sideConditions[condition][2] == 2) {
|
||
this.battle.spriteElemsFront[this.n].append('<img src="' + BattleEffects.caltrop.url + '" style="display:none;position:absolute" />');
|
||
curelem = this.battle.spriteElemsFront[this.n].children().last();
|
||
curelem.css(this.battle.pos({
|
||
display: 'block',
|
||
x: this.x + 50,
|
||
y: this.y - 40,
|
||
z: this.z,
|
||
scale: .3
|
||
}, BattleEffects.caltrop));
|
||
this.sideConditions['spikes'][1] = this.sideConditions['spikes'][1].add(curelem);
|
||
} else if (condition === 'spikes') {
|
||
this.battle.spriteElemsFront[this.n].append('<img src="' + BattleEffects.caltrop.url + '" style="display:none;position:absolute" />');
|
||
curelem = this.battle.spriteElemsFront[this.n].children().last();
|
||
curelem.css(this.battle.pos({
|
||
display: 'block',
|
||
x: this.x + 30,
|
||
y: this.y - 45,
|
||
z: this.z,
|
||
scale: .3
|
||
}, BattleEffects.caltrop));
|
||
this.sideConditions['spikes'][1] = this.sideConditions['spikes'][1].add(curelem);
|
||
} else if (condition === 'toxicspikes') {
|
||
this.battle.spriteElemsFront[this.n].append('<img src="' + BattleEffects.poisoncaltrop.url + '" style="display:none;position:absolute" />');
|
||
curelem = this.battle.spriteElemsFront[this.n].children().last();
|
||
curelem.css(this.battle.pos({
|
||
display: 'block',
|
||
x: this.x - 15,
|
||
y: this.y - 35,
|
||
z: this.z,
|
||
scale: .3
|
||
}, BattleEffects.poisoncaltrop));
|
||
this.sideConditions['toxicspikes'][1] = this.sideConditions['toxicspikes'][1].add(curelem);
|
||
}
|
||
}
|
||
return;
|
||
}
|
||
// Side conditions work as: [effectName, elem, levels, minDuration, maxDuration]
|
||
switch (condition) {
|
||
case 'auroraveil':
|
||
this.battle.spriteElemsFront[this.n].append('<div class="sidecondition-auroraveil" style="display:none;position:absolute" />');
|
||
curelem = this.battle.spriteElemsFront[this.n].children().last();
|
||
curelem.css(this.battle.pos({
|
||
display: 'block',
|
||
x: this.x,
|
||
y: this.y,
|
||
z: this.behind(-14),
|
||
xscale: 1,
|
||
yscale: 0,
|
||
opacity: .1
|
||
}, BattleEffects.none)).animate(this.battle.pos({
|
||
x: this.x,
|
||
y: this.y,
|
||
z: this.behind(-14),
|
||
xscale: 1,
|
||
yscale: .5,
|
||
opacity: .7
|
||
}, BattleEffects.none)).animate({
|
||
opacity: .3
|
||
}, 300);
|
||
elem = curelem;
|
||
this.sideConditions[condition] = [effect.name, elem, 1, 5, 8];
|
||
break;
|
||
case 'reflect':
|
||
this.battle.spriteElemsFront[this.n].append('<div class="sidecondition-reflect" style="display:none;position:absolute" />');
|
||
curelem = this.battle.spriteElemsFront[this.n].children().last();
|
||
curelem.css(this.battle.pos({
|
||
display: 'block',
|
||
x: this.x,
|
||
y: this.y,
|
||
z: this.behind(-17),
|
||
xscale: 1,
|
||
yscale: 0,
|
||
opacity: .1
|
||
}, BattleEffects.none)).animate(this.battle.pos({
|
||
x: this.x,
|
||
y: this.y,
|
||
z: this.behind(-17),
|
||
xscale: 1,
|
||
yscale: .5,
|
||
opacity: .7
|
||
}, BattleEffects.none)).animate({
|
||
opacity: .3
|
||
}, 300);
|
||
elem = curelem;
|
||
this.sideConditions[condition] = [effect.name, elem, 1, 5, this.battle.gen >= 4 ? 8 : 0];
|
||
break;
|
||
case 'safeguard':
|
||
this.battle.spriteElemsFront[this.n].append('<div class="sidecondition-safeguard" style="display:none;position:absolute" />');
|
||
curelem = this.battle.spriteElemsFront[this.n].children().last();
|
||
curelem.css(this.battle.pos({
|
||
display: 'block',
|
||
x: this.x,
|
||
y: this.y,
|
||
z: this.behind(-20),
|
||
xscale: 1,
|
||
yscale: 0,
|
||
opacity: .1
|
||
}, BattleEffects.none)).animate(this.battle.pos({
|
||
x: this.x,
|
||
y: this.y,
|
||
z: this.behind(-20),
|
||
xscale: 1,
|
||
yscale: .5,
|
||
opacity: .7
|
||
}, BattleEffects.none)).animate({
|
||
opacity: .2
|
||
}, 300);
|
||
elem = curelem;
|
||
this.sideConditions[condition] = [effect.name, elem, 1, 5, 0];
|
||
break;
|
||
case 'lightscreen':
|
||
this.battle.spriteElemsFront[this.n].append('<div class="sidecondition-lightscreen" style="display:none;position:absolute" />');
|
||
curelem = this.battle.spriteElemsFront[this.n].children().last();
|
||
curelem.css(this.battle.pos({
|
||
display: 'block',
|
||
x: this.x,
|
||
y: this.y,
|
||
z: this.behind(-23),
|
||
xscale: 1,
|
||
yscale: 0,
|
||
opacity: .1
|
||
}, BattleEffects.none)).animate(this.battle.pos({
|
||
x: this.x,
|
||
y: this.y,
|
||
z: this.behind(-23),
|
||
xscale: 1,
|
||
yscale: .5,
|
||
opacity: .7
|
||
}, BattleEffects.none)).animate({
|
||
opacity: .3
|
||
}, 300);
|
||
elem = curelem;
|
||
this.sideConditions[condition] = [effect.name, elem, 1, 5, this.battle.gen >= 4 ? 8 : 0];
|
||
break;
|
||
case 'mist':
|
||
this.battle.spriteElemsFront[this.n].append('<div class="sidecondition-mist" style="display:none;position:absolute" />');
|
||
curelem = this.battle.spriteElemsFront[this.n].children().last();
|
||
curelem.css(this.battle.pos({
|
||
display: 'block',
|
||
x: this.x,
|
||
y: this.y,
|
||
z: this.behind(-27),
|
||
xscale: 1,
|
||
yscale: 0,
|
||
opacity: .1
|
||
}, BattleEffects.none)).animate(this.battle.pos({
|
||
x: this.x,
|
||
y: this.y,
|
||
z: this.behind(-27),
|
||
xscale: 1,
|
||
yscale: .5,
|
||
opacity: .7
|
||
}, BattleEffects.none)).animate({
|
||
opacity: .2
|
||
}, 300);
|
||
elem = curelem;
|
||
this.sideConditions[condition] = [effect.name, elem, 1, 5, 0];
|
||
break;
|
||
case 'tailwind':
|
||
this.sideConditions[condition] = [effect.name, null, 1, this.battle.gen >= 5 ? 4 : 3, 0];
|
||
break;
|
||
case 'luckychant':
|
||
this.sideConditions[condition] = [effect.name, null, 1, 5, 0];
|
||
break;
|
||
case 'stealthrock':
|
||
this.battle.spriteElemsFront[this.n].append('<img src="' + BattleEffects.rock1.url + '" style="display:none;position:absolute" />');
|
||
curelem = this.battle.spriteElemsFront[this.n].children().last();
|
||
curelem.css(this.battle.pos({
|
||
display: 'block',
|
||
x: this.leftof(-40),
|
||
y: this.y - 10,
|
||
z: this.z,
|
||
opacity: .5,
|
||
scale: .2
|
||
}, BattleEffects.rock1));
|
||
elem = curelem;
|
||
|
||
this.battle.spriteElemsFront[this.n].append('<img src="' + BattleEffects.rock2.url + '" style="display:none;position:absolute" />');
|
||
curelem = this.battle.spriteElemsFront[this.n].children().last();
|
||
curelem.css(this.battle.pos({
|
||
display: 'block',
|
||
x: this.leftof(-20),
|
||
y: this.y - 40,
|
||
z: this.z,
|
||
opacity: .5,
|
||
scale: .2
|
||
}, BattleEffects.rock2));
|
||
elem = elem.add(curelem);
|
||
|
||
this.battle.spriteElemsFront[this.n].append('<img src="' + BattleEffects.rock1.url + '" style="display:none;position:absolute" />');
|
||
curelem = this.battle.spriteElemsFront[this.n].children().last();
|
||
curelem.css(this.battle.pos({
|
||
display: 'block',
|
||
x: this.leftof(30),
|
||
y: this.y - 20,
|
||
z: this.z,
|
||
opacity: .5,
|
||
scale: .2
|
||
}, BattleEffects.rock1));
|
||
elem = elem.add(curelem);
|
||
|
||
this.battle.spriteElemsFront[this.n].append('<img src="' + BattleEffects.rock2.url + '" style="display:none;position:absolute" />');
|
||
curelem = this.battle.spriteElemsFront[this.n].children().last();
|
||
curelem.css(this.battle.pos({
|
||
display: 'block',
|
||
x: this.leftof(10),
|
||
y: this.y - 30,
|
||
z: this.z,
|
||
opacity: .5,
|
||
scale: .2
|
||
}, BattleEffects.rock2));
|
||
elem = elem.add(curelem);
|
||
this.sideConditions[condition] = [effect.name, elem, 1, 0, 0];
|
||
break;
|
||
case 'spikes':
|
||
this.battle.spriteElemsFront[this.n].append('<img src="' + BattleEffects.caltrop.url + '" style="display:none;position:absolute" />');
|
||
curelem = this.battle.spriteElemsFront[this.n].children().last();
|
||
curelem.css(this.battle.pos({
|
||
display: 'block',
|
||
x: this.x - 25,
|
||
y: this.y - 40,
|
||
z: this.z,
|
||
scale: .3
|
||
}, BattleEffects.caltrop));
|
||
elem = curelem;
|
||
this.sideConditions[condition] = [effect.name, elem, 1, 0, 0];
|
||
break;
|
||
case 'toxicspikes':
|
||
this.battle.spriteElemsFront[this.n].append('<img src="' + BattleEffects.poisoncaltrop.url + '" style="display:none;position:absolute" />');
|
||
curelem = this.battle.spriteElemsFront[this.n].children().last();
|
||
curelem.css(this.battle.pos({
|
||
display: 'block',
|
||
x: this.x + 5,
|
||
y: this.y - 40,
|
||
z: this.z,
|
||
scale: .3
|
||
}, BattleEffects.poisoncaltrop));
|
||
elem = curelem;
|
||
this.sideConditions[condition] = [effect.name, elem, 1, 0, 0];
|
||
break;
|
||
case 'stickyweb':
|
||
this.battle.spriteElemsFront[this.n].append('<img src="' + BattleEffects.web.url + '" style="display:none;position:absolute" />');
|
||
curelem = this.battle.spriteElemsFront[this.n].children().last();
|
||
curelem.css(this.battle.pos({
|
||
display: 'block',
|
||
x: this.x + 15,
|
||
y: this.y - 35,
|
||
z: this.z,
|
||
opacity: 0.4,
|
||
scale: 0.7
|
||
}, BattleEffects.web));
|
||
elem = curelem;
|
||
this.sideConditions[condition] = [effect.name, elem, 1, 0, 0];
|
||
break;
|
||
default:
|
||
this.sideConditions[condition] = [effect.name, null, 1, 0, 0];
|
||
}
|
||
};
|
||
Side.prototype.removeSideCondition = function (condition) {
|
||
condition = toId(condition);
|
||
if (!this.sideConditions[condition]) return;
|
||
if (this.sideConditions[condition][1]) this.sideConditions[condition][1].remove();
|
||
delete this.sideConditions[condition];
|
||
};
|
||
Side.prototype.newPokemon = function (species, replaceSlot) {
|
||
var id;
|
||
var pokeobj;
|
||
if (species.species) {
|
||
pokeobj = species;
|
||
species = pokeobj.species;
|
||
id = pokeobj.id;
|
||
}
|
||
var poke = Tools.getTemplate(species);
|
||
poke = $.extend(new Pokemon(species, this), poke);
|
||
poke.atkStat = 10;
|
||
poke.defStat = 10;
|
||
poke.spaStat = 10;
|
||
poke.spdStat = 10;
|
||
poke.maxhp = 1000;
|
||
if (pokeobj) poke = $.extend(poke, pokeobj);
|
||
if (!poke.ability && poke.baseAbility) poke.ability = poke.baseAbility;
|
||
poke.id = id;
|
||
poke.reset();
|
||
poke.sprite = new Sprite(Tools.getSpriteData(poke, this.n, {
|
||
afd: this.battle.tier === "[Seasonal] Fools Festival",
|
||
gen: this.battle.gen
|
||
}), this.x, this.y, this.z, this.battle, this.n);
|
||
|
||
if (typeof replaceSlot !== 'undefined') {
|
||
this.pokemon[replaceSlot] = poke;
|
||
} else {
|
||
this.pokemon.push(poke);
|
||
}
|
||
if (this.pokemon.length == 7 || this.battle.speciesClause) {
|
||
// check for Illusion
|
||
var existingTable = {};
|
||
for (var i = 0; i < this.pokemon.length; i++) {
|
||
var poke1 = this.pokemon[i];
|
||
if (poke1.searchid in existingTable) {
|
||
var j = existingTable[poke1.searchid];
|
||
var poke2 = this.pokemon[j];
|
||
if (this.active.indexOf(poke1) >= 0) {
|
||
this.pokemon.splice(j, 1);
|
||
} else if (this.active.indexOf(poke2) >= 0) {
|
||
this.pokemon.splice(i, 1);
|
||
} else if (poke1.fainted && !poke2.fainted) {
|
||
this.pokemon.splice(j, 1);
|
||
} else {
|
||
this.pokemon.splice(i, 1);
|
||
}
|
||
break;
|
||
}
|
||
existingTable[poke1.searchid] = i;
|
||
}
|
||
}
|
||
this.updateSidebar();
|
||
|
||
return poke;
|
||
};
|
||
|
||
Side.prototype.getStatbarHTML = function (pokemon, inner) {
|
||
var buf = '';
|
||
if (!inner) buf += '<div class="statbar' + (this.n ? ' lstatbar' : ' rstatbar') + '">';
|
||
buf += '<strong>' + (this.n && (this.battle.ignoreOpponent || this.battle.ignoreNicks) ? pokemon.species : Tools.escapeHTML(pokemon.name));
|
||
var gender = pokemon.gender;
|
||
if (gender) gender = ' <img src="' + Tools.resourcePrefix + 'fx/gender-' + gender.toLowerCase() + '.png" alt="' + gender + '" />';
|
||
buf += gender + (pokemon.level === 100 ? '' : ' <small>L' + pokemon.level + '</small>');
|
||
|
||
var symbol = '';
|
||
if (pokemon.species.indexOf('-Mega') >= 0) symbol = 'mega';
|
||
else if (pokemon.species === 'Kyogre-Primal') symbol = 'alpha';
|
||
else if (pokemon.species === 'Groudon-Primal') symbol = 'omega';
|
||
if (symbol) buf += ' <img src="' + Tools.resourcePrefix + 'sprites/misc/' + symbol + '.png" alt="' + symbol + '" style="vertical-align:text-bottom;" />';
|
||
|
||
buf += '</strong><div class="hpbar"><div class="hptext"></div><div class="hptextborder"></div><div class="prevhp"><div class="hp"></div></div><div class="status"></div>';
|
||
if (!inner) buf += '</div>';
|
||
return buf;
|
||
};
|
||
Side.prototype.switchIn = function (pokemon, slot) {
|
||
if (slot === undefined) slot = pokemon.slot;
|
||
this.active[slot] = pokemon;
|
||
pokemon.slot = slot;
|
||
pokemon.clearVolatile();
|
||
pokemon.lastmove = '';
|
||
this.battle.lastmove = 'switch-in';
|
||
if (this.lastPokemon && (this.lastPokemon.lastmove === 'batonpass' || this.lastPokemon.lastmove === 'zbatonpass')) {
|
||
pokemon.copyVolatileFrom(this.lastPokemon);
|
||
}
|
||
|
||
if (pokemon.side.n === 0) {
|
||
this.battle.message('Go! ' + pokemon.getFullName() + '!');
|
||
} else {
|
||
this.battle.message('' + Tools.escapeHTML(pokemon.side.name) + ' sent out ' + pokemon.getFullName() + '!');
|
||
}
|
||
|
||
pokemon.sprite.animSummon(slot);
|
||
if (pokemon.hasVolatile('substitute')) {
|
||
pokemon.sprite.animSub();
|
||
}
|
||
if (pokemon.statbarElem) {
|
||
pokemon.statbarElem.remove();
|
||
}
|
||
this.battle.statElem.append(this.getStatbarHTML(pokemon));
|
||
pokemon.statbarElem = this.battle.statElem.children().last();
|
||
this.updateStatbar(pokemon, true);
|
||
pokemon.side.updateSidebar();
|
||
if (this.battle.fastForward) {
|
||
pokemon.statbarElem.css({
|
||
display: 'block',
|
||
left: pokemon.sprite.left - 80,
|
||
top: pokemon.sprite.top - 73 - pokemon.sprite.statbarOffset,
|
||
opacity: 1
|
||
});
|
||
if (this.battle.switchCallback) this.battle.switchCallback(this.battle, this);
|
||
return;
|
||
}
|
||
pokemon.statbarElem.css({
|
||
display: 'block',
|
||
left: pokemon.sprite.left - 80,
|
||
top: pokemon.sprite.top - 53 - pokemon.sprite.statbarOffset,
|
||
opacity: 0
|
||
});
|
||
pokemon.statbarElem.delay(300).animate({
|
||
top: pokemon.sprite.top - 73 - pokemon.sprite.statbarOffset,
|
||
opacity: 1
|
||
}, 400);
|
||
|
||
this.battle.dogarsCheck(pokemon);
|
||
|
||
if (this.battle.switchCallback) this.battle.switchCallback(this.battle, this);
|
||
};
|
||
Side.prototype.dragIn = function (pokemon, slot) {
|
||
if (slot === undefined) slot = pokemon.slot;
|
||
this.battle.message('' + pokemon.getFullName() + ' was dragged out!');
|
||
var oldpokemon = this.active[slot];
|
||
if (oldpokemon === pokemon) return;
|
||
this.lastPokemon = oldpokemon;
|
||
if (oldpokemon) oldpokemon.clearVolatile();
|
||
pokemon.clearVolatile();
|
||
pokemon.lastmove = '';
|
||
this.battle.lastmove = 'switch-in';
|
||
this.active[slot] = pokemon;
|
||
pokemon.slot = slot;
|
||
|
||
if (oldpokemon) {
|
||
oldpokemon.sprite.animDragOut();
|
||
}
|
||
pokemon.sprite.animDragIn(slot);
|
||
if (pokemon.statbarElem) {
|
||
pokemon.statbarElem.remove();
|
||
}
|
||
this.battle.statElem.append(this.getStatbarHTML(pokemon));
|
||
pokemon.statbarElem = this.battle.statElem.children().last();
|
||
this.updateStatbar(pokemon, true);
|
||
pokemon.side.updateSidebar();
|
||
if (this.battle.fastForward) {
|
||
if (oldpokemon) {
|
||
oldpokemon.statbarElem.remove();
|
||
oldpokemon.statbarElem = null;
|
||
}
|
||
pokemon.statbarElem.css({
|
||
display: 'block',
|
||
left: pokemon.sprite.left - 80,
|
||
top: pokemon.sprite.top - 73 - pokemon.sprite.statbarOffset,
|
||
opacity: 1
|
||
});
|
||
if (this.battle.dragCallback) this.battle.dragCallback(this.battle, this);
|
||
return;
|
||
}
|
||
if (this.n == 0) {
|
||
if (oldpokemon) {
|
||
oldpokemon.statbarElem.animate({
|
||
left: pokemon.sprite.left - 130,
|
||
opacity: 0
|
||
}, 400, function () {
|
||
oldpokemon.statbarElem.remove();
|
||
oldpokemon.statbarElem = null;
|
||
});
|
||
}
|
||
pokemon.statbarElem.css({
|
||
display: 'block',
|
||
left: pokemon.sprite.left - 30,
|
||
top: pokemon.sprite.top - 73 - pokemon.sprite.statbarOffset,
|
||
opacity: 0
|
||
});
|
||
pokemon.statbarElem.delay(300).animate({
|
||
left: pokemon.sprite.left - 80,
|
||
opacity: 1
|
||
}, 400);
|
||
} else {
|
||
if (oldpokemon) {
|
||
oldpokemon.statbarElem.animate({
|
||
left: pokemon.sprite.left - 30,
|
||
opacity: 0
|
||
}, 400, function () {
|
||
oldpokemon.statbarElem.remove();
|
||
oldpokemon.statbarElem = null;
|
||
});
|
||
}
|
||
pokemon.statbarElem.css({
|
||
display: 'block',
|
||
left: pokemon.sprite.left - 130,
|
||
top: pokemon.sprite.top - 73 - pokemon.sprite.statbarOffset,
|
||
opacity: 0
|
||
});
|
||
pokemon.statbarElem.delay(300).animate({
|
||
left: pokemon.sprite.left - 80,
|
||
opacity: 1
|
||
}, 400);
|
||
}
|
||
|
||
this.battle.dogarsCheck(pokemon);
|
||
|
||
if (this.battle.dragCallback) this.battle.dragCallback(this.battle, this);
|
||
};
|
||
Side.prototype.replace = function (pokemon, slot) {
|
||
if (slot === undefined) slot = pokemon.slot;
|
||
var oldpokemon = this.active[slot];
|
||
if (pokemon === oldpokemon) return;
|
||
this.lastPokemon = oldpokemon;
|
||
pokemon.clearVolatile();
|
||
if (oldpokemon) {
|
||
pokemon.lastmove = oldpokemon.lastmove;
|
||
pokemon.hp = oldpokemon.hp;
|
||
pokemon.maxhp = oldpokemon.maxhp;
|
||
pokemon.status = oldpokemon.status;
|
||
pokemon.copyVolatileFrom(oldpokemon, true);
|
||
}
|
||
this.active[slot] = pokemon;
|
||
pokemon.slot = slot;
|
||
|
||
if (oldpokemon) {
|
||
oldpokemon.sprite.animUnsummon(true);
|
||
}
|
||
pokemon.sprite.animSummon(slot, true);
|
||
if (pokemon.hasVolatile('substitute')) {
|
||
pokemon.sprite.animSub(true);
|
||
}
|
||
if (oldpokemon) {
|
||
oldpokemon.statbarElem.remove();
|
||
oldpokemon.statbarElem = null;
|
||
}
|
||
if (pokemon.statbarElem) {
|
||
pokemon.statbarElem.remove();
|
||
}
|
||
this.battle.statElem.append(this.getStatbarHTML(pokemon));
|
||
pokemon.statbarElem = this.battle.statElem.children().last();
|
||
this.updateStatbar(pokemon, true);
|
||
pokemon.statbarElem.css({
|
||
display: 'block',
|
||
left: pokemon.sprite.left - 80,
|
||
top: pokemon.sprite.top - 73 - pokemon.sprite.statbarOffset,
|
||
opacity: 1
|
||
});
|
||
// not sure if we want a different callback
|
||
if (this.battle.dragCallback) this.battle.dragCallback(this.battle, this);
|
||
};
|
||
Side.prototype.switchOut = function (pokemon, slot) {
|
||
if (slot === undefined) slot = pokemon.slot;
|
||
if (pokemon.lastmove !== 'batonpass' && pokemon.lastmove !== 'zbatonpass') {
|
||
pokemon.clearVolatile();
|
||
} else {
|
||
pokemon.removeVolatile('transform');
|
||
pokemon.removeVolatile('formechange');
|
||
}
|
||
if (pokemon.lastmove === 'uturn' || pokemon.lastmove === 'voltswitch') {
|
||
this.battle.message('' + pokemon.getName() + ' went back to ' + Tools.escapeHTML(pokemon.side.name) + '!');
|
||
} else if (pokemon.lastmove !== 'batonpass' && pokemon.lastmove !== 'zbatonpass') {
|
||
if (pokemon.side.n === 0) {
|
||
this.battle.message('' + pokemon.getName() + ', come back!');
|
||
} else {
|
||
this.battle.message('' + Tools.escapeHTML(pokemon.side.name) + ' withdrew ' + pokemon.getFullName() + '!');
|
||
}
|
||
}
|
||
this.lastPokemon = pokemon;
|
||
this.active[slot] = null;
|
||
|
||
this.updateStatbar(pokemon, true);
|
||
pokemon.sprite.animUnsummon();
|
||
if (this.battle.fastForward) {
|
||
pokemon.statbarElem.remove();
|
||
pokemon.statbarElem = null;
|
||
return;
|
||
}
|
||
pokemon.statbarElem.animate({
|
||
top: pokemon.sprite.top - 43 - pokemon.sprite.statbarOffset,
|
||
opacity: 0
|
||
}, 300, function () {
|
||
pokemon.statbarElem.remove();
|
||
pokemon.statbarElem = null;
|
||
});
|
||
//pokemon.statbarElem.done(pokemon.statbarElem.remove());
|
||
};
|
||
Side.prototype.swapTo = function (pokemon, slot, kwargs) {
|
||
slot = Number(slot);
|
||
if (pokemon.slot === slot) return;
|
||
var target = this.active[slot];
|
||
|
||
if (!kwargs.silent) {
|
||
var fromeffect = Tools.getEffect(kwargs.from);
|
||
switch (fromeffect.id) {
|
||
case 'allyswitch':
|
||
this.battle.message('<small>' + pokemon.getName() + ' and ' + target.getLowerName() + ' switched places.</small>');
|
||
break;
|
||
default:
|
||
this.battle.message('<small>' + pokemon.getName() + ' moved to the center!</small>');
|
||
break;
|
||
}
|
||
}
|
||
|
||
var oslot = pokemon.slot;
|
||
|
||
pokemon.slot = slot;
|
||
if (target) target.slot = oslot;
|
||
|
||
this.active[slot] = pokemon;
|
||
this.active[oslot] = target;
|
||
|
||
if (pokemon.hasVolatile('substitute')) pokemon.sprite.animSubFade();
|
||
if (target && target.hasVolatile('substitute')) target.sprite.animSubFade();
|
||
|
||
pokemon.sprite.animUnsummon(true);
|
||
if (target) target.sprite.animUnsummon(true);
|
||
|
||
pokemon.sprite.animSummon(slot, true);
|
||
if (target) target.sprite.animSummon(oslot, true);
|
||
|
||
if (pokemon.hasVolatile('substitute')) pokemon.sprite.animSub();
|
||
if (target && target.hasVolatile('substitute')) target.sprite.animSub();
|
||
|
||
if (pokemon.statbarElem) {
|
||
pokemon.statbarElem.remove();
|
||
}
|
||
if (target && target.statbarElem) {
|
||
target.statbarElem.remove();
|
||
}
|
||
|
||
this.battle.statElem.append(this.getStatbarHTML(pokemon));
|
||
pokemon.statbarElem = this.battle.statElem.children().last();
|
||
if (target) {
|
||
this.battle.statElem.append(this.getStatbarHTML(target));
|
||
target.statbarElem = this.battle.statElem.children().last();
|
||
}
|
||
|
||
this.updateStatbar(pokemon, true);
|
||
if (target) this.updateStatbar(target, true);
|
||
|
||
pokemon.statbarElem.css({
|
||
display: 'block',
|
||
left: pokemon.sprite.left - 80,
|
||
top: pokemon.sprite.top - 73 - pokemon.sprite.statbarOffset,
|
||
opacity: 1
|
||
});
|
||
if (target) target.statbarElem.css({
|
||
display: 'block',
|
||
left: target.sprite.left - 80,
|
||
top: target.sprite.top - 73 - target.sprite.statbarOffset,
|
||
opacity: 1
|
||
});
|
||
};
|
||
Side.prototype.swapWith = function (pokemon, target, kwargs) {
|
||
// method provided for backwards compatibility only
|
||
if (pokemon === target) return;
|
||
|
||
if (!kwargs.silent) {
|
||
var fromeffect = Tools.getEffect(kwargs.from);
|
||
switch (fromeffect.id) {
|
||
case 'allyswitch':
|
||
this.battle.message('<small>' + pokemon.getName() + ' and ' + target.getLowerName() + ' switched places.</small>');
|
||
break;
|
||
}
|
||
}
|
||
|
||
var oslot = pokemon.slot;
|
||
var nslot = target.slot;
|
||
|
||
pokemon.slot = nslot;
|
||
target.slot = oslot;
|
||
this.active[nslot] = pokemon;
|
||
this.active[oslot] = target;
|
||
|
||
pokemon.sprite.animUnsummon(true);
|
||
target.sprite.animUnsummon(true);
|
||
|
||
pokemon.sprite.animSummon(nslot, true);
|
||
target.sprite.animSummon(oslot, true);
|
||
|
||
if (pokemon.statbarElem) {
|
||
pokemon.statbarElem.remove();
|
||
}
|
||
if (target.statbarElem) {
|
||
target.statbarElem.remove();
|
||
}
|
||
|
||
this.battle.statElem.append(this.getStatbarHTML(pokemon));
|
||
pokemon.statbarElem = this.battle.statElem.children().last();
|
||
this.battle.statElem.append(this.getStatbarHTML(target));
|
||
target.statbarElem = this.battle.statElem.children().last();
|
||
|
||
this.updateStatbar(pokemon, true);
|
||
this.updateStatbar(target, true);
|
||
|
||
pokemon.statbarElem.css({
|
||
display: 'block',
|
||
left: pokemon.sprite.left - 80,
|
||
top: pokemon.sprite.top - 73 - pokemon.sprite.statbarOffset,
|
||
opacity: 1
|
||
});
|
||
target.statbarElem.css({
|
||
display: 'block',
|
||
left: target.sprite.left - 80,
|
||
top: target.sprite.top - 73 - target.sprite.statbarOffset,
|
||
opacity: 1
|
||
});
|
||
};
|
||
Side.prototype.faint = function (pokemon, slot) {
|
||
if (slot === undefined) slot = pokemon.slot;
|
||
pokemon.clearVolatile();
|
||
this.lastPokemon = pokemon;
|
||
this.active[slot] = null;
|
||
|
||
this.battle.message('' + pokemon.getName() + ' fainted!');
|
||
|
||
pokemon.fainted = true;
|
||
pokemon.zerohp = true;
|
||
pokemon.hp = 0;
|
||
pokemon.side.updateStatbar(pokemon, false, true);
|
||
pokemon.side.updateSidebar();
|
||
|
||
pokemon.sprite.animFaint();
|
||
if (this.battle.fastForward) {
|
||
pokemon.statbarElem.remove();
|
||
pokemon.statbarElem = null;
|
||
} else {
|
||
pokemon.statbarElem.animate({
|
||
opacity: 0
|
||
}, 300, function () {
|
||
pokemon.statbarElem.remove();
|
||
pokemon.statbarElem = null;
|
||
});
|
||
}
|
||
if (this.battle.faintCallback) this.battle.faintCallback(this.battle, this);
|
||
};
|
||
Side.prototype.updateHPText = function (pokemon) {
|
||
var $hptext = pokemon.statbarElem.find('.hptext');
|
||
var $hptextborder = pokemon.statbarElem.find('.hptextborder');
|
||
if (pokemon.maxhp === 48 || this.battle.hardcoreMode && pokemon.maxhp === 100) {
|
||
$hptext.hide();
|
||
$hptextborder.hide();
|
||
} else if (this.battle.hardcoreMode) {
|
||
$hptext.html(pokemon.hp + '/');
|
||
$hptext.show();
|
||
$hptextborder.show();
|
||
} else {
|
||
$hptext.html(pokemon.hpWidth(100) + '%');
|
||
$hptext.show();
|
||
$hptextborder.show();
|
||
}
|
||
};
|
||
Side.prototype.updateStatbar = function (pokemon, updatePrevhp, updateHp) {
|
||
if (this.battle.fastForward) return;
|
||
if (!pokemon) {
|
||
if (this.active[0]) this.updateStatbar(this.active[0], updatePrevhp, updateHp);
|
||
if (this.active[1]) this.updateStatbar(this.active[1], updatePrevhp, updateHp);
|
||
if (this.active[2]) this.updateStatbar(this.active[2], updatePrevhp, updateHp);
|
||
return;
|
||
}
|
||
if (!pokemon || !pokemon.statbarElem) {
|
||
return;
|
||
}
|
||
var hpcolor;
|
||
if (updatePrevhp || updateHp) {
|
||
hpcolor = pokemon.getHPColor();
|
||
var w = pokemon.hpWidth(150);
|
||
var $hp = pokemon.statbarElem.find('.hp');
|
||
$hp.css({
|
||
width: w,
|
||
'border-right-width': (w ? 1 : 0)
|
||
});
|
||
if (hpcolor === 'g') $hp.removeClass('hp-yellow hp-red');
|
||
else if (hpcolor === 'y') $hp.removeClass('hp-red').addClass('hp-yellow');
|
||
else $hp.addClass('hp-yellow hp-red');
|
||
this.updateHPText(pokemon);
|
||
}
|
||
if (updatePrevhp) {
|
||
var $prevhp = pokemon.statbarElem.find('.prevhp');
|
||
$prevhp.css('width', pokemon.hpWidth(150) + 1);
|
||
if (hpcolor === 'g') $prevhp.removeClass('prevhp-yellow prevhp-red');
|
||
else if (hpcolor === 'y') $prevhp.removeClass('prevhp-red').addClass('prevhp-yellow');
|
||
else $prevhp.addClass('prevhp-yellow prevhp-red');
|
||
}
|
||
var status = '';
|
||
if (pokemon.status === 'brn') {
|
||
status += '<span class="brn">BRN</span> ';
|
||
} else if (pokemon.status === 'psn') {
|
||
status += '<span class="psn">PSN</span> ';
|
||
} else if (pokemon.status === 'tox') {
|
||
status += '<span class="psn">TOX</span> ';
|
||
} else if (pokemon.status === 'slp') {
|
||
status += '<span class="slp">SLP</span> ';
|
||
} else if (pokemon.status === 'par') {
|
||
status += '<span class="par">PAR</span> ';
|
||
} else if (pokemon.status === 'frz') {
|
||
status += '<span class="frz">FRZ</span> ';
|
||
}
|
||
if (pokemon.volatiles.typechange && pokemon.volatiles.typechange[2]) {
|
||
var types = pokemon.volatiles.typechange[2].split('/');
|
||
status += '<img src="' + Tools.resourcePrefix + 'sprites/types/' + encodeURIComponent(types[0]) + '.png" alt="' + types[0] + '" /> ';
|
||
if (types[1]) {
|
||
status += '<img src="' + Tools.resourcePrefix + 'sprites/types/' + encodeURIComponent(types[1]) + '.png" alt="' + types[1] + '" /> ';
|
||
}
|
||
}
|
||
if (pokemon.volatiles.typeadd) {
|
||
var type = pokemon.volatiles.typeadd[2];
|
||
status += '+<img src="' + Tools.resourcePrefix + 'sprites/types/' + type + '.png" alt="' + type + '" /> ';
|
||
}
|
||
for (var x in pokemon.boosts) {
|
||
if (pokemon.boosts[x]) {
|
||
status += '<span class="' + pokemon.getBoostType(x) + '">' + pokemon.getBoost(x) + '</span> ';
|
||
}
|
||
}
|
||
var statusTable = {
|
||
throatchop: '<span class="bad">Throat Chop</span> ',
|
||
confusion: '<span class="bad">Confused</span> ',
|
||
healblock: '<span class="bad">Heal Block</span> ',
|
||
yawn: '<span class="bad">Drowsy</span> ',
|
||
flashfire: '<span class="good">Flash Fire</span> ',
|
||
imprison: '<span class="good">Imprisoning foe</span> ',
|
||
formechange: '',
|
||
typechange: '',
|
||
typeadd: '',
|
||
autotomize: '<span class="neutral">Lightened</span> ',
|
||
miracleeye: '<span class="bad">Miracle Eye</span> ',
|
||
foresight: '<span class="bad">Foresight</span> ',
|
||
telekinesis: '<span class="neutral">Telekinesis</span> ',
|
||
transform: '<span class="neutral">Transformed</span> ',
|
||
powertrick: '<span class="neutral">Power Trick</span> ',
|
||
curse: '<span class="bad">Curse</span> ',
|
||
nightmare: '<span class="bad">Nightmare</span> ',
|
||
attract: '<span class="bad">Attract</span> ',
|
||
torment: '<span class="bad">Torment</span> ',
|
||
taunt: '<span class="bad">Taunt</span> ',
|
||
disable: '<span class="bad">Disable</span> ',
|
||
embargo: '<span class="bad">Embargo</span> ',
|
||
ingrain: '<span class="good">Ingrain</span> ',
|
||
aquaring: '<span class="good">Aqua Ring</span> ',
|
||
stockpile1: '<span class="good">Stockpile</span> ',
|
||
stockpile2: '<span class="good">Stockpile×2</span> ',
|
||
stockpile3: '<span class="good">Stockpile×3</span> ',
|
||
perish0: '<span class="bad">Perish now</span>',
|
||
perish1: '<span class="bad">Perish next turn</span> ',
|
||
perish2: '<span class="bad">Perish in 2</span> ',
|
||
perish3: '<span class="bad">Perish in 3</span> ',
|
||
airballoon: '<span class="good">Balloon</span> ',
|
||
leechseed: '<span class="bad">Leech Seed</span> ',
|
||
encore: '<span class="bad">Encore</span> ',
|
||
mustrecharge: '<span class="bad">Must recharge</span> ',
|
||
bide: '<span class="good">Bide</span> ',
|
||
magnetrise: '<span class="good">Magnet Rise</span> ',
|
||
smackdown: '<span class="bad">Smack Down</span> ',
|
||
focusenergy: '<span class="good">Focus Energy</span> ',
|
||
slowstart: '<span class="bad">Slow Start</span> ',
|
||
doomdesire: '',
|
||
futuresight: '',
|
||
mimic: '<span class="good">Mimic</span> ',
|
||
watersport: '<span class="good">Water Sport</span> ',
|
||
mudsport: '<span class="good">Mud Sport</span> ',
|
||
substitute: '',
|
||
// sub graphics are handled elsewhere, see Battle.Sprite.animSub()
|
||
uproar: '<span class="neutral">Uproar</span>',
|
||
rage: '<span class="neutral">Rage</span>',
|
||
roost: '<span class="neutral">Landed</span>',
|
||
protect: '<span class="good">Protect</span>',
|
||
quickguard: '<span class="good">Quick Guard</span>',
|
||
wideguard: '<span class="good">Wide Guard</span>',
|
||
craftyshield: '<span class="good">Crafty Shield</span>',
|
||
matblock: '<span class="good">Mat Block</span>',
|
||
helpinghand: '<span class="good">Helping Hand</span>',
|
||
magiccoat: '<span class="good">Magic Coat</span>',
|
||
destinybond: '<span class="good">Destiny Bond</span>',
|
||
snatch: '<span class="good">Snatch</span>',
|
||
grudge: '<span class="good">Grudge</span>',
|
||
endure: '<span class="good">Endure</span>',
|
||
focuspunch: '<span class="neutral">Focusing</span>',
|
||
shelltrap: '<span class="neutral">Trap set</span>',
|
||
powder: '<span class="bad">Powder</span>',
|
||
electrify: '<span class="bad">Electrify</span>',
|
||
ragepowder: '<span class="good">Rage Powder</span>',
|
||
followme: '<span class="good">Follow Me</span>',
|
||
instruct: '<span class="neutral">Instruct</span>',
|
||
beakblast: '<span class="neutral">Beak Blast</span>',
|
||
laserfocus: '<span class="good">Laser Focus</span>',
|
||
spotlight: '<span class="neutral">Spotlight</span>',
|
||
itemremoved: '',
|
||
// Gen 1
|
||
lightscreen: '<span class="good">Light Screen</span>',
|
||
reflect: '<span class="good">Reflect</span>'
|
||
};
|
||
for (var i in pokemon.volatiles) {
|
||
if (typeof statusTable[i] === 'undefined') status += '<span class="neutral">[[' + i + ']]</span>';
|
||
else status += statusTable[i];
|
||
}
|
||
for (var i in pokemon.turnstatuses) {
|
||
if (typeof statusTable[i] === 'undefined') status += '<span class="neutral">[[' + i + ']]</span>';
|
||
else status += statusTable[i];
|
||
}
|
||
for (var i in pokemon.movestatuses) {
|
||
if (typeof statusTable[i] === 'undefined') status += '<span class="neutral">[[' + i + ']]</span>';
|
||
else status += statusTable[i];
|
||
}
|
||
var statusbar = pokemon.statbarElem.find('.status');
|
||
statusbar.html(status);
|
||
};
|
||
Side.prototype.destroy = function () {
|
||
for (var i = 0; i < this.pokemon.length; i++) {
|
||
if (this.pokemon[i]) this.pokemon[i].destroy();
|
||
this.pokemon[i] = null;
|
||
}
|
||
for (var i = 0; i < this.active.length; i++) {
|
||
if (this.active[i]) this.active[i].destroy();
|
||
this.active[i] = null;
|
||
}
|
||
delete this.battle;
|
||
delete this.foe;
|
||
};
|
||
|
||
return Side;
|
||
})();
|
||
|
||
var Battle = (function () {
|
||
function Battle(frame, logFrame) {
|
||
frame.addClass('battle');
|
||
|
||
// turn number
|
||
this.turn = 0;
|
||
// has playback gotten to the point where a player has won or tied?
|
||
// affects whether BGM is playing
|
||
this.ended = false;
|
||
this.usesUpkeep = false;
|
||
this.weather = '';
|
||
this.pseudoWeather = [];
|
||
this.weatherTimeLeft = 0;
|
||
this.weatherMinTimeLeft = 0;
|
||
this.mySide = null;
|
||
this.yourSide = null;
|
||
this.p1 = null;
|
||
this.p2 = null;
|
||
this.sides = [];
|
||
this.lastMove = '';
|
||
this.gen = 6;
|
||
this.speciesClause = false;
|
||
|
||
this.frameElem = frame;
|
||
this.logFrameElem = logFrame;
|
||
this.logElem = null;
|
||
this.weatherElem = null;
|
||
this.bgEffectElem = null;
|
||
this.bgElem = null;
|
||
this.spriteElem = null;
|
||
this.spriteElems = [null, null];
|
||
this.spriteElemsFront = [null, null];
|
||
this.statElem = null;
|
||
this.fxElem = null;
|
||
this.leftbarElem = null;
|
||
this.rightbarElem = null;
|
||
this.turnElem = null;
|
||
this.messagebarElem = null;
|
||
this.delayElem = null;
|
||
this.hiddenMessageElem = null;
|
||
this.ignoreNicks = Tools.prefs('ignorenicks');
|
||
|
||
this.paused = true;
|
||
// 0 = uninitialized
|
||
// 1 = ready
|
||
// 2 = playing
|
||
// 3 = paused
|
||
// 4 = finished
|
||
// 5 = seeking
|
||
this.playbackState = 0;
|
||
|
||
this.backdropImage = 'sprites/gen6bgs/' + BattleBackdrops[Math.floor(Math.random() * BattleBackdrops.length)];
|
||
|
||
this.bgm = null;
|
||
this.activeQueue = this.queue1;
|
||
|
||
this.activityQueue = [];
|
||
this.preemptActivityQueue = [];
|
||
this.activityAnimations = $();
|
||
this.minorQueue = [];
|
||
|
||
// external
|
||
this.resumeButton = null;
|
||
|
||
this.preloadCache = {};
|
||
|
||
this.preloadEffects();
|
||
this.init();
|
||
}
|
||
|
||
Battle.prototype.sidesSwitched = false;
|
||
Battle.prototype.messageActive = false;
|
||
|
||
// activity queue
|
||
Battle.prototype.animationDelay = 0;
|
||
Battle.prototype.activityStep = 0;
|
||
Battle.prototype.activityDelay = 0;
|
||
Battle.prototype.activityAfter = null;
|
||
Battle.prototype.activityQueueActive = false;
|
||
Battle.prototype.fastForward = false;
|
||
|
||
Battle.prototype.resultWaiting = false;
|
||
Battle.prototype.multiHitMove = null;
|
||
Battle.prototype.activeMoveIsSpread = null;
|
||
|
||
// callback
|
||
Battle.prototype.faintCallback = null;
|
||
Battle.prototype.switchCallback = null;
|
||
Battle.prototype.dragCallback = null;
|
||
Battle.prototype.turnCallback = null;
|
||
Battle.prototype.startCallback = null;
|
||
Battle.prototype.stagnateCallback = null;
|
||
Battle.prototype.endCallback = null;
|
||
Battle.prototype.customCallback = null;
|
||
Battle.prototype.errorCallback = null;
|
||
|
||
Battle.prototype.preloadDone = 0;
|
||
Battle.prototype.preloadNeeded = 0;
|
||
Battle.prototype.bgm = null;
|
||
|
||
Battle.prototype.mute = false;
|
||
Battle.prototype.messageDelay = 8;
|
||
|
||
|
||
Battle.prototype.removePseudoWeather = function (weather) {
|
||
for (var i = 0; i < this.pseudoWeather.length; i++) {
|
||
if (this.pseudoWeather[i][0] === weather) {
|
||
this.pseudoWeather.splice(i, 1);
|
||
this.updateWeather();
|
||
return;
|
||
}
|
||
}
|
||
};
|
||
Battle.prototype.addPseudoWeather = function (weather, minTimeLeft, timeLeft) {
|
||
this.pseudoWeather.push([weather, minTimeLeft, timeLeft]);
|
||
this.updateWeather();
|
||
};
|
||
Battle.prototype.hasPseudoWeather = function (weather) {
|
||
for (var i = 0; i < this.pseudoWeather.length; i++) {
|
||
if (this.pseudoWeather[i][0] === weather) {
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
};
|
||
Battle.prototype.init = function () {
|
||
this.reset();
|
||
this.mySide = new Side(this, 0);
|
||
this.yourSide = new Side(this, 1);
|
||
this.mySide.foe = this.yourSide;
|
||
this.yourSide.foe = this.mySide;
|
||
this.sides = [this.mySide, this.yourSide];
|
||
this.p1 = this.mySide;
|
||
this.p2 = this.yourSide;
|
||
this.gen = 6;
|
||
};
|
||
Battle.prototype.updateGen = function () {
|
||
var gen = this.gen;
|
||
if (Tools.prefs('nopastgens')) gen = 6;
|
||
if (Tools.prefs('bwgfx') && gen > 5) gen = 5;
|
||
if (gen <= 5) {
|
||
if (gen <= 1) this.backdropImage = 'fx/bg-gen1.png';
|
||
else if (gen <= 2) this.backdropImage = 'fx/bg-gen2.png';
|
||
else if (gen <= 3) this.backdropImage = 'fx/' + BattleBackdropsThree[Math.floor(Math.random() * BattleBackdropsThree.length)];
|
||
else if (gen <= 4) this.backdropImage = 'fx/' + BattleBackdropsFour[Math.floor(Math.random() * BattleBackdropsFour.length)];
|
||
else this.backdropImage = 'fx/' + BattleBackdropsFive[Math.floor(Math.random() * BattleBackdropsFive.length)];
|
||
}
|
||
if (this.bgElem) this.bgElem.css('background-image', 'url(' + Tools.resourcePrefix + '' + this.backdropImage + ')');
|
||
};
|
||
Battle.prototype.reset = function (dontResetSound) {
|
||
// battle state
|
||
this.turn = 0;
|
||
this.ended = false;
|
||
this.weather = '';
|
||
this.weatherTimeLeft = 0;
|
||
this.weatherMinTimeLeft = 0;
|
||
this.pseudoWeather = [];
|
||
this.lastMove = '';
|
||
|
||
// DOM state
|
||
this.frameElem.empty();
|
||
this.frameElem.html('<div class="innerbattle"></div>');
|
||
this.elem = this.frameElem.children();
|
||
if (this.optionsElem) {
|
||
this.logElem.empty();
|
||
this.logPreemptElem.empty();
|
||
} else {
|
||
this.logFrameElem.html('<div class="battle-options"></div>');
|
||
this.optionsElem = this.logFrameElem.children().last();
|
||
this.logFrameElem.append('<div class="inner" role="log"></div>');
|
||
this.logElem = this.logFrameElem.children().last();
|
||
this.logFrameElem.append('<div class="inner-preempt"></div>');
|
||
this.logPreemptElem = this.logFrameElem.children().last();
|
||
this.logFrameElem.append('<div class="inner-after"></div>');
|
||
}
|
||
|
||
this.updateGen();
|
||
this.elem.append('<div class="backdrop" style="background-image:url(' + Tools.resourcePrefix + '' + this.backdropImage + ');display:block;opacity:0"></div>');
|
||
this.bgElem = this.elem.children().last();
|
||
this.bgElem.animate({
|
||
opacity: 0.8
|
||
});
|
||
|
||
this.elem.append('<div class="weather"></div>');
|
||
this.weatherElem = this.elem.children().last();
|
||
|
||
this.elem.append('<div></div>');
|
||
this.bgEffectElem = this.elem.children().last();
|
||
|
||
this.elem.append('<div></div>');
|
||
this.spriteElem = this.elem.children().last();
|
||
|
||
this.spriteElem.append('<div></div>');
|
||
this.spriteElems[1] = this.spriteElem.children().last();
|
||
this.spriteElem.append('<div></div>');
|
||
this.spriteElemsFront[1] = this.spriteElem.children().last();
|
||
this.spriteElem.append('<div></div>');
|
||
this.spriteElemsFront[0] = this.spriteElem.children().last();
|
||
this.spriteElem.append('<div></div>');
|
||
this.spriteElems[0] = this.spriteElem.children().last();
|
||
|
||
this.elem.append('<div role="complementary" aria-label="Active Pokemon"></div>');
|
||
this.statElem = this.elem.children().last();
|
||
|
||
this.elem.append('<div></div>');
|
||
this.fxElem = this.elem.children().last();
|
||
|
||
this.elem.append('<div class="leftbar" role="complementary" aria-label="Your Team"></div>');
|
||
this.leftbarElem = this.elem.children().last();
|
||
|
||
this.elem.append('<div class="rightbar" role="complementary" aria-label="Opponent\'s Team"></div>');
|
||
this.rightbarElem = this.elem.children().last();
|
||
|
||
this.elem.append('<div></div>');
|
||
this.turnElem = this.elem.children().last();
|
||
|
||
this.elem.append('<div class="messagebar message"></div>');
|
||
this.messagebarElem = this.elem.children().last();
|
||
|
||
this.elem.append('<div></div>');
|
||
this.delayElem = this.elem.children().last();
|
||
|
||
this.elem.append('<div class="message" style="position:absolute;display:block;visibility:hidden"></div>');
|
||
this.hiddenMessageElem = this.elem.children().last();
|
||
|
||
if (this.mySide) this.mySide.reset();
|
||
if (this.yourSide) this.yourSide.reset();
|
||
|
||
if (this.ignoreNicks) {
|
||
var $log = $('.battle-log .inner');
|
||
if ($log.length) $log.addClass('hidenicks');
|
||
}
|
||
|
||
// activity queue state
|
||
this.animationDelay = 0;
|
||
this.multiHitMove = null;
|
||
this.activeMoveIsSpread = null;
|
||
this.activityStep = 0;
|
||
this.activityDelay = 0;
|
||
this.activityAfter = null;
|
||
this.activityAnimations = $();
|
||
this.activityQueueActive = false;
|
||
this.fastForwardOff();
|
||
$.fx.off = false;
|
||
this.minorQueue = [];
|
||
this.resultWaiting = false;
|
||
this.paused = true;
|
||
if (this.playbackState !== 5) {
|
||
this.playbackState = (this.activityQueue.length ? 1 : 0);
|
||
if (!dontResetSound) this.soundStop();
|
||
}
|
||
};
|
||
Battle.prototype.destroy = function () {
|
||
if (this.logFrameElem) this.logFrameElem.remove();
|
||
|
||
this.soundStop();
|
||
for (var i = 0; i < this.sides.length; i++) {
|
||
if (this.sides[i]) this.sides[i].destroy();
|
||
this.sides[i] = null;
|
||
}
|
||
delete this.mySide;
|
||
delete this.yourSide;
|
||
delete this.p1;
|
||
delete this.p2;
|
||
};
|
||
|
||
Battle.prototype.logConsole = function (text) {
|
||
if (window.console && console.log) console.log(text);
|
||
};
|
||
Battle.prototype.log = function (html, preempt) {
|
||
var willScroll = false;
|
||
if (!this.fastForward) willScroll = (this.logFrameElem.scrollTop() + 60 >= this.logElem.height() + this.logPreemptElem.height() - this.optionsElem.height() - this.logFrameElem.height());
|
||
if (preempt) {
|
||
this.logPreemptElem.append(html);
|
||
} else {
|
||
this.logElem.append(html);
|
||
}
|
||
if (willScroll) {
|
||
this.logFrameElem.scrollTop(this.logElem.height() + this.logPreemptElem.height());
|
||
}
|
||
};
|
||
Battle.prototype.preemptCatchup = function () {
|
||
this.logElem.append(this.logPreemptElem.children().first());
|
||
};
|
||
|
||
Battle.prototype.pos = function (loc, obj) {
|
||
var left, top, scale, width, height;
|
||
|
||
if (!loc.scale && loc.scale !== 0) loc.scale = 1;
|
||
if (!loc.xscale && loc.xscale !== 0) loc.xscale = loc.scale;
|
||
if (!loc.yscale && loc.yscale !== 0) loc.yscale = loc.scale;
|
||
if (!loc.opacity && loc.opacity !== 0) loc.opacity = 1;
|
||
if (!loc.z) loc.z = 0;
|
||
if (!loc.x) loc.x = 0;
|
||
if (!loc.y) loc.y = 0;
|
||
|
||
left = 210;
|
||
top = 245;
|
||
scale = 1;
|
||
scale = 1.5 - 0.5 * (loc.z / 200);
|
||
if (scale < .1) scale = .1;
|
||
|
||
left += (410 - 190) * (loc.z / 200);
|
||
top += (135 - 245) * (loc.z / 200);
|
||
left += Math.floor(loc.x * scale);
|
||
top -= Math.floor(loc.y * scale /* - loc.x * scale / 4 */);
|
||
width = Math.floor(obj.w * scale * loc.xscale);
|
||
height = Math.floor(obj.h * scale * loc.yscale);
|
||
left -= Math.floor(width / 2);
|
||
top -= Math.floor(height / 2);
|
||
|
||
var pos = {
|
||
left: left,
|
||
top: top,
|
||
width: width,
|
||
height: height,
|
||
opacity: loc.opacity
|
||
};
|
||
if (loc.display) pos.display = loc.display;
|
||
return pos;
|
||
};
|
||
Battle.prototype.posT = function (loc, obj, transition, oldloc) {
|
||
var pos = this.pos(loc, obj);
|
||
var oldpos = null;
|
||
if (oldloc) oldpos = this.pos(oldloc, obj);
|
||
var transitionMap = {
|
||
left: 'linear',
|
||
top: 'linear',
|
||
width: 'linear',
|
||
height: 'linear',
|
||
opacity: 'linear'
|
||
};
|
||
if (transition === 'ballistic') {
|
||
transitionMap.top = (pos.top < oldpos.top ? 'ballisticUp' : 'ballisticDown');
|
||
}
|
||
if (transition === 'ballisticUnder') {
|
||
transitionMap.top = (pos.top < oldpos.top ? 'ballisticDown' : 'ballisticUp');
|
||
}
|
||
if (transition === 'ballistic2') {
|
||
transitionMap.top = (pos.top < oldpos.top ? 'quadUp' : 'quadDown');
|
||
}
|
||
if (transition === 'ballistic2Under') {
|
||
transitionMap.top = (pos.top < oldpos.top ? 'quadDown' : 'quadUp');
|
||
}
|
||
if (transition === 'swing') {
|
||
transitionMap.left = 'swing';
|
||
transitionMap.top = 'swing';
|
||
transitionMap.width = 'swing';
|
||
transitionMap.height = 'swing';
|
||
}
|
||
if (transition === 'accel') {
|
||
transitionMap.left = 'quadDown';
|
||
transitionMap.top = 'quadDown';
|
||
transitionMap.width = 'quadDown';
|
||
transitionMap.height = 'quadDown';
|
||
}
|
||
if (transition === 'decel') {
|
||
transitionMap.left = 'quadUp';
|
||
transitionMap.top = 'quadUp';
|
||
transitionMap.width = 'quadUp';
|
||
transitionMap.height = 'quadUp';
|
||
}
|
||
return {
|
||
left: [pos.left, transitionMap.left],
|
||
top: [pos.top, transitionMap.top],
|
||
width: [pos.width, transitionMap.width],
|
||
height: [pos.height, transitionMap.height],
|
||
opacity: [pos.opacity, transitionMap.opacity]
|
||
};
|
||
};
|
||
Battle.prototype.backgroundEffect = function (bg, duration, opacity, delay) {
|
||
if (!opacity) {
|
||
opacity = 1;
|
||
}
|
||
if (!delay) delay = 0;
|
||
this.bgEffectElem.append('<div class="background"></div>');
|
||
var elem = this.bgEffectElem.children().last();
|
||
elem.css({
|
||
background: bg,
|
||
display: 'block',
|
||
opacity: 0
|
||
});
|
||
elem.delay(delay).animate({
|
||
opacity: opacity
|
||
}, 250).delay(duration - 250);
|
||
elem.animate({
|
||
opacity: 0
|
||
}, 250);
|
||
};
|
||
Battle.prototype.showEffect = function (img, start, end, transition, after) {
|
||
var effect = img;
|
||
if (img && img.length) effect = BattleEffects[img];
|
||
if (!start.time) start.time = 0;
|
||
if (!end.time) end.time = start.time + 500;
|
||
start.time += this.animationDelay;
|
||
end.time += this.animationDelay;
|
||
if (!end.scale && end.scale !== 0) end.scale = start.scale;
|
||
if (!end.xscale && end.xscale !== 0) end.xscale = start.xscale;
|
||
if (!end.yscale && end.yscale !== 0) end.yscale = start.yscale;
|
||
end = $.extend({}, start, end);
|
||
|
||
var startpos = this.pos(start, effect);
|
||
var endpos = this.posT(end, effect, transition, start);
|
||
|
||
this.fxElem.append('<img src="' + effect.url + '" style="display:none;position:absolute" />');
|
||
var effectElem = this.fxElem.children().last();
|
||
effectElem.css({
|
||
display: 'block',
|
||
opacity: 0
|
||
});
|
||
effectElem.css(startpos);
|
||
effectElem.css({
|
||
opacity: 0
|
||
});
|
||
|
||
if (start.time) {
|
||
effectElem.delay(start.time).animate({
|
||
opacity: startpos.opacity
|
||
}, 1);
|
||
} else {
|
||
effectElem.css('opacity', startpos.opacity);
|
||
}
|
||
effectElem.animate(endpos, end.time - start.time);
|
||
if (after === 'fade') {
|
||
effectElem.animate({
|
||
opacity: 0
|
||
}, 100);
|
||
}
|
||
if (after === 'explode') {
|
||
if (end.scale) end.scale *= 3;
|
||
if (end.xscale) end.xscale *= 3;
|
||
if (end.yscale) end.yscale *= 3;
|
||
end.opacity = 0;
|
||
var endendpos = this.pos(end, effect);
|
||
effectElem.animate(endendpos, 200);
|
||
}
|
||
this.activityWait(effectElem);
|
||
};
|
||
Battle.prototype.switchSides = function (replay) {
|
||
if (replay) {
|
||
this.reset(true);
|
||
this.setSidesSwitched(!this.sidesSwitched);
|
||
this.play();
|
||
} else if (this.ended) {
|
||
this.reset(true);
|
||
this.setSidesSwitched(!this.sidesSwitched);
|
||
this.fastForwardTo(-1);
|
||
} else {
|
||
var turn = this.turn;
|
||
var playbackState = this.playbackState;
|
||
this.reset(true);
|
||
this.setSidesSwitched(!this.sidesSwitched);
|
||
if (turn) this.fastForwardTo(turn);
|
||
if (this.playbackState !== 3) {
|
||
this.play();
|
||
} else {
|
||
this.pause();
|
||
}
|
||
}
|
||
};
|
||
Battle.prototype.setSidesSwitched = function (sidesSwitched) {
|
||
this.sidesSwitched = sidesSwitched;
|
||
if (this.sidesSwitched) {
|
||
this.mySide = this.p2;
|
||
this.yourSide = this.p1;
|
||
} else {
|
||
this.mySide = this.p1;
|
||
this.yourSide = this.p2;
|
||
}
|
||
this.mySide.n = 0;
|
||
this.yourSide.n = 1;
|
||
this.sides[0] = this.mySide;
|
||
this.sides[1] = this.yourSide;
|
||
|
||
this.mySide.updateSidebar();
|
||
this.mySide.updateSprites();
|
||
this.yourSide.updateSidebar();
|
||
this.yourSide.updateSprites();
|
||
// nothing else should need updating - don't call this function after sending out pokemon
|
||
};
|
||
Battle.prototype.message = function (message, hiddenmessage) {
|
||
if (message && !this.messageActive) {
|
||
this.log('<div class="spacer battle-history"></div>');
|
||
}
|
||
if (message && !this.fastForward) {
|
||
if (!this.messageActive) {
|
||
this.messagebarElem.empty();
|
||
this.messagebarElem.css({
|
||
display: 'block',
|
||
opacity: 0,
|
||
height: 'auto'
|
||
});
|
||
this.messagebarElem.animate({
|
||
opacity: 1
|
||
}, 300);
|
||
}
|
||
this.hiddenMessageElem.append('<p></p>');
|
||
var messageElem = this.hiddenMessageElem.children().last();
|
||
messageElem.html(message);
|
||
messageElem.css({
|
||
display: 'block',
|
||
opacity: 0
|
||
});
|
||
var self = this;
|
||
messageElem.animate({
|
||
height: 'hide'
|
||
}, 1, function () {
|
||
messageElem.appendTo(self.messagebarElem);
|
||
messageElem.animate({
|
||
height: 'show',
|
||
'padding-bottom': 4,
|
||
opacity: 1
|
||
}, 300);
|
||
});
|
||
this.activityWait(messageElem);
|
||
}
|
||
this.messageActive = true;
|
||
this.log('<div class="battle-history">' + message + (hiddenmessage ? hiddenmessage : '') + '</div>');
|
||
};
|
||
Battle.prototype.endAction = function () {
|
||
if (this.messageActive) {
|
||
this.messageActive = false;
|
||
if (!this.fastForward) {
|
||
this.messagebarElem.delay(this.messageDelay).animate({
|
||
height: 'toggle',
|
||
opacity: 0
|
||
}, 300);
|
||
this.activityWait(this.messagebarElem);
|
||
}
|
||
}
|
||
};
|
||
|
||
//
|
||
// activities
|
||
//
|
||
Battle.prototype.start = function () {
|
||
this.log('<div>Battle between ' + Tools.escapeHTML(this.p1.name) + ' and ' + Tools.escapeHTML(this.p2.name) + ' started!</div>');
|
||
if (this.startCallback) this.startCallback(this);
|
||
};
|
||
Battle.prototype.winner = function (winner) {
|
||
if (winner) this.message('' + Tools.escapeHTML(winner) + ' won the battle!');
|
||
else this.message('Tie between ' + Tools.escapeHTML(this.p1.name) + ' and ' + Tools.escapeHTML(this.p2.name) + '!');
|
||
this.ended = true;
|
||
};
|
||
Battle.prototype.prematureEnd = function () {
|
||
this.message('This replay ends here.');
|
||
this.ended = true;
|
||
};
|
||
Battle.prototype.endLastTurn = function () {
|
||
if (this.endLastTurnPending) {
|
||
this.endLastTurnPending = false;
|
||
this.mySide.updateStatbar(null, true);
|
||
this.yourSide.updateStatbar(null, true);
|
||
}
|
||
};
|
||
Battle.prototype.setHardcoreMode = function (mode) {
|
||
this.hardcoreMode = mode;
|
||
this.mySide.updateSidebar();
|
||
this.yourSide.updateSidebar();
|
||
this.updateWeather(undefined, true);
|
||
};
|
||
Battle.prototype.setTurn = function (turnnum) {
|
||
turnnum = parseInt(turnnum, 10);
|
||
if (turnnum == this.turn + 1) {
|
||
this.endLastTurnPending = true;
|
||
}
|
||
if (this.turn && !this.usesUpkeep) this.updatePseudoWeatherLeft(); // for compatibility with old replays
|
||
this.turn = turnnum;
|
||
|
||
if (this.mySide.active[0]) this.mySide.active[0].clearTurnstatuses();
|
||
if (this.mySide.active[1]) this.mySide.active[1].clearTurnstatuses();
|
||
if (this.mySide.active[2]) this.mySide.active[2].clearTurnstatuses();
|
||
if (this.yourSide.active[0]) this.yourSide.active[0].clearTurnstatuses();
|
||
if (this.yourSide.active[1]) this.yourSide.active[1].clearTurnstatuses();
|
||
if (this.yourSide.active[2]) this.yourSide.active[2].clearTurnstatuses();
|
||
|
||
this.log('<h2 class="battle-history">Turn ' + turnnum + '</h2>');
|
||
|
||
var prevTurnElem = this.turnElem.children();
|
||
if (this.fastForward) {
|
||
if (prevTurnElem.length) prevTurnElem.html('Turn ' + turnnum);
|
||
else this.turnElem.append('<div class="turn" style="display:block;opacity:1;left:110px;">Turn ' + turnnum + '</div>');
|
||
if (this.turnCallback) this.turnCallback(this);
|
||
if (this.fastForward > -1 && turnnum >= this.fastForward) {
|
||
this.fastForwardOff();
|
||
if (this.endCallback) this.endCallback(this);
|
||
}
|
||
return;
|
||
}
|
||
this.turnElem.append('<div class="turn">Turn ' + turnnum + '</div>');
|
||
var newTurnElem = this.turnElem.children().last();
|
||
newTurnElem.css({
|
||
display: 'block',
|
||
opacity: 0,
|
||
left: 160
|
||
});
|
||
newTurnElem.animate({
|
||
opacity: 1,
|
||
left: 110
|
||
}, 500).animate({
|
||
opacity: .4
|
||
}, 1500);
|
||
prevTurnElem.animate({
|
||
opacity: 0,
|
||
left: 60
|
||
}, 500, function () {
|
||
prevTurnElem.remove();
|
||
});
|
||
this.activityWait(500);
|
||
if (this.turnCallback) this.turnCallback(this);
|
||
};
|
||
Battle.prototype.changeWeather = function (weather, poke, isUpkeep, ability) {
|
||
weather = toId(weather);
|
||
var weatherTable = {
|
||
sunnyday: {
|
||
name: 'Sun',
|
||
startMessage: 'The sunlight turned harsh!',
|
||
abilityMessage: "'s Drought intensified the sun's rays!",
|
||
//upkeepMessage: 'The sunlight is strong!',
|
||
endMessage: "The sunlight faded."
|
||
},
|
||
desolateland: {
|
||
name: "Intense Sun",
|
||
startMessage: "The sunlight turned extremely harsh!",
|
||
endMessage: "The harsh sunlight faded."
|
||
},
|
||
raindance: {
|
||
name: 'Rain',
|
||
startMessage: 'It started to rain!',
|
||
abilityMessage: "'s Drizzle made it rain!",
|
||
//upkeepMessage: 'Rain continues to fall!',
|
||
endMessage: 'The rain stopped.'
|
||
},
|
||
primordialsea: {
|
||
name: "Heavy Rain",
|
||
startMessage: "A heavy rain began to fall!",
|
||
endMessage: "The heavy rain has lifted!"
|
||
},
|
||
sandstorm: {
|
||
name: 'Sandstorm',
|
||
startMessage: 'A sandstorm kicked up!',
|
||
abilityMessage: "'s Sand Stream whipped up a sandstorm!",
|
||
upkeepMessage: 'The sandstorm is raging.',
|
||
endMessage: 'The sandstorm subsided.'
|
||
},
|
||
hail: {
|
||
name: 'Hail',
|
||
startMessage: 'It started to hail!',
|
||
abilityMessage: "'s Snow Warning whipped up a hailstorm!",
|
||
upkeepMessage: 'The hail is crashing down.',
|
||
endMessage: 'The hail stopped.'
|
||
},
|
||
deltastream: {
|
||
name: 'Strong Winds',
|
||
startMessage: 'Mysterious strong winds are protecting Flying-type Pokémon!',
|
||
endMessage: 'The mysterious strong winds have dissipated!'
|
||
}
|
||
};
|
||
if (!weather || weather === 'none') {
|
||
weather = '';
|
||
}
|
||
var newWeather = weatherTable[weather];
|
||
if (isUpkeep) {
|
||
if (this.weather && this.weatherTimeLeft) {
|
||
this.weatherTimeLeft--;
|
||
if (this.weatherMinTimeLeft != 0) this.weatherMinTimeLeft--;
|
||
}
|
||
if (!this.fastForward) {
|
||
this.weatherElem.animate({
|
||
opacity: 1.0
|
||
}, 400).animate({
|
||
opacity: .4
|
||
}, 400);
|
||
}
|
||
if (newWeather && newWeather.upkeepMessage) this.log('<div><small>' + newWeather.upkeepMessage + '</small></div>');
|
||
return;
|
||
}
|
||
if (newWeather) {
|
||
var isExtremeWeather = (weather === 'deltastream' || weather === 'desolateland' || weather === 'primordialsea');
|
||
if (poke) {
|
||
if (ability) {
|
||
this.resultAnim(poke, ability.name, 'ability');
|
||
this.message('', "<small>[" + poke.getName(true) + "'s " + ability.name + "!]</small>");
|
||
poke.markAbility(ability.name);
|
||
this.message('<small>' + newWeather.startMessage + '</small>');
|
||
} else {
|
||
this.message('<small>' + poke.getName() + newWeather.abilityMessage + '</small>'); // for backwards compatibility
|
||
}
|
||
this.weatherTimeLeft = (this.gen <= 5 || isExtremeWeather) ? 0 : 8;
|
||
this.weatherMinTimeLeft = (this.gen <= 5 || isExtremeWeather) ? 0 : 5;
|
||
} else if (isUpkeep) {
|
||
this.log('<div><small>' + newWeather.upkeepMessage + '</small></div>');
|
||
this.weatherTimeLeft = 0;
|
||
this.weatherMinTimeLeft = 0;
|
||
} else if (isExtremeWeather) {
|
||
this.message('<small>' + newWeather.startMessage + '</small>');
|
||
this.weatherTimeLeft = 0;
|
||
this.weatherMinTimeLeft = 0;
|
||
} else {
|
||
this.message('<small>' + newWeather.startMessage + '</small>');
|
||
this.weatherTimeLeft = (this.gen <= 3 ? 5 : 8);
|
||
this.weatherMinTimeLeft = (this.gen <= 3 ? 0 : 5);
|
||
}
|
||
}
|
||
if (this.weather && !newWeather) {
|
||
this.message('<small>' + weatherTable[this.weather].endMessage + '</small>');
|
||
}
|
||
this.updateWeather(weather);
|
||
};
|
||
Battle.prototype.updatePseudoWeatherLeft = function () {
|
||
for (var i = 0; i < this.pseudoWeather.length; i++) {
|
||
var pWeather = this.pseudoWeather[i];
|
||
if (pWeather[1]) pWeather[1]--;
|
||
if (pWeather[2]) pWeather[2]--;
|
||
}
|
||
for (var i = 0; i < this.sides.length; i++) {
|
||
for (var id in this.sides[i].sideConditions) {
|
||
var cond = this.sides[i].sideConditions[id];
|
||
if (cond[3]) cond[3]--;
|
||
if (cond[4]) cond[4]--;
|
||
}
|
||
}
|
||
this.updateWeather();
|
||
};
|
||
Battle.prototype.pseudoWeatherLeft = function (pWeather) {
|
||
var buf = '<br />' + Tools.getMove(pWeather[0]).name;
|
||
if (!pWeather[1] && pWeather[2]) {
|
||
pWeather[1] = pWeather[2];
|
||
pWeather[2] = 0;
|
||
}
|
||
if (this.gen < 7 && this.hardcoreMode) return buf;
|
||
if (pWeather[2]) {
|
||
return buf + ' <small>(' + pWeather[1] + ' or ' + pWeather[2] + ' turns)</small>';
|
||
}
|
||
if (pWeather[1]) {
|
||
return buf + ' <small>(' + pWeather[1] + ' turn' + (pWeather[1] == 1 ? '' : 's') + ')</small>';
|
||
}
|
||
return buf; // weather not found
|
||
};
|
||
Battle.prototype.sideConditionLeft = function (cond, siden) {
|
||
if (!cond[3] && !cond[4]) return '';
|
||
var buf = '<br />' + (siden ? "Foe's " : "") + Tools.getMove(cond[0]).name;
|
||
if (!cond[3] && cond[4]) {
|
||
cond[3] = cond[4];
|
||
cond[4] = 0;
|
||
}
|
||
if (this.gen < 7 && this.hardcoreMode) return buf;
|
||
if (!cond[4]) {
|
||
return buf + ' <small>(' + cond[3] + ' turn' + (cond[3] == 1 ? '' : 's') + ')</small>';
|
||
}
|
||
return buf + ' <small>(' + cond[3] + ' or ' + cond[4] + ' turns)</small>';
|
||
};
|
||
Battle.prototype.weatherLeft = function () {
|
||
if (this.gen < 7 && this.hardcoreMode) return '';
|
||
if (this.weatherMinTimeLeft != 0) {
|
||
return ' <small>(' + this.weatherMinTimeLeft + ' or ' + this.weatherTimeLeft + ' turns)</small>';
|
||
}
|
||
if (this.weatherTimeLeft != 0) {
|
||
return ' <small>(' + this.weatherTimeLeft + ' turn' + (this.weatherTimeLeft == 1 ? '' : 's') + ')</small>';
|
||
}
|
||
return '';
|
||
};
|
||
Battle.prototype.updateWeather = function (weather, instant) {
|
||
if (typeof weather === 'undefined') {
|
||
weather = this.weather;
|
||
}
|
||
var isIntense = false;
|
||
var weatherNameTable = {
|
||
sunnyday: 'Sun',
|
||
desolateland: 'Intense Sun',
|
||
raindance: 'Rain',
|
||
primordialsea: 'Heavy Rain',
|
||
sandstorm: 'Sandstorm',
|
||
hail: 'Hail',
|
||
deltastream: 'Strong Winds'
|
||
};
|
||
if (!(weather in weatherNameTable)) {
|
||
weather = (this.pseudoWeather.length ? 'pseudo' : '');
|
||
for (var i = 0; i < this.pseudoWeather.length; i++) {
|
||
var pwid = toId(this.pseudoWeather[i][0]);
|
||
switch (pwid) {
|
||
case 'electricterrain':
|
||
case 'grassyterrain':
|
||
case 'mistyterrain':
|
||
case 'psychicterrain':
|
||
weather = pwid;
|
||
isIntense = true;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
if (weather === 'desolateland' || weather === 'primordialsea' || weather === 'deltastream') {
|
||
isIntense = true;
|
||
}
|
||
|
||
var oldweather = this.weather;
|
||
this.weather = weather;
|
||
|
||
if (this.fastForward) return;
|
||
|
||
if (instant) oldweather = true;
|
||
|
||
var weatherhtml = '';
|
||
if (weather) {
|
||
if (weather in weatherNameTable) {
|
||
weatherhtml += '<br />' + weatherNameTable[weather] + this.weatherLeft();
|
||
}
|
||
for (var i = 0; i < this.pseudoWeather.length; i++) {
|
||
weatherhtml += this.pseudoWeatherLeft(this.pseudoWeather[i]);
|
||
}
|
||
}
|
||
for (var i = 0; i < this.sides.length; i++) {
|
||
for (var id in this.sides[i].sideConditions) {
|
||
weatherhtml += this.sideConditionLeft(this.sides[i].sideConditions[id], i);
|
||
}
|
||
}
|
||
if (instant || weather === oldweather) {
|
||
if (weather) {
|
||
this.weatherElem.attr('class', 'weather ' + weather + 'weather');
|
||
} else {
|
||
this.weatherElem.attr('class', 'weather');
|
||
}
|
||
this.weatherElem.html('<em>' + weatherhtml + '</em>');
|
||
this.weatherElem.css({opacity: isIntense ? 0.9 : .5});
|
||
if (weather && !instant) this.weatherElem.animate({
|
||
opacity: 1.0
|
||
}, 400).animate({
|
||
opacity: isIntense ? 0.9 : .5
|
||
}, 400);
|
||
return;
|
||
}
|
||
if (oldweather) {
|
||
var self = this;
|
||
if (weather) {
|
||
this.weatherElem.animate({
|
||
opacity: 0
|
||
}, 300, function () {
|
||
self.weatherElem.attr('class', 'weather ' + weather + 'weather');
|
||
self.weatherElem.html('<em>' + weatherhtml + '</em>');
|
||
self.weatherElem.css({opacity: isIntense ? 0.9 : 0.5});
|
||
});
|
||
} else {
|
||
this.weatherElem.animate({
|
||
opacity: 0
|
||
}, 500, function () {
|
||
self.weatherElem.attr('class', 'weather');
|
||
self.weatherElem.html('<em>' + weatherhtml + '</em>');
|
||
self.weatherElem.css({opacity: 0.5});
|
||
});
|
||
}
|
||
} else if (weather) {
|
||
this.weatherElem.css({opacity: 0});
|
||
this.weatherElem.attr('class', 'weather ' + weather + 'weather');
|
||
this.weatherElem.html('<em>' + weatherhtml + '</em>');
|
||
this.weatherElem.animate({
|
||
opacity: 1.0
|
||
}, 400).animate({
|
||
opacity: isIntense ? 0.9 : .5
|
||
}, 400);
|
||
}
|
||
};
|
||
Battle.prototype.resultAnim = function (pokemon, result, type) {
|
||
if (this.fastForward) return;
|
||
if (type === 'ability') return this.abilityActivateAnim(pokemon, result);
|
||
this.fxElem.append('<div class="result ' + type + 'result"><strong>' + result + '</strong></div>');
|
||
var effectElem = this.fxElem.children().last();
|
||
effectElem.delay(this.animationDelay).css({
|
||
display: 'block',
|
||
opacity: 0,
|
||
top: pokemon.sprite.top - 5,
|
||
left: pokemon.sprite.left - 75
|
||
}).animate({
|
||
opacity: 1
|
||
}, 1);
|
||
effectElem.animate({
|
||
opacity: 0,
|
||
top: pokemon.sprite.top - 65
|
||
}, 1000, 'swing');
|
||
this.animationDelay += 350;
|
||
pokemon.side.updateStatbar(pokemon);
|
||
this.activityWait(effectElem);
|
||
};
|
||
Battle.prototype.abilityActivateAnim = function (pokemon, result) {
|
||
if (this.fastForward) return;
|
||
this.fxElem.append('<div class="result abilityresult"><strong>' + result + '</strong></div>');
|
||
var effectElem = this.fxElem.children().last();
|
||
effectElem.delay(this.animationDelay).css({
|
||
display: 'block',
|
||
opacity: 0,
|
||
top: pokemon.sprite.top + 15,
|
||
left: pokemon.sprite.left - 75
|
||
}).animate({
|
||
opacity: 1
|
||
}, 1);
|
||
effectElem.delay(800).animate({
|
||
opacity: 0
|
||
}, 400, 'swing');
|
||
this.animationDelay += 100;
|
||
pokemon.side.updateStatbar(pokemon);
|
||
this.activityWait(effectElem);
|
||
};
|
||
Battle.prototype.damageAnim = function (pokemon, damage) {
|
||
if (this.fastForward) return;
|
||
if (!pokemon.statbarElem) return;
|
||
pokemon.side.updateHPText(pokemon);
|
||
|
||
var $hp = pokemon.statbarElem.find('div.hp');
|
||
var w = pokemon.hpWidth(150);
|
||
var hpcolor = pokemon.getHPColor();
|
||
var callback;
|
||
if (hpcolor === 'y') callback = function () {
|
||
$hp.addClass('hp-yellow');
|
||
};
|
||
if (hpcolor === 'r') callback = function () {
|
||
$hp.addClass('hp-yellow hp-red');
|
||
};
|
||
|
||
this.resultAnim(pokemon, this.hardcoreMode ? 'Damage' : '−' + damage, 'bad');
|
||
|
||
$hp.animate({
|
||
width: w,
|
||
'border-right-width': w ? 1 : 0
|
||
}, 350, callback);
|
||
};
|
||
Battle.prototype.healAnim = function (pokemon, damage) {
|
||
if (this.fastForward) return;
|
||
if (!pokemon.statbarElem) return;
|
||
pokemon.side.updateHPText(pokemon);
|
||
|
||
var $hp = pokemon.statbarElem.find('div.hp');
|
||
var w = pokemon.hpWidth(150);
|
||
var hpcolor = pokemon.getHPColor();
|
||
var callback;
|
||
if (hpcolor === 'g') callback = function () {
|
||
$hp.removeClass('hp-yellow hp-red');
|
||
};
|
||
if (hpcolor === 'y') callback = function () {
|
||
$hp.removeClass('hp-red');
|
||
};
|
||
|
||
this.resultAnim(pokemon, this.hardcoreMode ? 'Heal' : '+' + damage, 'good');
|
||
|
||
$hp.animate({
|
||
width: w,
|
||
'border-right-width': w ? 1 : 0
|
||
}, 350, callback);
|
||
};
|
||
Battle.prototype.useMove = function (pokemon, move, target, kwargs) {
|
||
var fromeffect = Tools.getEffect(kwargs.from);
|
||
pokemon.clearMovestatuses();
|
||
if (move.id === 'focuspunch') {
|
||
pokemon.removeTurnstatus('focuspunch');
|
||
}
|
||
pokemon.side.updateStatbar(pokemon);
|
||
if (!target) {
|
||
target = pokemon.side.foe.active[0];
|
||
}
|
||
if (!target) {
|
||
target = pokemon.side.foe.missedPokemon;
|
||
}
|
||
if (!kwargs.silent) {
|
||
if (kwargs.zeffect) {
|
||
this.message('<small>' + pokemon.getName() + ' unleashes its full-force Z-Move!</small>', '');
|
||
}
|
||
switch (fromeffect.id) {
|
||
case 'snatch':
|
||
break;
|
||
case 'magicbounce':
|
||
case 'magiccoat':
|
||
case 'rebound':
|
||
if (fromeffect.id === 'magiccoat') {
|
||
this.resultAnim(pokemon, "Bounced", 'good');
|
||
pokemon.addTurnstatus('magiccoat');
|
||
} else {
|
||
this.resultAnim(pokemon, fromeffect.name, 'ability');
|
||
this.message('', "<small>[" + pokemon.getName(true) + "'s " + fromeffect.name + "!]</small>");
|
||
pokemon.markAbility(fromeffect.name);
|
||
}
|
||
this.message(pokemon.getName() + " bounced the " + move.name + " back!");
|
||
break;
|
||
case 'metronome':
|
||
this.message('Waggling a finger let it use <strong>' + move.name + '</strong>!');
|
||
break;
|
||
case 'naturepower':
|
||
this.message('Nature Power turned into <strong>' + move.name + '</strong>!');
|
||
break;
|
||
case 'weatherball':
|
||
this.message('Breakneck Blitz turned into <strong>' + move.name + '</strong> due to the weather!');
|
||
break;
|
||
case 'sleeptalk':
|
||
pokemon.markMove(move.name, 0);
|
||
this.message(pokemon.getName() + ' used <strong>' + move.name + '</strong>!');
|
||
break;
|
||
// Gen 1
|
||
case 'bind':
|
||
case 'clamp':
|
||
case 'firespin':
|
||
case 'wrap':
|
||
this.message(pokemon.getName() + "'s attack continues!");
|
||
break;
|
||
default:
|
||
// April Fool's 2014
|
||
if (window.Config && Config.server && Config.server.afd && move.id === 'earthquake') {
|
||
if (!this.fastForward) {
|
||
$('body').css({
|
||
position: 'absolute',
|
||
left: 0,
|
||
right: 0,
|
||
top: 0,
|
||
bottom: 0
|
||
}).animate({
|
||
left: -30,
|
||
right: 30
|
||
}, 75).animate({
|
||
left: 30,
|
||
right: -30
|
||
}, 100).animate({
|
||
left: -30,
|
||
right: 30
|
||
}, 100).animate({
|
||
left: 30,
|
||
right: -30
|
||
}, 100).animate({
|
||
left: 0,
|
||
right: 0
|
||
}, 100, function () {
|
||
$(this).css({
|
||
position: 'static'
|
||
});
|
||
});
|
||
}
|
||
this.message(pokemon.getName() + ' used <strong>Fissure</strong>!');
|
||
this.message('Just kidding! It was <strong>Earthquake</strong>!');
|
||
} else if (window.Config && Config.server && Config.server.afd && move.id === 'stealthrock') {
|
||
var srNames = ['Sneaky Pebbles', 'Sly Rubble', 'Subtle Sediment', 'Buried Bedrock', 'Camouflaged Cinnabar', 'Clandestine Cobblestones', 'Cloaked Clay', 'Concealed Ore', 'Covert Crags', 'Crafty Coal', 'Discreet Bricks', 'Disguised Debris', 'Espionage Pebbles', 'Furtive Fortress', 'Hush-Hush Hardware', 'Incognito Boulders', 'Invisible Quartz', 'Masked Minerals', 'Mischievous Masonry', 'Obscure Ornaments', 'Private Paragon', 'Secret Solitaire', 'Sheltered Sand', 'Surreptitious Sapphire', 'Undercover Ultramarine'];
|
||
this.message(pokemon.getName() + ' used <strong>' + srNames[Math.floor(Math.random() * srNames.length)] + '</strong>!');
|
||
// } else if (window.Config && Config.server && Config.server.afd && (move.id === 'metronome' || move.id === 'sleeptalk' || move.id === 'assist')) {
|
||
// this.message(pokemon.getName() + ' used <strong>' + move.name + '</strong>!');
|
||
// var buttons = ["A", "B", "START", "SELECT", "UP", "DOWN", "LEFT", "RIGHT", "DEMOCRACY", "ANARCHY"];
|
||
// var people = ["Zarel", "The Immortal", "Diatom", "Nani Man", "shaymin", "apt-get", "sirDonovan", "Arcticblast", "Trickster"];
|
||
// var button;
|
||
// for (var i = 0; i < 10; i++) {
|
||
// var name = people[Math.floor(Math.random() * people.length)];
|
||
// if (!button) button = buttons[Math.floor(Math.random() * buttons.length)];
|
||
// this.log('<div class="chat"><strong style="' + hashColor(toUserid(name)) + '" class="username" data-name="' + Tools.escapeHTML(name) + '">' + Tools.escapeHTML(name) + ':</strong> <em>' + button + '</em></div>');
|
||
// button = (name === 'Diatom' ? "thanks diatom" : null);
|
||
// }
|
||
} else {
|
||
this.message(pokemon.getName() + ' used <strong>' + move.name + '</strong>!');
|
||
}
|
||
if (!fromeffect.id || fromeffect.id === 'pursuit') {
|
||
var pp = (target && target.side !== pokemon.side && toId(target.ability) === 'pressure' ? 2 : 1);
|
||
pokemon.markMove(move.name, pp);
|
||
}
|
||
break;
|
||
}
|
||
if (window.Config && Config.server && Config.server.afd && move.id === 'taunt') {
|
||
var quotes = [
|
||
"Yo mama so fat, she 4x resists Ice- and Fire-type attacks!",
|
||
"Yo mama so ugly, Captivate raises her opponent's Special Attack!",
|
||
"Yo mama so dumb, she lowers her Special Attack when she uses Nasty Plot!",
|
||
"Yo mama so dumb, she thought Sylveon would be Light Type!"
|
||
];
|
||
var quote = quotes[(this.p1.name.charCodeAt(2) + this.p2.name.charCodeAt(2) + this.turn) % quotes.length];
|
||
this.message(pokemon.getName() + " said, \"" + quote + "\"");
|
||
}
|
||
}
|
||
if (!this.fastForward && !kwargs.still) {
|
||
// skip
|
||
if (kwargs.miss && target.side) {
|
||
target = target.side.missedPokemon;
|
||
}
|
||
if (kwargs.notarget || !target || !target.sprite.elem) {
|
||
target = pokemon.side.foe.missedPokemon;
|
||
}
|
||
if (kwargs.prepare || kwargs.anim === 'prepare') {
|
||
this.prepareMove(pokemon, move, target);
|
||
} else if (!kwargs.notarget) {
|
||
var usedMove = kwargs.anim ? Tools.getMove(kwargs.anim) : move;
|
||
if (kwargs.spread) {
|
||
this.activeMoveIsSpread = kwargs.spread;
|
||
var targets = [pokemon.sprite];
|
||
var hitPokemon = kwargs.spread.split(',');
|
||
if (hitPokemon[0] !== '.') {
|
||
for (var i = hitPokemon.length - 1; i >= 0; i--) {
|
||
targets.push(this.getPokemon(hitPokemon[i] + ': ?').sprite);
|
||
}
|
||
} else {
|
||
// if hitPokemon[0] === '.' then no target was hit by the attack
|
||
targets.push(target.sprite.elem ? target.side.missedPokemon.sprite : target.sprite);
|
||
}
|
||
|
||
usedMove.anim(this, targets);
|
||
} else {
|
||
usedMove.anim(this, [pokemon.sprite, target.sprite]);
|
||
}
|
||
}
|
||
}
|
||
pokemon.lastmove = move.id;
|
||
this.lastmove = move.id;
|
||
if (move.id === 'wish' || move.id === 'healingwish') {
|
||
pokemon.side.wisher = pokemon;
|
||
}
|
||
};
|
||
Battle.prototype.cantUseMove = function (pokemon, effect, move, kwargs) {
|
||
pokemon.clearMovestatuses();
|
||
pokemon.side.updateStatbar(pokemon);
|
||
if (window.BattleStatusAnims && effect.id in BattleStatusAnims && !this.fastForward) {
|
||
BattleStatusAnims[effect.id].anim(this, [pokemon.sprite]);
|
||
}
|
||
if (effect.effectType === 'Ability') {
|
||
this.resultAnim(pokemon, effect.name, 'ability');
|
||
this.message('', "<small>[" + pokemon.getName(true) + "'s " + effect.name + "!]</small>");
|
||
pokemon.markAbility(effect.name);
|
||
}
|
||
switch (effect.id) {
|
||
case 'taunt':
|
||
this.message('' + pokemon.getName() + ' can\'t use ' + move.name + ' after the taunt!');
|
||
pokemon.markMove(move.name, 0);
|
||
break;
|
||
case 'gravity':
|
||
this.message('' + pokemon.getName() + ' can\'t use ' + move.name + ' because of gravity!');
|
||
pokemon.markMove(move.name, 0);
|
||
break;
|
||
case 'healblock':
|
||
this.message('' + pokemon.getName() + ' can\'t use ' + move.name + ' because of Heal Block!');
|
||
pokemon.markMove(move.name, 0);
|
||
break;
|
||
case 'imprison':
|
||
this.message('' + pokemon.getName() + ' can\'t use its sealed ' + move.name + '!');
|
||
pokemon.markMove(move.name, 0);
|
||
break;
|
||
case 'throatchop':
|
||
this.message('The effects of Throat Chop prevent ' + pokemon.getName() + ' from using certain moves!');
|
||
break;
|
||
case 'par':
|
||
this.resultAnim(pokemon, 'Paralyzed', 'par');
|
||
this.message('' + pokemon.getName() + ' is paralyzed! It can\'t move!');
|
||
break;
|
||
case 'frz':
|
||
this.resultAnim(pokemon, 'Frozen', 'frz');
|
||
this.message('' + pokemon.getName() + ' is frozen solid!');
|
||
break;
|
||
case 'slp':
|
||
this.resultAnim(pokemon, 'Asleep', 'slp');
|
||
this.message('' + pokemon.getName() + ' is fast asleep.');
|
||
break;
|
||
case 'skydrop':
|
||
this.message('Sky Drop won\'t let ' + pokemon.getLowerName() + ' go!');
|
||
break;
|
||
case 'damp':
|
||
case 'dazzling':
|
||
case 'queenlymajesty':
|
||
var ofpoke = this.getPokemon(kwargs.of);
|
||
this.message(ofpoke.getName() + ' cannot use ' + move.name + '!');
|
||
break;
|
||
case 'truant':
|
||
this.resultAnim(pokemon, 'Loafing around', 'neutral');
|
||
this.message('' + pokemon.getName() + ' is loafing around!');
|
||
break;
|
||
case 'recharge':
|
||
if (!this.fastForward) BattleOtherAnims['selfstatus'].anim(this, [pokemon.sprite]);
|
||
this.resultAnim(pokemon, 'Must recharge', 'neutral');
|
||
this.message('<small>' + pokemon.getName() + ' must recharge!</small>');
|
||
break;
|
||
case 'focuspunch':
|
||
this.resultAnim(pokemon, 'Lost focus', 'neutral');
|
||
this.message(pokemon.getName() + ' lost its focus and couldn\'t move!');
|
||
pokemon.removeTurnstatus('focuspunch');
|
||
break;
|
||
case 'shelltrap':
|
||
this.resultAnim(pokemon, 'Trap failed', 'neutral');
|
||
this.message(pokemon.getName() + '\'s shell trap didn\'t work!');
|
||
pokemon.removeTurnstatus('shelltrap');
|
||
break;
|
||
case 'flinch':
|
||
this.resultAnim(pokemon, 'Flinched', 'neutral');
|
||
this.message(pokemon.getName() + ' flinched and couldn\'t move!');
|
||
pokemon.removeTurnstatus('focuspunch');
|
||
break;
|
||
case 'attract':
|
||
this.resultAnim(pokemon, 'Immobilized', 'neutral');
|
||
this.message(pokemon.getName() + ' is immobilized by love!');
|
||
break;
|
||
case 'nopp':
|
||
this.message(pokemon.getName() + ' used <strong>' + move.name + '</strong>!');
|
||
this.message('But there was no PP left for the move!');
|
||
break;
|
||
default:
|
||
this.message('<small>' + pokemon.getName() + (move.name ? ' can\'t use ' + move.name + '' : ' can\'t move') + '!</small>');
|
||
break;
|
||
}
|
||
pokemon.sprite.animReset();
|
||
};
|
||
Battle.prototype.prepareMove = function (pokemon, move, target) {
|
||
if (!move.prepareAnim) return;
|
||
if (!target) {
|
||
target = pokemon.side.foe.active[0];
|
||
}
|
||
if (!target) {
|
||
target = pokemon;
|
||
}
|
||
if (!this.fastForward) move.prepareAnim(this, [pokemon.sprite, target.sprite]);
|
||
this.message('<small>' + move.prepareMessage(pokemon, target) + '</small>');
|
||
};
|
||
Battle.prototype.animMultiHitMove = function () {
|
||
if (this.multiHitMove && !this.fastForward) {
|
||
this.multiHitMove[0].anim(this, [this.multiHitMove[1], this.multiHitMove[2]]);
|
||
this.multiHitMove[3]++;
|
||
this.animationDelay += 500;
|
||
}
|
||
};
|
||
Battle.prototype.runMinor = function (args, kwargs, preempt, nextArgs, nextKwargs) {
|
||
var actions = '';
|
||
var minors = this.minorQueue;
|
||
if (this.multiHitMove && minors.length) {
|
||
var lastMinor = minors[minors.length - 1];
|
||
//if (lastMinor[0][0] === '-damage' || lastMinor[0][1]['subdamage']) this.animMultiHitMove();
|
||
}
|
||
if (args) {
|
||
if (args[2] === 'Sturdy' && args[0] === '-activate') args[2] = 'ability: Sturdy';
|
||
if (args[0] === '-crit' || args[0] === '-supereffective' || args[0] === '-resisted' || args[2] === 'ability: Sturdy') kwargs.then = '.';
|
||
if (args[0] === '-damage' && !kwargs.from && args[1] !== nextArgs[1] && (nextArgs[0] === '-crit' || nextArgs[0] === '-supereffective' || nextArgs[0] === '-resisted' || (nextArgs[0] === '-damage' && !nextKwargs.from))) kwargs.then = '.';
|
||
if (args[0] === '-ability' && (args[2] === 'Intimidate' || args[3] === 'boost')) kwargs.then = '.';
|
||
if (args[0] === '-unboost' && nextArgs[0] === '-unboost') kwargs.then = '.';
|
||
if (args[0] === '-boost' && nextArgs[0] === '-boost') kwargs.then = '.';
|
||
if (args[0] === '-damage' && kwargs.from === 'Leech Seed' && nextArgs[0] === '-heal' && nextKwargs.silent) kwargs.then = '.';
|
||
minors.push([args, kwargs]);
|
||
if (kwargs.simult || kwargs.then) {
|
||
return;
|
||
}
|
||
}
|
||
while (minors.length) {
|
||
var row = minors.shift();
|
||
args = row[0];
|
||
kwargs = row[1];
|
||
if (kwargs.simult) this.animationDelay = 0;
|
||
|
||
switch (args[0]) {
|
||
case '-center':
|
||
actions += "Automatic center!";
|
||
break;
|
||
case '-damage':
|
||
var poke = this.getPokemon(args[1]);
|
||
var damage = poke.healthParse(args[2], true);
|
||
if (damage === false) break;
|
||
this.lastDamage = (damage[2] || 1); // not sure if this is used for anything
|
||
var range = poke.getDamageRange(damage);
|
||
|
||
if (kwargs.silent) {
|
||
// do nothing
|
||
} else if (kwargs.from) {
|
||
var effect = Tools.getEffect(kwargs.from);
|
||
var ofpoke = this.getPokemon(kwargs.of);
|
||
if (effect.effectType === 'Ability' && ofpoke) {
|
||
this.resultAnim(ofpoke, effect.name, 'ability');
|
||
this.message('', "<small>[" + ofpoke.getName(true) + "'s " + effect.name + "!]</small>");
|
||
ofpoke.markAbility(effect.name);
|
||
} else if (effect.effectType === 'Item') {
|
||
(ofpoke || poke).item = effect.name;
|
||
}
|
||
switch (effect.id) {
|
||
case 'stealthrock':
|
||
actions += "Pointed stones dug into " + poke.getLowerName() + "!";
|
||
break;
|
||
case 'spikes':
|
||
actions += "" + poke.getName() + " is hurt by the spikes!";
|
||
break;
|
||
case 'brn':
|
||
if (!this.fastForward) BattleStatusAnims['brn'].anim(this, [poke.sprite]);
|
||
actions += "" + poke.getName() + " was hurt by its burn!";
|
||
break;
|
||
case 'psn':
|
||
if (!this.fastForward) BattleStatusAnims['psn'].anim(this, [poke.sprite]);
|
||
actions += "" + poke.getName() + " was hurt by poison!";
|
||
break;
|
||
case 'lifeorb':
|
||
this.message('', '<small>' + poke.getName() + ' lost some of its HP!</small>');
|
||
break;
|
||
case 'recoil':
|
||
actions += "" + poke.getName() + " is damaged by the recoil!";
|
||
break;
|
||
case 'sandstorm':
|
||
actions += "" + poke.getName() + " is buffeted by the sandstorm!";
|
||
break;
|
||
case 'hail':
|
||
actions += "" + poke.getName() + " is buffeted by the hail!";
|
||
break;
|
||
case 'baddreams':
|
||
actions += "" + poke.getName() + " is tormented!";
|
||
break;
|
||
case 'curse':
|
||
actions += "" + poke.getName() + " is afflicted by the curse!";
|
||
break;
|
||
case 'nightmare':
|
||
actions += "" + poke.getName() + " is locked in a nightmare!";
|
||
break;
|
||
case 'roughskin':
|
||
case 'ironbarbs':
|
||
case 'spikyshield':
|
||
actions += "" + poke.getName() + " was hurt!";
|
||
break;
|
||
case 'innardsout':
|
||
case 'aftermath':
|
||
actions += "" + poke.getName() + " is hurt!";
|
||
break;
|
||
case 'liquidooze':
|
||
actions += "" + poke.getName() + " sucked up the liquid ooze!";
|
||
break;
|
||
case 'dryskin':
|
||
case 'solarpower':
|
||
break;
|
||
case 'confusion':
|
||
actions += "It hurt itself in its confusion! ";
|
||
poke.sprite.animReset();
|
||
break;
|
||
case 'leechseed':
|
||
if (!this.fastForward) {
|
||
BattleOtherAnims.leech.anim(this, [ofpoke.sprite, poke.sprite]);
|
||
// this.activityWait(500);
|
||
}
|
||
actions += "" + poke.getName() + "'s health is sapped by Leech Seed!";
|
||
break;
|
||
case 'flameburst':
|
||
actions += "The bursting flame hit " + poke.getLowerName() + "!";
|
||
break;
|
||
case 'firepledge':
|
||
actions += "" + poke.getName() + " is hurt by the sea of fire!";
|
||
break;
|
||
case 'jumpkick':
|
||
case 'highjumpkick':
|
||
actions += "" + poke.getName() + " kept going and crashed!";
|
||
break;
|
||
case 'bind':
|
||
case 'wrap':
|
||
if (!this.fastForward) BattleOtherAnims.bound.anim(this, [poke.sprite]);
|
||
actions += "" + poke.getName() + ' is hurt by ' + effect.name + '!';
|
||
break;
|
||
default:
|
||
if (ofpoke) {
|
||
actions += "" + poke.getName() + " is hurt by " + ofpoke.getLowerName() + "'s " + effect.name + "!";
|
||
} else if (effect.effectType === 'Item') {
|
||
actions += "" + poke.getName() + " is hurt by its " + effect.name + "!";
|
||
} else if (effect.effectType === 'Ability') {
|
||
actions += "" + poke.getName() + " is hurt by its " + effect.name + "!";
|
||
} else if (kwargs.partiallytrapped) {
|
||
actions += "" + poke.getName() + ' is hurt by ' + effect.name + '!';
|
||
} else {
|
||
actions += "" + poke.getName() + " lost some HP because of " + effect.name + "!";
|
||
}
|
||
break;
|
||
}
|
||
} else {
|
||
var damageinfo = '' + poke.getFormattedRange(range, damage[1] === 100 ? 0 : 1, '–');
|
||
if (damage[1] !== 100) {
|
||
var hover = '' + ((damage[0] < 0) ? '−' : '') +
|
||
Math.abs(damage[0]) + '/' + damage[1];
|
||
if (damage[1] === 48) { // this is a hack
|
||
hover += ' pixels';
|
||
}
|
||
damageinfo = '<abbr title="' + hover + '">' + damageinfo + '</abbr>';
|
||
}
|
||
var hiddenactions = '<small>' + poke.getName() + ' lost ' + damageinfo + ' of its health!</small><br />';
|
||
this.message(actions ? '<small>' + actions + '</small>' : '', hiddenactions);
|
||
actions = '';
|
||
}
|
||
this.damageAnim(poke, poke.getFormattedRange(range, 0, ' to '));
|
||
break;
|
||
case '-heal':
|
||
var poke = this.getPokemon(args[1]);
|
||
var damage = poke.healthParse(args[2], true, true);
|
||
if (damage === false) break;
|
||
var range = poke.getDamageRange(damage);
|
||
|
||
if (kwargs.silent) {
|
||
// do nothing
|
||
} else if (kwargs.from) {
|
||
var effect = Tools.getEffect(kwargs.from);
|
||
var ofpoke = this.getPokemon(kwargs.of);
|
||
if (effect.effectType === 'Ability') {
|
||
this.resultAnim(poke, effect.name, 'ability');
|
||
this.message('', "<small>[" + poke.getName(true) + "'s " + effect.name + "!]</small>");
|
||
poke.markAbility(effect.name);
|
||
}
|
||
switch (effect.id) {
|
||
case 'memento':
|
||
case 'partingshot':
|
||
actions += "" + poke.getName() + "'s HP was restored by the Z-Power!";
|
||
break;
|
||
case 'ingrain':
|
||
actions += "" + poke.getName() + " absorbed nutrients with its roots!";
|
||
break;
|
||
case 'aquaring':
|
||
actions += "A veil of water restored " + poke.getLowerName() + "'s HP!";
|
||
break;
|
||
case 'healingwish':
|
||
actions += "The healing wish came true for " + poke.getLowerName() + "!";
|
||
this.lastmove = 'healing-wish';
|
||
Tools.getMove('healingwish').residualAnim(this, [poke.sprite]);
|
||
poke.side.wisher = null;
|
||
break;
|
||
case 'lunardance':
|
||
actions += "" + poke.getName() + " became cloaked in mystical moonlight!";
|
||
this.lastmove = 'healing-wish';
|
||
Tools.getMove('healingwish').residualAnim(this, [poke.sprite]);
|
||
for (var i = 0; i < poke.moveTrack.length; i++) {
|
||
poke.moveTrack[i][1] = 0;
|
||
}
|
||
poke.side.wisher = null;
|
||
break;
|
||
case 'wish':
|
||
actions += "" + kwargs.wisher + "'s wish came true!";
|
||
if (!this.fastForward) this.backgroundEffect("url('fx/bg-space.jpg')", 600, 0.4);
|
||
Tools.getMove('wish').residualAnim(this, [poke.sprite]);
|
||
this.animationDelay += 500;
|
||
break;
|
||
case 'drain':
|
||
actions += ofpoke.getName() + ' had its energy drained!';
|
||
break;
|
||
case 'leftovers':
|
||
case 'shellbell':
|
||
case 'blacksludge':
|
||
poke.item = effect.name;
|
||
actions += "" + poke.getName() + " restored a little HP using its " + effect.name + "!";
|
||
break;
|
||
default:
|
||
if (kwargs.absorb) {
|
||
actions += "" + poke.getName() + "'s " + effect.name + " absorbs the attack!";
|
||
} else if (effect.id && effect.effectType !== 'Ability') {
|
||
actions += "" + poke.getName() + " restored HP using its " + effect.name + "!";
|
||
} else {
|
||
actions += poke.getName() + ' restored its HP.';
|
||
}
|
||
break;
|
||
}
|
||
} else if (kwargs.zeffect) {
|
||
actions += "" + poke.getName() + " restored its HP using its Z-Power!";
|
||
} else {
|
||
actions += poke.getName() + ' restored its HP.';
|
||
}
|
||
if (!this.fastForward) BattleOtherAnims.heal.anim(this, [poke.sprite]);
|
||
this.healAnim(poke, poke.getFormattedRange(range, 0, ' to '));
|
||
break;
|
||
case '-sethp':
|
||
var effect = Tools.getEffect(kwargs.from);
|
||
var poke, ofpoke;
|
||
for (var k = 0; k < 2; k++) {
|
||
var cpoke = this.getPokemon(args[1 + 2 * k]);
|
||
if (cpoke) {
|
||
var damage = cpoke.healthParse(args[2 + 2 * k]);
|
||
var range = cpoke.getDamageRange(damage);
|
||
var formattedRange = cpoke.getFormattedRange(range, 0, ' to ');
|
||
var diff = damage[0];
|
||
if (diff > 0) {
|
||
this.healAnim(cpoke, formattedRange);
|
||
} else {
|
||
this.damageAnim(cpoke, formattedRange);
|
||
}
|
||
}
|
||
if (k == 0) poke = cpoke;
|
||
if (k == 1) ofpoke = cpoke;
|
||
}
|
||
switch (effect.id) {
|
||
case 'painsplit':
|
||
actions += 'The battlers shared their pain!';
|
||
break;
|
||
}
|
||
|
||
break;
|
||
|
||
case '-boost':
|
||
var poke = this.getPokemon(args[1]);
|
||
var stat = args[2];
|
||
if (this.gen === 1 && stat === 'spd') break;
|
||
if (this.gen === 1 && stat === 'spa') stat = 'spc';
|
||
var amount = parseInt(args[3], 10);
|
||
if (amount === 0) {
|
||
actions += "" + poke.getName() + "'s " + BattleStats[stat] + " won't go any higher! ";
|
||
this.resultAnim(poke, 'Highest ' + BattleStats[stat], 'good');
|
||
break;
|
||
}
|
||
if (!poke.boosts[stat]) {
|
||
poke.boosts[stat] = 0;
|
||
}
|
||
poke.boosts[stat] += amount;
|
||
|
||
var amountString = '';
|
||
if (amount === 2) amountString = ' sharply';
|
||
if (amount >= 3) amountString = ' drastically';
|
||
if (kwargs.silent) {
|
||
// do nothing
|
||
} else if (kwargs.from) {
|
||
var effect = Tools.getEffect(kwargs.from);
|
||
var ofpoke = this.getPokemon(kwargs.of);
|
||
if (effect.effectType === 'Ability' && !(effect.id === 'weakarmor' && stat === 'spe')) {
|
||
this.resultAnim(ofpoke || poke, effect.name, 'ability');
|
||
this.message('', "<small>[" + (ofpoke || poke).getName(true) + "'s " + effect.name + "!]</small>");
|
||
poke.markAbility(effect);
|
||
}
|
||
switch (effect.id) {
|
||
default:
|
||
if (effect.effectType === 'Ability') {
|
||
actions += "" + poke.getName() + "'s " + BattleStats[stat] + " rose" + amountString + "! ";
|
||
}
|
||
if (effect.effectType === 'Item') {
|
||
actions += "The " + effect.name + amountString + " raised " + poke.getLowerName() + "'s " + BattleStats[stat] + "! ";
|
||
}
|
||
break;
|
||
}
|
||
} else if (kwargs.zeffect) {
|
||
if (minors.length) {
|
||
actions += "" + poke.getName() + " boosted its stats" + amountString + " using its Z-Power! ";
|
||
for (var i = 0; i < minors.length; i++) {
|
||
minors[i][1].silent = '.';
|
||
}
|
||
} else {
|
||
actions += "" + poke.getName() + " boosted its " + BattleStats[stat] + amountString + " using its Z-Power! ";
|
||
}
|
||
} else {
|
||
actions += "" + poke.getName() + "'s " + BattleStats[stat] + " rose" + amountString + "! ";
|
||
}
|
||
this.resultAnim(poke, poke.getBoost(stat), 'good');
|
||
break;
|
||
case '-unboost':
|
||
var poke = this.getPokemon(args[1]);
|
||
var stat = args[2];
|
||
if (this.gen === 1 && stat === 'spd') break;
|
||
if (this.gen === 1 && stat === 'spa') stat = 'spc';
|
||
var amount = parseInt(args[3], 10);
|
||
if (amount === 0) {
|
||
actions += "" + poke.getName() + "'s " + BattleStats[stat] + " won't go any lower! ";
|
||
this.resultAnim(poke, 'Lowest ' + BattleStats[stat], 'bad');
|
||
break;
|
||
}
|
||
if (!poke.boosts[stat]) {
|
||
poke.boosts[stat] = 0;
|
||
}
|
||
poke.boosts[stat] -= amount;
|
||
|
||
var amountString = '';
|
||
if (amount === 2) amountString = ' harshly';
|
||
if (amount >= 3) amountString = ' severely';
|
||
if (kwargs.silent) {
|
||
// do nothing
|
||
} else if (kwargs.from) {
|
||
var effect = Tools.getEffect(kwargs.from);
|
||
var ofpoke = this.getPokemon(kwargs.of);
|
||
if (effect.effectType === 'Ability') {
|
||
this.resultAnim(ofpoke || poke, effect.name, 'ability');
|
||
this.message('', "<small>[" + (ofpoke || poke).getName(true) + "'s " + effect.name + "!]</small>");
|
||
poke.markAbility(effect);
|
||
}
|
||
switch (effect.id) {
|
||
default:
|
||
if (effect.effectType === 'Ability') {
|
||
actions += "" + poke.getName() + "'s " + BattleStats[stat] + " fell" + amountString + "! ";
|
||
}
|
||
if (effect.effectType === 'Item') {
|
||
actions += "The " + effect.name + amountString + " lowered " + poke.getLowerName() + "'s " + BattleStats[stat] + "! ";
|
||
}
|
||
break;
|
||
}
|
||
} else {
|
||
actions += "" + poke.getName() + "'s " + BattleStats[stat] + " fell" + amountString + "! ";
|
||
}
|
||
this.resultAnim(poke, poke.getBoost(stat), 'bad');
|
||
break;
|
||
case '-setboost':
|
||
var poke = this.getPokemon(args[1]);
|
||
var stat = args[2];
|
||
var amount = parseInt(args[3], 10);
|
||
var effect = Tools.getEffect(kwargs.from);
|
||
var ofpoke = this.getPokemon(kwargs.of);
|
||
poke.boosts[stat] = amount;
|
||
this.resultAnim(poke, poke.getBoost(stat), (amount > 0 ? 'good' : 'bad'));
|
||
|
||
if (kwargs.silent) {
|
||
// do nothing
|
||
} else if (kwargs.from) {
|
||
switch (effect.id) {
|
||
case 'bellydrum':
|
||
actions += '' + poke.getName() + ' cut its own HP and maximized its Attack!';
|
||
break;
|
||
case 'angerpoint':
|
||
if (!this.fastForward) BattleOtherAnims.anger.anim(this, [poke.sprite]);
|
||
this.resultAnim(poke, 'Anger Point', 'ability');
|
||
this.message('', "<small>[" + poke.getName(true) + "'s Anger Point!]</small>");
|
||
poke.markAbility('Anger Point');
|
||
actions += '' + poke.getName() + ' maxed its Attack!';
|
||
break;
|
||
}
|
||
}
|
||
break;
|
||
case '-swapboost':
|
||
var poke = this.getPokemon(args[1]);
|
||
var poke2 = this.getPokemon(args[2]);
|
||
var stats = args[3] ? args[3].split(', ') : ['atk', 'def', 'spa', 'spd', 'spe', 'accuracy', 'evasion'];
|
||
var effect = Tools.getEffect(kwargs.from);
|
||
for (var i = 0; i < stats.length; i++) {
|
||
var tmp = poke.boosts[stats[i]];
|
||
poke.boosts[stats[i]] = poke2.boosts[stats[i]];
|
||
if (!poke.boosts[stats[i]]) delete poke.boosts[stats[i]];
|
||
poke2.boosts[stats[i]] = tmp;
|
||
if (!poke2.boosts[stats[i]]) delete poke2.boosts[stats[i]];
|
||
}
|
||
this.resultAnim(poke, 'Stats swapped', 'neutral', true);
|
||
this.resultAnim(poke2, 'Stats swapped', 'neutral');
|
||
|
||
if (kwargs.silent) {
|
||
// do nothing
|
||
} else if (effect.id) {
|
||
switch (effect.id) {
|
||
case 'guardswap':
|
||
actions += '' + poke.getName() + ' switched all changes to its Defense and Sp. Def with its target!';
|
||
break;
|
||
case 'heartswap':
|
||
actions += '' + poke.getName() + ' switched stat changes with its target!';
|
||
break;
|
||
case 'powerswap':
|
||
actions += '' + poke.getName() + ' switched all changes to its Attack and Sp. Atk with its target!';
|
||
break;
|
||
}
|
||
}
|
||
break;
|
||
case '-clearpositiveboost':
|
||
var poke = this.getPokemon(args[1]);
|
||
var ofpoke = this.getPokemon(args[2]);
|
||
var effect = Tools.getEffect(args[3]);
|
||
for (i in poke.boosts) {
|
||
if (poke.boosts[i] > 0) delete poke.boosts[i];
|
||
}
|
||
this.resultAnim(poke, 'Boosts lost', 'bad');
|
||
|
||
if (kwargs.silent) {
|
||
// do nothing
|
||
} else if (effect.id) {
|
||
switch (effect.id) {
|
||
case 'spectralthief':
|
||
// todo: update StealBoosts so it animates 1st on Spectral Thief
|
||
if (!this.fastForward) BattleOtherAnims.spectralthiefboost.anim(this, [ofpoke.sprite, poke.sprite]);
|
||
actions += '' + ofpoke.getName() + ' stole the target\'s boosted stats!';
|
||
break;
|
||
}
|
||
}
|
||
break;
|
||
case '-clearnegativeboost':
|
||
var poke = this.getPokemon(args[1]);
|
||
for (i in poke.boosts) {
|
||
if (poke.boosts[i] < 0) delete poke.boosts[i];
|
||
}
|
||
this.resultAnim(poke, 'Restored', 'good');
|
||
|
||
if (kwargs.silent) {
|
||
// do nothing
|
||
} else if (kwargs.zeffect) {
|
||
actions += '' + poke.getName() + ' returned its decreased stats to normal using its Z-Power!';
|
||
break;
|
||
}
|
||
break;
|
||
case '-copyboost':
|
||
var poke = this.getPokemon(args[1]);
|
||
var frompoke = this.getPokemon(args[2]);
|
||
var stats = args[3] ? args[3].split(', ') : ['atk', 'def', 'spa', 'spd', 'spe', 'accuracy', 'evasion'];
|
||
var effect = Tools.getEffect(kwargs.from);
|
||
for (var i = 0; i < stats.length; i++) {
|
||
poke.boosts[stats[i]] = frompoke.boosts[stats[i]];
|
||
if (!poke.boosts[stats[i]]) delete poke.boosts[stats[i]];
|
||
}
|
||
//poke.boosts = $.extend({}, frompoke.boosts);
|
||
|
||
if (kwargs.silent) {
|
||
// do nothing
|
||
} else {
|
||
this.resultAnim(poke, 'Stats copied', 'neutral');
|
||
actions += "" + poke.getName() + " copied " + frompoke.getLowerName() + "'s stat changes!";
|
||
}
|
||
break;
|
||
case '-clearboost':
|
||
var poke = this.getPokemon(args[1]);
|
||
poke.boosts = {};
|
||
this.resultAnim(poke, 'Stats reset', 'neutral');
|
||
|
||
if (kwargs.silent) {
|
||
// do nothing
|
||
} else {
|
||
actions += '' + poke.getName() + '\'s stat changes were removed!';
|
||
}
|
||
break;
|
||
case '-invertboost':
|
||
var poke = this.getPokemon(args[1]);
|
||
for (i in poke.boosts) {
|
||
poke.boosts[i] = -poke.boosts[i];
|
||
}
|
||
this.resultAnim(poke, 'Stats inverted', 'neutral');
|
||
|
||
if (kwargs.silent) {
|
||
// do nothing
|
||
} else {
|
||
actions += '' + poke.getName() + '\'s stat changes were inverted!';
|
||
}
|
||
break;
|
||
case '-clearallboost':
|
||
for (var slot = 0; slot < this.mySide.active.length; slot++) {
|
||
if (this.mySide.active[slot]) {
|
||
this.mySide.active[slot].boosts = {};
|
||
this.resultAnim(this.mySide.active[slot], 'Stats reset', 'neutral', true);
|
||
}
|
||
if (this.yourSide.active[slot]) {
|
||
this.yourSide.active[slot].boosts = {};
|
||
this.resultAnim(this.yourSide.active[slot], 'Stats reset', 'neutral', true);
|
||
}
|
||
}
|
||
|
||
if (kwargs.silent) {
|
||
// do nothing
|
||
} else {
|
||
actions += 'All stat changes were eliminated!';
|
||
}
|
||
break;
|
||
|
||
case '-crit':
|
||
var poke = this.getPokemon(args[1]);
|
||
for (var j = 1; !poke && j < 10; j++) poke = this.getPokemon(minors[i + j][0][1]);
|
||
if (poke) this.resultAnim(poke, 'Critical hit', 'bad');
|
||
actions += "A critical hit" + (this.activeMoveIsSpread ? " on " + poke.getLowerName() : "") + "! ";
|
||
break;
|
||
|
||
case '-supereffective':
|
||
var poke = this.getPokemon(args[1]);
|
||
for (var j = 1; !poke && j < 10; j++) poke = this.getPokemon(minors[i + j][0][1]);
|
||
if (poke) this.resultAnim(poke, 'Super-effective', 'bad');
|
||
actions += "It's super effective" + (this.activeMoveIsSpread ? " on " + poke.getLowerName() : "") + "! ";
|
||
break;
|
||
|
||
case '-resisted':
|
||
var poke = this.getPokemon(args[1]);
|
||
for (var j = 1; !poke && j < 10; j++) poke = this.getPokemon(minors[i + j][0][1]);
|
||
if (poke) this.resultAnim(poke, 'Resisted', 'neutral');
|
||
actions += "It's not very effective" + (this.activeMoveIsSpread ? " on " + poke.getLowerName() : "..") + ". ";
|
||
break;
|
||
|
||
case '-immune':
|
||
var poke = this.getPokemon(args[1]);
|
||
var effect = Tools.getEffect(args[2]);
|
||
var fromeffect = Tools.getEffect(kwargs.from);
|
||
if (fromeffect && fromeffect.effectType === 'Ability') {
|
||
var ofpoke = this.getPokemon(kwargs.of) || poke;
|
||
this.resultAnim(ofpoke, fromeffect.name, 'ability');
|
||
this.message('', "<small>[" + ofpoke.getName(true) + "'s " + fromeffect.name + "!]</small>");
|
||
ofpoke.markAbility(fromeffect.name);
|
||
}
|
||
if (effect.id == 'confusion') {
|
||
actions += "" + poke.getName() + " doesn't become confused! ";
|
||
} else if (kwargs.msg) {
|
||
actions += "It doesn't affect " + poke.getLowerName() + "... ";
|
||
} else if (kwargs.ohko) {
|
||
actions += "" + poke.getName() + " is unaffected! ";
|
||
} else {
|
||
actions += "It had no effect! ";
|
||
}
|
||
this.resultAnim(poke, 'Immune', 'neutral');
|
||
break;
|
||
|
||
case '-miss':
|
||
var user = this.getPokemon(args[1]);
|
||
var target = this.getPokemon(args[2]);
|
||
if (target) {
|
||
actions += "" + target.getName() + " avoided the attack!";
|
||
this.resultAnim(target, 'Missed', 'neutral');
|
||
} else {
|
||
actions += "" + user.getName() + "'s attack missed!";
|
||
}
|
||
break;
|
||
|
||
case '-fail':
|
||
var poke = this.getPokemon(args[1]);
|
||
var effect = Tools.getEffect(args[2]);
|
||
var fromeffect = Tools.getEffect(kwargs.from);
|
||
var ofpoke = this.getPokemon(kwargs.of);
|
||
if (poke) {
|
||
this.resultAnim(poke, 'Failed', 'neutral');
|
||
}
|
||
// Sky Drop blocking moves takes priority over all other moves
|
||
if (fromeffect.id === 'skydrop') {
|
||
actions += "Sky Drop won't let " + poke.getLowerName() + " go!";
|
||
break;
|
||
}
|
||
switch (effect.id) {
|
||
case 'brn':
|
||
this.resultAnim(poke, 'Already burned', 'neutral');
|
||
actions += "" + poke.getName() + " already has a burn.";
|
||
break;
|
||
case 'tox':
|
||
case 'psn':
|
||
this.resultAnim(poke, 'Already poisoned', 'neutral');
|
||
actions += "" + poke.getName() + " is already poisoned.";
|
||
break;
|
||
case 'slp':
|
||
if (fromeffect.id === 'uproar') {
|
||
this.resultAnim(poke, 'Failed', 'neutral');
|
||
if (kwargs.msg) {
|
||
actions += "But " + poke.getLowerName() + " can't sleep in an uproar!";
|
||
} else {
|
||
actions += "But the uproar kept " + poke.getLowerName() + " awake!";
|
||
}
|
||
} else {
|
||
this.resultAnim(poke, 'Already asleep', 'neutral');
|
||
actions += "" + poke.getName() + " is already asleep!";
|
||
}
|
||
break;
|
||
case 'par':
|
||
this.resultAnim(poke, 'Already paralyzed', 'neutral');
|
||
actions += "" + poke.getName() + " is already paralyzed.";
|
||
break;
|
||
case 'frz':
|
||
this.resultAnim(poke, 'Already frozen', 'neutral');
|
||
actions += "" + poke.getName() + " is already frozen solid!";
|
||
break;
|
||
case 'darkvoid':
|
||
case 'hyperspacefury':
|
||
if (kwargs.forme) {
|
||
actions += 'But ' + poke.getLowerName() + ' can\'t use it the way it is now!';
|
||
} else {
|
||
actions += 'But ' + poke.getLowerName() + ' can\'t use the move!';
|
||
}
|
||
break;
|
||
case 'magikarpsrevenge':
|
||
actions += 'But ' + poke.getLowerName() + ' can\'t use the move!';
|
||
break;
|
||
case 'substitute':
|
||
if (kwargs.weak) {
|
||
actions += "But it does not have enough HP left to make a substitute!";
|
||
} else {
|
||
actions += '' + poke.getName() + ' already has a substitute!';
|
||
}
|
||
break;
|
||
case 'skydrop':
|
||
if (kwargs.heavy) {
|
||
actions += '' + poke.getName() + ' is too heavy to be lifted!';
|
||
} else {
|
||
actions += "But it failed!";
|
||
}
|
||
break;
|
||
case 'sunnyday':
|
||
case 'raindance':
|
||
case 'sandstorm':
|
||
case 'hail':
|
||
switch (fromeffect.id) {
|
||
case 'desolateland':
|
||
actions += "The extremely harsh sunlight was not lessened at all!";
|
||
break;
|
||
case 'primordialsea':
|
||
actions += "There is no relief from this heavy rain!";
|
||
break;
|
||
case 'deltastream':
|
||
actions += "The mysterious strong winds blow on regardless!";
|
||
break;
|
||
default:
|
||
actions += "But it failed!";
|
||
}
|
||
break;
|
||
case 'unboost':
|
||
if (fromeffect.effectType === 'Ability') {
|
||
this.resultAnim(poke, fromeffect.name, 'ability');
|
||
this.message('', "<small>[" + poke.getName(true) + "'s " + fromeffect.name + "!]</small>");
|
||
poke.markAbility(fromeffect);
|
||
} else {
|
||
this.resultAnim(poke, 'Stat drop blocked', 'neutral');
|
||
}
|
||
switch (fromeffect.id) {
|
||
case 'flowerveil':
|
||
actions += '' + ofpoke.getName() + ' surrounded itself with a veil of petals!';
|
||
break;
|
||
default:
|
||
var stat = Tools.escapeHTML(args[3]);
|
||
actions += "" + poke.getName() + "'s " + (stat ? stat + " was" : "stats were") + " not lowered!";
|
||
}
|
||
break;
|
||
default:
|
||
switch (fromeffect.id) {
|
||
case 'desolateland':
|
||
actions += "The Water-type attack evaporated in the harsh sunlight!";
|
||
break;
|
||
case 'primordialsea':
|
||
actions += "The Fire-type attack fizzled out in the heavy rain!";
|
||
break;
|
||
default:
|
||
actions += "But it failed!";
|
||
}
|
||
break;
|
||
}
|
||
break;
|
||
|
||
case '-notarget':
|
||
if (this.gen >= 5) {
|
||
actions += "But it failed!";
|
||
} else {
|
||
actions += "But there was no target...";
|
||
}
|
||
break;
|
||
|
||
case '-ohko':
|
||
actions += "It's a one-hit KO!";
|
||
break;
|
||
|
||
case '-hitcount':
|
||
var hits = parseInt(args[2], 10);
|
||
if (this.multiHitMove && this.multiHitMove[3] === 0 && hits > 0) this.animMultiHitMove();
|
||
actions += 'Hit ' + hits + (hits > 1 ? ' times!' : ' time!');
|
||
break;
|
||
|
||
case '-nothing':
|
||
actions += "But nothing happened! ";
|
||
break;
|
||
|
||
case '-waiting':
|
||
var poke = this.getPokemon(args[1]);
|
||
var ofpoke = this.getPokemon(args[2]);
|
||
actions += "" + poke.getName() + " is waiting for " + ofpoke.getLowerName() + "'s move...";
|
||
break;
|
||
|
||
case '-combine':
|
||
actions += "The two moves have become one! It's a combined move!";
|
||
break;
|
||
|
||
case '-zpower':
|
||
var poke = this.getPokemon(args[1]);
|
||
if (!this.fastForward) BattleOtherAnims.zpower.anim(this, [poke.sprite]);
|
||
actions += "" + poke.getName() + " surrounded itself with its Z-Power! ";
|
||
break;
|
||
|
||
case '-prepare':
|
||
var poke = this.getPokemon(args[1]);
|
||
var move = Tools.getMove(args[2]);
|
||
var target = this.getPokemon(args[3]);
|
||
this.prepareMove(poke, move, target);
|
||
break;
|
||
|
||
case '-mustrecharge':
|
||
var poke = this.getPokemon(args[1]);
|
||
poke.addMovestatus('mustrecharge');
|
||
poke.side.updateStatbar(poke);
|
||
break;
|
||
|
||
case '-status':
|
||
var poke = this.getPokemon(args[1]);
|
||
var effect = Tools.getEffect(kwargs.from);
|
||
poke.status = args[2];
|
||
poke.removeVolatile('yawn');
|
||
var effectMessage = "";
|
||
if (effect.effectType === 'Ability') {
|
||
var ofpoke = this.getPokemon(kwargs.of) || poke;
|
||
this.resultAnim(ofpoke, effect.name, 'ability');
|
||
this.message('', "<small>[" + ofpoke.getName(true) + "'s " + effect.name + "!]</small>");
|
||
ofpoke.markAbility(effect);
|
||
} else if (effect.effectType === 'Item') {
|
||
(ofpoke || poke).item = effect.name;
|
||
effectMessage = " by the " + effect.name;
|
||
}
|
||
|
||
switch (args[2]) {
|
||
case 'brn':
|
||
this.resultAnim(poke, 'Burned', 'brn');
|
||
if (!this.fastForward) BattleStatusAnims['brn'].anim(this, [poke.sprite]);
|
||
actions += "" + poke.getName() + " was burned" + effectMessage + "!";
|
||
break;
|
||
case 'tox':
|
||
this.resultAnim(poke, 'Toxic poison', 'psn');
|
||
if (!this.fastForward) BattleStatusAnims['psn'].anim(this, [poke.sprite]);
|
||
actions += "" + poke.getName() + " was badly poisoned" + effectMessage + "!";
|
||
break;
|
||
case 'psn':
|
||
this.resultAnim(poke, 'Poisoned', 'psn');
|
||
if (!this.fastForward) BattleStatusAnims['psn'].anim(this, [poke.sprite]);
|
||
actions += "" + poke.getName() + " was poisoned!";
|
||
break;
|
||
case 'slp':
|
||
this.resultAnim(poke, 'Asleep', 'slp');
|
||
if (effect.id === 'rest') {
|
||
actions += '' + poke.getName() + ' slept and became healthy!';
|
||
} else {
|
||
actions += "" + poke.getName() + " fell asleep!";
|
||
}
|
||
break;
|
||
case 'par':
|
||
this.resultAnim(poke, 'Paralyzed', 'par');
|
||
if (!this.fastForward) BattleStatusAnims['par'].anim(this, [poke.sprite]);
|
||
actions += "" + poke.getName() + " is paralyzed! It may be unable to move!";
|
||
break;
|
||
case 'frz':
|
||
this.resultAnim(poke, 'Frozen', 'frz');
|
||
if (!this.fastForward) BattleStatusAnims['frz'].anim(this, [poke.sprite]);
|
||
actions += "" + poke.getName() + " was frozen solid!";
|
||
break;
|
||
default:
|
||
poke.side.updateStatbar(poke);
|
||
break;
|
||
}
|
||
break;
|
||
|
||
case '-curestatus':
|
||
var poke = this.getPokemon(args[1]);
|
||
var effect = Tools.getEffect(kwargs.from);
|
||
var ofpoke = this.getPokemon(kwargs.of);
|
||
poke.status = '';
|
||
|
||
if (kwargs.silent) {
|
||
// do nothing
|
||
} else if (effect.id) switch (effect.id) {
|
||
case 'psychoshift':
|
||
actions += '' + poke.getName() + ' moved its status onto ' + ofpoke.getLowerName() + '!';
|
||
this.resultAnim(poke, 'Cured', 'good');
|
||
break;
|
||
case 'flamewheel':
|
||
case 'flareblitz':
|
||
case 'fusionflare':
|
||
case 'sacredfire':
|
||
case 'scald':
|
||
case 'steameruption':
|
||
this.resultAnim(poke, 'Thawed', 'good');
|
||
actions += "" + poke.getName() + "'s " + effect.name + " melted the ice!";
|
||
break;
|
||
case 'naturalcure':
|
||
actions += "(" + poke.getName() + "'s Natural Cure activated!)";
|
||
poke.markAbility('Natural Cure');
|
||
break;
|
||
default:
|
||
this.resultAnim(poke, 'Cured', 'good');
|
||
actions += "" + poke.getName() + "'s " + effect.name + " heals its status!";
|
||
break;
|
||
} else switch (args[2]) {
|
||
case 'brn':
|
||
this.resultAnim(poke, 'Burn cured', 'good');
|
||
if (effect.effectType === 'Item') {
|
||
actions += "" + poke.getName() + "'s " + effect.name + " healed its burn!";
|
||
break;
|
||
}
|
||
if (poke.side.n === 0) actions += "" + poke.getName() + "'s burn was healed.";
|
||
else actions += "" + poke.getName() + " healed its burn!";
|
||
break;
|
||
case 'tox':
|
||
case 'psn':
|
||
this.resultAnim(poke, 'Poison cured', 'good');
|
||
if (effect.effectType === 'Item') {
|
||
actions += "" + poke.getName() + "'s " + effect.name + " cured its poison!";
|
||
break;
|
||
}
|
||
actions += "" + poke.getName() + " was cured of its poisoning.";
|
||
break;
|
||
case 'slp':
|
||
this.resultAnim(poke, 'Woke up', 'good');
|
||
if (effect.effectType === 'Item') {
|
||
actions += "" + poke.getName() + "'s " + effect.name + " woke it up!";
|
||
break;
|
||
}
|
||
actions += "" + poke.getName() + " woke up!";
|
||
break;
|
||
case 'par':
|
||
this.resultAnim(poke, 'Paralysis cured', 'good');
|
||
if (effect.effectType === 'Item') {
|
||
actions += "" + poke.getName() + "'s " + effect.name + " cured its paralysis!";
|
||
break;
|
||
}
|
||
actions += "" + poke.getName() + " was cured of paralysis.";
|
||
break;
|
||
case 'frz':
|
||
this.resultAnim(poke, 'Thawed', 'good');
|
||
if (effect.effectType === 'Item') {
|
||
actions += "" + poke.getName() + "'s " + effect.name + " defrosted it!";
|
||
break;
|
||
}
|
||
actions += "" + poke.getName() + " thawed out!";
|
||
break;
|
||
default:
|
||
poke.removeVolatile('confusion');
|
||
this.resultAnim(poke, 'Cured', 'good');
|
||
actions += "" + poke.getName() + "'s status cleared!";
|
||
}
|
||
break;
|
||
|
||
case '-cureteam': // For old gens when the whole team was always cured
|
||
var poke = this.getPokemon(args[1]);
|
||
for (var k = 0; k < poke.side.pokemon.length; k++) {
|
||
poke.side.pokemon[k].status = '';
|
||
poke.side.updateStatbar(poke.side.pokemon[k]);
|
||
}
|
||
|
||
this.resultAnim(poke, 'Team Cured', 'good');
|
||
var effect = Tools.getEffect(kwargs.from);
|
||
switch (effect.id) {
|
||
case 'aromatherapy':
|
||
actions += 'A soothing aroma wafted through the area!';
|
||
break;
|
||
case 'healbell':
|
||
actions += 'A bell chimed!';
|
||
break;
|
||
default:
|
||
actions += "" + poke.getName() + "'s team was cured!";
|
||
break;
|
||
}
|
||
break;
|
||
|
||
case '-item':
|
||
var poke = this.getPokemon(args[1]);
|
||
var item = Tools.getItem(args[2]);
|
||
var effect = Tools.getEffect(kwargs.from);
|
||
var ofpoke = this.getPokemon(kwargs.of);
|
||
poke.item = item.name;
|
||
poke.itemEffect = '';
|
||
poke.removeVolatile('airballoon');
|
||
if (item.id === 'airballoon') poke.addVolatile('airballoon');
|
||
|
||
if (effect.id) switch (effect.id) {
|
||
case 'pickup':
|
||
this.resultAnim(poke, 'Pickup', 'ability');
|
||
this.message('', "<small>[" + poke.getName(true) + "'s Pickup!]</small>");
|
||
poke.markAbility('Pickup');
|
||
// falls through
|
||
case 'recycle':
|
||
poke.itemEffect = 'found';
|
||
actions += '' + poke.getName() + ' found one ' + item.name + '!';
|
||
this.resultAnim(poke, item.name, 'neutral');
|
||
break;
|
||
case 'frisk':
|
||
this.resultAnim(ofpoke, 'Frisk', 'ability');
|
||
this.message('', "<small>[" + ofpoke.getName(true) + "'s Frisk!]</small>");
|
||
ofpoke.markAbility('Frisk');
|
||
if (kwargs.identify) { // used for gen 6
|
||
poke.itemEffect = 'frisked';
|
||
actions += '' + ofpoke.getName() + ' frisked ' + poke.getLowerName() + ' and found its ' + item.name + '!';
|
||
this.resultAnim(poke, item.name, 'neutral');
|
||
} else {
|
||
actions += '' + ofpoke.getName() + ' frisked its target and found one ' + item.name + '!';
|
||
}
|
||
break;
|
||
case 'magician':
|
||
case 'pickpocket':
|
||
this.resultAnim(poke, effect.name, 'ability');
|
||
this.message('', "<small>[" + poke.getName(true) + "'s " + effect.name + "!]</small>");
|
||
poke.markAbility(effect.name);
|
||
// falls through
|
||
case 'thief':
|
||
case 'covet':
|
||
// simulate the removal of the item from the ofpoke
|
||
ofpoke.item = '';
|
||
ofpoke.itemEffect = '';
|
||
ofpoke.prevItem = item.name;
|
||
ofpoke.prevItemEffect = 'stolen';
|
||
ofpoke.addVolatile('itemremoved');
|
||
poke.itemEffect = 'stolen';
|
||
actions += '' + poke.getName() + ' stole ' + ofpoke.getLowerName() + "'s " + item.name + "!";
|
||
this.resultAnim(poke, item.name, 'neutral');
|
||
this.resultAnim(ofpoke, 'Item Stolen', 'bad');
|
||
break;
|
||
case 'harvest':
|
||
poke.itemEffect = 'harvested';
|
||
this.resultAnim(poke, 'Harvest', 'ability');
|
||
this.message('', "<small>[" + poke.getName(true) + "'s Harvest!]</small>");
|
||
poke.markAbility('Harvest');
|
||
actions += '' + poke.getName() + ' harvested one ' + item.name + '!';
|
||
this.resultAnim(poke, item.name, 'neutral');
|
||
break;
|
||
case 'bestow':
|
||
poke.itemEffect = 'bestowed';
|
||
actions += '' + poke.getName() + ' received ' + item.name + ' from ' + ofpoke.getLowerName() + '!';
|
||
this.resultAnim(poke, item.name, 'neutral');
|
||
break;
|
||
case 'trick':
|
||
poke.itemEffect = 'tricked';
|
||
// falls through
|
||
default:
|
||
actions += '' + poke.getName() + ' obtained one ' + item.name + '.';
|
||
this.resultAnim(poke, item.name, 'neutral');
|
||
break;
|
||
} else switch (item.id) {
|
||
case 'airballoon':
|
||
this.resultAnim(poke, 'Balloon', 'good');
|
||
actions += "" + poke.getName() + " floats in the air with its Air Balloon!";
|
||
break;
|
||
default:
|
||
actions += "" + poke.getName() + " has " + item.name + "!";
|
||
break;
|
||
}
|
||
break;
|
||
|
||
case '-enditem':
|
||
var poke = this.getPokemon(args[1]);
|
||
var item = Tools.getItem(args[2]);
|
||
var effect = Tools.getEffect(kwargs.from);
|
||
var ofpoke = this.getPokemon(kwargs.of);
|
||
poke.item = '';
|
||
poke.itemEffect = '';
|
||
poke.prevItem = item.name;
|
||
poke.prevItemEffect = '';
|
||
poke.removeVolatile('airballoon');
|
||
poke.addVolatile('itemremoved');
|
||
if (kwargs.silent) {
|
||
// do nothing
|
||
} else if (kwargs.eat) {
|
||
poke.prevItemEffect = 'eaten';
|
||
if (!this.fastForward) BattleOtherAnims.consume.anim(this, [poke.sprite]);
|
||
actions += '' + poke.getName() + ' ate its ' + item.name + '!';
|
||
this.lastmove = item.id;
|
||
} else if (kwargs.weaken) {
|
||
poke.prevItemEffect = 'eaten';
|
||
actions += 'The ' + item.name + ' weakened the damage to ' + poke.getLowerName() + '!';
|
||
this.lastmove = item.id;
|
||
} else if (effect.id) switch (effect.id) {
|
||
case 'fling':
|
||
poke.prevItemEffect = 'flung';
|
||
actions += "" + poke.getName() + ' flung its ' + item.name + '!';
|
||
break;
|
||
case 'knockoff':
|
||
poke.prevItemEffect = 'knocked off';
|
||
actions += '' + ofpoke.getName() + ' knocked off ' + poke.getLowerName() + '\'s ' + item.name + '!';
|
||
if (!this.fastForward) BattleOtherAnims.itemoff.anim(this, [poke.sprite]);
|
||
this.resultAnim(poke, 'Item knocked off', 'neutral');
|
||
break;
|
||
case 'stealeat':
|
||
poke.prevItemEffect = 'stolen';
|
||
actions += '' + ofpoke.getName() + ' stole and ate its target\'s ' + item.name + '!';
|
||
break;
|
||
case 'gem':
|
||
poke.prevItemEffect = 'consumed';
|
||
actions += 'The ' + item.name + ' strengthened ' + Tools.getMove(kwargs.move).name + '\'s power!';
|
||
break;
|
||
case 'incinerate':
|
||
poke.prevItemEffect = 'incinerated';
|
||
actions += "" + poke.getName() + "'s " + item.name + " was burned up!";
|
||
break;
|
||
default:
|
||
actions += "" + poke.getName() + ' lost its ' + item.name + '!';
|
||
break;
|
||
} else switch (item.id) {
|
||
case 'airballoon':
|
||
poke.prevItemEffect = 'popped';
|
||
poke.removeVolatile('airballoon');
|
||
this.resultAnim(poke, 'Balloon popped', 'neutral');
|
||
actions += "" + poke.getName() + "'s Air Balloon popped!";
|
||
break;
|
||
case 'focussash':
|
||
poke.prevItemEffect = 'consumed';
|
||
this.resultAnim(poke, 'Sash', 'neutral');
|
||
actions += "" + poke.getName() + ' hung on using its Focus Sash!';
|
||
break;
|
||
case 'focusband':
|
||
this.resultAnim(poke, 'Focus Band', 'neutral');
|
||
actions += "" + poke.getName() + ' hung on using its Focus Band!';
|
||
break;
|
||
case 'powerherb':
|
||
poke.prevItemEffect = 'consumed';
|
||
actions += "" + poke.getName() + " became fully charged due to its Power Herb!";
|
||
break;
|
||
case 'whiteherb':
|
||
poke.prevItemEffect = 'consumed';
|
||
actions += "" + poke.getName() + " returned its status to normal using its White Herb!";
|
||
break;
|
||
case 'ejectbutton':
|
||
poke.prevItemEffect = 'consumed';
|
||
actions += "" + poke.getName() + " is switched out with the Eject Button!";
|
||
break;
|
||
case 'redcard':
|
||
poke.prevItemEffect = 'held up';
|
||
actions += "" + poke.getName() + " held up its Red Card against " + ofpoke.getLowerName() + "!";
|
||
break;
|
||
default:
|
||
poke.prevItemEffect = 'consumed';
|
||
actions += "" + poke.getName() + "'s " + item.name + " activated!";
|
||
break;
|
||
}
|
||
break;
|
||
|
||
case '-ability':
|
||
var poke = this.getPokemon(args[1]);
|
||
var ability = Tools.getAbility(args[2]);
|
||
var effect = Tools.getEffect(kwargs.from);
|
||
var ofpoke = this.getPokemon(kwargs.of);
|
||
poke.markAbility(ability, effect.id && !kwargs.fail);
|
||
|
||
if (kwargs.silent) {
|
||
// do nothing
|
||
} else if (effect.id) switch (effect.id) {
|
||
case 'trace':
|
||
this.resultAnim(poke, "Trace", 'ability');
|
||
this.animationDelay = 500;
|
||
this.resultAnim(poke, ability.name, 'ability');
|
||
this.message('', "<small>[" + poke.getName(true) + "'s Trace!]</small>");
|
||
if (!poke.baseAbility) poke.baseAbility = effect.name;
|
||
ofpoke.markAbility(ability.name);
|
||
actions += '' + poke.getName() + ' traced ' + ofpoke.getLowerName() + '\'s ' + ability.name + '!';
|
||
break;
|
||
case 'powerofalchemy':
|
||
case 'receiver':
|
||
this.resultAnim(poke, effect.name, 'ability');
|
||
this.animationDelay = 500;
|
||
this.resultAnim(poke, ability.name, 'ability');
|
||
this.message('', "<small>[" + poke.getName(true) + "'s " + effect.name + "!]</small>");
|
||
if (!poke.baseAbility) poke.baseAbility = effect.name;
|
||
actions += '' + ofpoke.getName() + '\'s ' + ability.name + ' was taken over!';
|
||
break;
|
||
case 'roleplay':
|
||
this.resultAnim(poke, ability.name, 'ability');
|
||
actions += '' + poke.getName() + ' copied ' + ofpoke.getLowerName() + '\'s ' + ability.name + ' Ability!';
|
||
ofpoke.markAbility(ability.name);
|
||
break;
|
||
case 'desolateland':
|
||
if (kwargs.fail) {
|
||
this.resultAnim(poke, ability.name, 'ability');
|
||
this.message('', "<small>[" + poke.getName(true) + "'s " + ability.name + "!]</small>");
|
||
actions += "The extremely harsh sunlight was not lessened at all!";
|
||
}
|
||
break;
|
||
case 'primordialsea':
|
||
if (kwargs.fail) {
|
||
this.resultAnim(poke, ability.name, 'ability');
|
||
this.message('', "<small>[" + poke.getName(true) + "'s " + ability.name + "!]</small>");
|
||
actions += "There's no relief from this heavy rain!";
|
||
}
|
||
break;
|
||
case 'deltastream':
|
||
if (kwargs.fail) {
|
||
this.resultAnim(poke, ability.name, 'ability');
|
||
this.message('', "<small>[" + poke.getName(true) + "'s " + ability.name + "!]</small>");
|
||
actions += "The mysterious strong winds blow on regardless!";
|
||
}
|
||
break;
|
||
default:
|
||
this.resultAnim(poke, ability.name, 'ability');
|
||
actions += "" + poke.getName() + " acquired " + ability.name + "!";
|
||
break;
|
||
} else {
|
||
this.resultAnim(poke, ability.name, 'ability');
|
||
this.message('', "<small>[" + poke.getName(true) + "'s " + ability.name + "!]</small>");
|
||
switch (ability.id) {
|
||
case 'airlock':
|
||
case 'cloudnine':
|
||
actions += "The effects of the weather disappeared.";
|
||
break;
|
||
case 'anticipation':
|
||
actions += "" + poke.getName() + " shuddered!";
|
||
break;
|
||
case 'aurabreak':
|
||
actions += "" + poke.getName() + " reversed all other Pokémon's auras!";
|
||
break;
|
||
case 'comatose':
|
||
actions += "" + poke.getName() + " is drowsing!";
|
||
break;
|
||
case 'darkaura':
|
||
actions += "" + poke.getName() + " is radiating a dark aura!";
|
||
break;
|
||
case 'fairyaura':
|
||
actions += "" + poke.getName() + " is radiating a fairy aura!";
|
||
break;
|
||
case 'moldbreaker':
|
||
actions += "" + poke.getName() + " breaks the mold!";
|
||
break;
|
||
case 'pressure':
|
||
actions += "" + poke.getName() + " is exerting its pressure!";
|
||
break;
|
||
case 'sturdy':
|
||
actions += "" + poke.getName() + " endured the hit!";
|
||
break;
|
||
case 'teravolt':
|
||
actions += "" + poke.getName() + " is radiating a bursting aura!";
|
||
break;
|
||
case 'turboblaze':
|
||
actions += "" + poke.getName() + " is radiating a blazing aura!";
|
||
break;
|
||
case 'unnerve':
|
||
actions += "" + this.getSide(args[3]).getTeamName() + " is too nervous to eat Berries!";
|
||
break;
|
||
default:
|
||
// Do nothing
|
||
}
|
||
}
|
||
break;
|
||
|
||
case '-endability':
|
||
var poke = this.getPokemon(args[1]);
|
||
var ability = Tools.getAbility(args[2]);
|
||
var effect = Tools.getEffect(kwargs.from);
|
||
poke.ability = '';
|
||
|
||
if (kwargs.silent) {
|
||
// do nothing
|
||
} else if (ability.exists) {
|
||
actions += "(" + poke.getName() + "'s " + ability.name + " was removed.)";
|
||
this.resultAnim(poke, ability.name + ' removed', 'bad');
|
||
if (!poke.baseAbility) poke.baseAbility = ability.name;
|
||
} else {
|
||
actions += "" + poke.getName() + "\'s Ability was suppressed!";
|
||
}
|
||
break;
|
||
|
||
case '-transform':
|
||
var poke = this.getPokemon(args[1]);
|
||
var tpoke = this.getPokemon(args[2]);
|
||
var effect = Tools.getEffect(kwargs.from);
|
||
|
||
if (!kwargs.silent && effect.effectType === 'Ability') {
|
||
this.resultAnim(poke, effect.name, 'ability');
|
||
this.message('', "<small>[" + poke.getName(true) + "'s " + effect.name + "!]</small>");
|
||
poke.markAbility(effect.name);
|
||
}
|
||
|
||
actions += '' + poke.getName() + ' transformed into ' + tpoke.species + '!';
|
||
poke.sprite.animTransform(tpoke);
|
||
poke.boosts = $.extend({}, tpoke.boosts);
|
||
poke.addVolatile('transform');
|
||
poke.addVolatile('formechange'); // the formechange volatile reminds us to revert the sprite change on switch-out
|
||
poke.copyTypesFrom(tpoke);
|
||
poke.ability = tpoke.ability;
|
||
poke.volatiles.formechange[2] = (tpoke.volatiles.formechange ? tpoke.volatiles.formechange[2] : tpoke.species);
|
||
poke.volatiles.transform[2] = tpoke;
|
||
for (var i = 0; i < tpoke.moveTrack.length; i++) {
|
||
poke.markMove(tpoke.moveTrack[i][0], 0);
|
||
}
|
||
this.resultAnim(poke, 'Transformed', 'good');
|
||
break;
|
||
case '-formechange':
|
||
var poke = this.getPokemon(args[1]);
|
||
var template = Tools.getTemplate(args[2]);
|
||
var fromeffect = Tools.getEffect(kwargs.from);
|
||
var spriteData = {'shiny': poke.sprite.sp.shiny};
|
||
var isCustomAnim = false;
|
||
poke.removeVolatile('typeadd');
|
||
poke.removeVolatile('typechange');
|
||
|
||
if (kwargs.silent) {
|
||
// do nothing
|
||
} else {
|
||
if (fromeffect.effectType === 'Ability') {
|
||
this.resultAnim(poke, fromeffect.name, 'ability');
|
||
this.message('', "<small>[" + poke.getName(true) + "'s " + fromeffect.name + "!]</small>");
|
||
poke.markAbility(fromeffect.name);
|
||
}
|
||
if (kwargs.msg) {
|
||
actions += "" + poke.getName() + " transformed!";
|
||
if (toId(template.species) === 'shaymin') break;
|
||
} else if (toId(template.species) === 'darmanitanzen') {
|
||
actions += "Zen Mode triggered!";
|
||
} else if (toId(template.species) === 'darmanitan') {
|
||
actions += "Zen Mode ended!";
|
||
} else if (toId(template.species) === 'aegislashblade') {
|
||
actions += "Changed to Blade Forme!";
|
||
} else if (toId(template.species) === 'aegislash') {
|
||
actions += "Changed to Shield Forme!";
|
||
} else if (toId(template.species) === 'wishiwashischool') {
|
||
actions += "" + poke.getName() + " formed a school!";
|
||
isCustomAnim = true;
|
||
} else if (toId(template.species) === 'wishiwashi') {
|
||
actions += "" + poke.getName() + " stopped schooling!";
|
||
isCustomAnim = true;
|
||
} else if (toId(template.species) === 'miniormeteor') {
|
||
actions += "Shields Down deactivated!";
|
||
} else if (toId(template.species) === 'minior') {
|
||
actions += "Shields Down activated!";
|
||
}
|
||
}
|
||
poke.sprite.animTransform($.extend(spriteData, template), isCustomAnim);
|
||
poke.addVolatile('formechange'); // the formechange volatile reminds us to revert the sprite change on switch-out
|
||
poke.volatiles.formechange[2] = template.species;
|
||
poke.side.updateStatbar();
|
||
break;
|
||
case '-mega':
|
||
var poke = this.getPokemon(args[1]);
|
||
var item = Tools.getItem(args[3]);
|
||
if (args[2] === 'Rayquaza') {
|
||
actions += "" + Tools.escapeHTML(poke.side.name) + "'s fervent wish has reached " + poke.getLowerName() + "!";
|
||
} else {
|
||
poke.item = item.name;
|
||
actions += "" + poke.getName() + "'s " + item.name + " is reacting to " + (this.gen >= 7 ? "the Key Stone" : Tools.escapeHTML(poke.side.name) + "'s Mega Bracelet") + "!";
|
||
}
|
||
actions += "<br />" + poke.getName() + " has Mega Evolved into Mega " + args[2] + "!";
|
||
break;
|
||
case '-primal':
|
||
var poke = this.getPokemon(args[1]);
|
||
actions += "" + poke.getName() + "'s Primal Reversion! It reverted to its primal state!";
|
||
break;
|
||
|
||
case '-start':
|
||
var poke = this.getPokemon(args[1]);
|
||
var effect = Tools.getEffect(args[2]);
|
||
var ofpoke = this.getPokemon(kwargs.of);
|
||
var fromeffect = Tools.getEffect(kwargs.from);
|
||
poke.addVolatile(effect.id);
|
||
|
||
if (effect.effectType === 'Ability') {
|
||
this.resultAnim(poke, effect.name, 'ability');
|
||
this.message('', "<small>[" + poke.getName(true) + "'s " + effect.name + "!]</small>");
|
||
poke.markAbility(effect.name);
|
||
}
|
||
if (kwargs.silent && effect.id !== 'typechange' && effect.id !== 'typeadd') {
|
||
// do nothing
|
||
} else switch (effect.id) {
|
||
case 'typechange':
|
||
args[3] = Tools.escapeHTML(args[3]);
|
||
poke.volatiles.typechange[2] = args[3];
|
||
poke.removeVolatile('typeadd');
|
||
if (kwargs.silent) {
|
||
poke.side.updateStatbar(poke);
|
||
break;
|
||
}
|
||
if (fromeffect.id) {
|
||
if (fromeffect.id === 'colorchange' || fromeffect.id === 'protean') {
|
||
this.resultAnim(poke, fromeffect.name, 'ability');
|
||
this.message('', "<small>[" + poke.getName(true) + "'s " + fromeffect.name + "!]</small>");
|
||
poke.markAbility(fromeffect.name);
|
||
actions += "" + poke.getName() + " transformed into the " + args[3] + " type!";
|
||
} else if (fromeffect.id === 'reflecttype') {
|
||
poke.copyTypesFrom(ofpoke);
|
||
if (!kwargs.silent) actions += "" + poke.getName() + "'s type became the same as " + ofpoke.getLowerName() + "'s type!";
|
||
} else if (fromeffect.id === 'burnup') {
|
||
actions += "" + poke.getName() + " burned itself out!";
|
||
} else if (!kwargs.silent) {
|
||
actions += "" + poke.getName() + "'s " + fromeffect.name + " made it the " + args[3] + " type!";
|
||
}
|
||
} else {
|
||
actions += "" + poke.getName() + " transformed into the " + args[3] + " type!";
|
||
}
|
||
this.resultAnim(poke, args[3].split('/').map(function (type) {
|
||
return '<img src="' + Tools.resourcePrefix + 'sprites/types/' + type + '.png" alt="' + type + '" />';
|
||
}).join(' '), 'neutral');
|
||
break;
|
||
case 'typeadd':
|
||
args[3] = Tools.escapeHTML(args[3]);
|
||
poke.volatiles.typeadd[2] = args[3];
|
||
if (kwargs.silent) break;
|
||
actions += "" + args[3] + " type was added to " + poke.getLowerName() + "!";
|
||
this.resultAnim(poke, '<img src="' + Tools.resourcePrefix + 'sprites/types/' + args[3] + '.png" alt="' + args[3] + '" />', 'neutral');
|
||
break;
|
||
case 'powertrick':
|
||
this.resultAnim(poke, 'Power Trick', 'neutral');
|
||
actions += "" + poke.getName() + " switched its Attack and Defense!";
|
||
break;
|
||
case 'foresight':
|
||
case 'miracleeye':
|
||
this.resultAnim(poke, 'Identified', 'bad');
|
||
actions += "" + poke.getName() + " was identified!";
|
||
break;
|
||
case 'telekinesis':
|
||
this.resultAnim(poke, 'Telekinesis', 'neutral');
|
||
actions += "" + poke.getName() + " was hurled into the air!";
|
||
break;
|
||
case 'confusion':
|
||
if (kwargs.already) {
|
||
actions += "" + poke.getName() + " is already confused!";
|
||
} else {
|
||
if (!this.fastForward) BattleStatusAnims['confused'].anim(this, [poke.sprite]);
|
||
this.resultAnim(poke, 'Confused', 'bad');
|
||
if (kwargs.fatigue) {
|
||
actions += "" + poke.getName() + " became confused due to fatigue!";
|
||
} else {
|
||
actions += "" + poke.getName() + " became confused!";
|
||
}
|
||
}
|
||
break;
|
||
case 'leechseed':
|
||
poke.side.updateStatbar(poke);
|
||
actions += '' + poke.getName() + ' was seeded!';
|
||
break;
|
||
case 'healblock':
|
||
this.resultAnim(poke, 'Heal Block', 'bad');
|
||
actions += "" + poke.getName() + " was prevented from healing!";
|
||
break;
|
||
case 'mudsport':
|
||
this.resultAnim(poke, 'Mud Sport', 'neutral');
|
||
actions += "Electricity's power was weakened!";
|
||
break;
|
||
case 'watersport':
|
||
this.resultAnim(poke, 'Water Sport', 'neutral');
|
||
actions += "Fire's power was weakened!";
|
||
break;
|
||
case 'yawn':
|
||
this.resultAnim(poke, 'Drowsy', 'slp');
|
||
actions += "" + poke.getName() + ' grew drowsy!';
|
||
break;
|
||
case 'flashfire':
|
||
actions += 'The power of ' + poke.getLowerName() + '\'s Fire-type moves rose!';
|
||
break;
|
||
case 'taunt':
|
||
this.resultAnim(poke, 'Taunted', 'bad');
|
||
actions += '' + poke.getName() + ' fell for the taunt!';
|
||
break;
|
||
case 'imprison':
|
||
this.resultAnim(poke, 'Imprisoning', 'good');
|
||
actions += "" + poke.getName() + " sealed any moves its target shares with it!";
|
||
break;
|
||
case 'disable':
|
||
if (fromeffect.effectType === 'Ability') {
|
||
this.resultAnim(ofpoke, fromeffect.name, 'ability');
|
||
this.message('', "<small>[" + ofpoke.getName(true) + "'s " + fromeffect.name + "!]</small>");
|
||
ofpoke.markAbility(fromeffect.name);
|
||
}
|
||
this.resultAnim(poke, 'Disabled', 'bad');
|
||
actions += "" + poke.getName() + "'s " + Tools.escapeHTML(args[3]) + " was disabled!";
|
||
break;
|
||
case 'embargo':
|
||
this.resultAnim(poke, 'Embargo', 'bad');
|
||
actions += "" + poke.getName() + " can't use items anymore!";
|
||
break;
|
||
case 'torment':
|
||
this.resultAnim(poke, 'Tormented', 'bad');
|
||
actions += '' + poke.getName() + ' was subjected to torment!';
|
||
break;
|
||
case 'ingrain':
|
||
this.resultAnim(poke, 'Ingrained', 'good');
|
||
actions += '' + poke.getName() + ' planted its roots!';
|
||
break;
|
||
case 'aquaring':
|
||
this.resultAnim(poke, 'Aqua Ring', 'good');
|
||
actions += '' + poke.getName() + ' surrounded itself with a veil of water!';
|
||
break;
|
||
case 'stockpile1':
|
||
this.resultAnim(poke, 'Stockpile', 'good');
|
||
actions += '' + poke.getName() + ' stockpiled 1!';
|
||
break;
|
||
case 'stockpile2':
|
||
poke.removeVolatile('stockpile1');
|
||
this.resultAnim(poke, 'Stockpile×2', 'good');
|
||
actions += '' + poke.getName() + ' stockpiled 2!';
|
||
break;
|
||
case 'stockpile3':
|
||
poke.removeVolatile('stockpile2');
|
||
this.resultAnim(poke, 'Stockpile×3', 'good');
|
||
actions += '' + poke.getName() + ' stockpiled 3!';
|
||
break;
|
||
case 'perish0':
|
||
poke.removeVolatile('perish1');
|
||
actions += '' + poke.getName() + "'s perish count fell to 0.";
|
||
break;
|
||
case 'perish1':
|
||
poke.removeVolatile('perish2');
|
||
this.resultAnim(poke, 'Perish next turn', 'bad');
|
||
actions += '' + poke.getName() + "'s perish count fell to 1.";
|
||
break;
|
||
case 'perish2':
|
||
poke.removeVolatile('perish3');
|
||
this.resultAnim(poke, 'Perish in 2', 'bad');
|
||
actions += '' + poke.getName() + "'s perish count fell to 2.";
|
||
break;
|
||
case 'perish3':
|
||
this.resultAnim(poke, 'Perish in 3', 'bad');
|
||
actions += '' + poke.getName() + "'s perish count fell to 3.";
|
||
break;
|
||
case 'encore':
|
||
this.resultAnim(poke, 'Encored', 'bad');
|
||
actions += '' + poke.getName() + ' received an encore!';
|
||
break;
|
||
case 'bide':
|
||
this.resultAnim(poke, 'Bide', 'good');
|
||
actions += "" + poke.getName() + " is storing energy!";
|
||
break;
|
||
case 'slowstart':
|
||
actions += "" + poke.getName() + " can't get it going!";
|
||
break;
|
||
case 'attract':
|
||
if (fromeffect.effectType === 'Ability') {
|
||
this.resultAnim(ofpoke, fromeffect.name, 'ability');
|
||
this.message('', "<small>[" + ofpoke.getName(true) + "'s " + fromeffect.name + "!]</small>");
|
||
ofpoke.markAbility(fromeffect.name);
|
||
}
|
||
this.resultAnim(poke, 'Attracted', 'bad');
|
||
if (fromeffect.effectType === 'Item') {
|
||
actions += "" + poke.getName() + " fell in love from the " + fromeffect.name + "!";
|
||
} else {
|
||
actions += "" + poke.getName() + " fell in love!";
|
||
}
|
||
break;
|
||
case 'autotomize':
|
||
this.resultAnim(poke, 'Lightened', 'good');
|
||
actions += "" + poke.getName() + " became nimble!";
|
||
break;
|
||
case 'focusenergy':
|
||
this.resultAnim(poke, '+Crit rate', 'good');
|
||
if (fromeffect.effectType === 'Item') {
|
||
actions += "" + poke.getName() + " used the " + fromeffect.name + " to get pumped!";
|
||
} else if (kwargs.zeffect) {
|
||
actions += "" + poke.getName() + " boosted its critical-hit ratio using its Z-Power!";
|
||
} else {
|
||
actions += "" + poke.getName() + " is getting pumped!";
|
||
}
|
||
break;
|
||
case 'curse':
|
||
this.resultAnim(poke, 'Cursed', 'bad');
|
||
actions += "" + ofpoke.getName() + " cut its own HP and put a curse on " + poke.getLowerName() + "!";
|
||
break;
|
||
case 'nightmare':
|
||
this.resultAnim(poke, 'Nightmare', 'bad');
|
||
actions += "" + poke.getName() + " began having a nightmare!";
|
||
break;
|
||
case 'magnetrise':
|
||
this.resultAnim(poke, 'Magnet Rise', 'good');
|
||
actions += "" + poke.getName() + " levitated with electromagnetism!";
|
||
break;
|
||
case 'smackdown':
|
||
this.resultAnim(poke, 'Smacked Down', 'bad');
|
||
actions += "" + poke.getName() + " fell straight down!";
|
||
poke.removeVolatile('magnetrise');
|
||
poke.removeVolatile('telekinesis');
|
||
if (poke.lastmove === 'fly' || poke.lastmove === 'bounce') poke.sprite.animReset();
|
||
break;
|
||
case 'substitute':
|
||
if (kwargs.damage) {
|
||
this.resultAnim(poke, 'Damage', 'bad');
|
||
actions += "The substitute took damage for " + poke.getLowerName() + "!";
|
||
} else if (kwargs.block) {
|
||
this.resultAnim(poke, 'Blocked', 'neutral');
|
||
actions += 'But it failed!';
|
||
} else if (kwargs.already) {
|
||
actions += '' + poke.getName() + ' already has a substitute!';
|
||
} else {
|
||
poke.sprite.animSub();
|
||
actions += '' + poke.getName() + ' put in a substitute!';
|
||
}
|
||
break;
|
||
case 'uproar':
|
||
if (kwargs.upkeep) {
|
||
actions += "" + poke.getName() + " is making an uproar!";
|
||
} else {
|
||
actions += "" + poke.getName() + " caused an uproar!";
|
||
}
|
||
break;
|
||
case 'doomdesire':
|
||
actions += '' + poke.getName() + ' chose Doom Desire as its destiny!';
|
||
break;
|
||
case 'futuresight':
|
||
actions += '' + poke.getName() + ' foresaw an attack!';
|
||
break;
|
||
case 'mimic':
|
||
actions += '' + poke.getName() + ' learned ' + Tools.escapeHTML(args[3]) + '!';
|
||
break;
|
||
case 'laserfocus':
|
||
actions += '' + poke.getName() + ' concentrated intensely!';
|
||
break;
|
||
case 'followme':
|
||
case 'ragepowder': // Deprecated, now uses -singleturn
|
||
actions += '' + poke.getName() + ' became the center of attention!';
|
||
break;
|
||
case 'powder': // Deprecated, now uses -singleturn
|
||
actions += '' + poke.getName() + ' is covered in powder!';
|
||
break;
|
||
|
||
// Gen 1
|
||
case 'lightscreen':
|
||
this.resultAnim(poke, 'Light Screen', 'good');
|
||
actions += '' + poke.getName() + '\'s protected against special attacks!';
|
||
break;
|
||
case 'reflect':
|
||
this.resultAnim(poke, 'Reflect', 'good');
|
||
actions += '' + poke.getName() + ' gained armor!';
|
||
break;
|
||
|
||
default:
|
||
actions += "" + poke.getName() + "'s " + effect.name + " started!";
|
||
}
|
||
poke.side.updateStatbar();
|
||
break;
|
||
case '-end':
|
||
var poke = this.getPokemon(args[1]);
|
||
var effect = Tools.getEffect(args[2]);
|
||
var fromeffect = Tools.getEffect(kwargs.from);
|
||
poke.removeVolatile(effect.id);
|
||
|
||
if (kwargs.silent) {
|
||
// do nothing
|
||
} else switch (effect.id) {
|
||
case 'powertrick':
|
||
this.resultAnim(poke, 'Power Trick', 'neutral');
|
||
actions += "" + poke.getName() + " switched its Attack and Defense!";
|
||
break;
|
||
case 'telekinesis':
|
||
this.resultAnim(poke, 'Telekinesis ended', 'neutral');
|
||
actions += "" + poke.getName() + " was freed from the telekinesis!";
|
||
break;
|
||
case 'skydrop':
|
||
if (kwargs.interrupt) {
|
||
poke.sprite.anim({time: 100});
|
||
}
|
||
actions += "" + poke.getName() + " was freed from the Sky Drop!";
|
||
break;
|
||
case 'confusion':
|
||
this.resultAnim(poke, 'Confusion ended', 'good');
|
||
if (!kwargs.silent) {
|
||
if (fromeffect.effectType === 'Item') {
|
||
actions += "" + poke.getName() + "'s " + fromeffect.name + " snapped it out of its confusion!";
|
||
break;
|
||
}
|
||
if (poke.side.n === 0) actions += "" + poke.getName() + " snapped out of its confusion.";
|
||
else actions += "" + poke.getName() + " snapped out of confusion!";
|
||
}
|
||
break;
|
||
case 'leechseed':
|
||
if (fromeffect.id === 'rapidspin') {
|
||
this.resultAnim(poke, 'De-seeded', 'good');
|
||
actions += "" + poke.getName() + " was freed from Leech Seed!";
|
||
}
|
||
break;
|
||
case 'healblock':
|
||
this.resultAnim(poke, 'Heal Block ended', 'good');
|
||
actions += "" + poke.getName() + "'s Heal Block wore off!";
|
||
break;
|
||
case 'attract':
|
||
this.resultAnim(poke, 'Attract ended', 'good');
|
||
if (fromeffect.id === 'oblivious') {
|
||
actions += '' + poke.getName() + " got over its infatuation.";
|
||
}
|
||
if (fromeffect.id === 'mentalherb') {
|
||
actions += "" + poke.getName() + " cured its infatuation status using its " + fromeffect.name + "!";
|
||
}
|
||
break;
|
||
case 'taunt':
|
||
this.resultAnim(poke, 'Taunt ended', 'good');
|
||
actions += '' + poke.getName() + "'s taunt wore off!";
|
||
break;
|
||
case 'disable':
|
||
this.resultAnim(poke, 'Disable ended', 'good');
|
||
actions += '' + poke.getName() + "'s move is no longer disabled!";
|
||
break;
|
||
case 'embargo':
|
||
this.resultAnim(poke, 'Embargo ended', 'good');
|
||
actions += "" + poke.getName() + " can use items again!";
|
||
break;
|
||
case 'torment':
|
||
this.resultAnim(poke, 'Torment ended', 'good');
|
||
actions += '' + poke.getName() + "'s torment wore off!";
|
||
break;
|
||
case 'encore':
|
||
this.resultAnim(poke, 'Encore ended', 'good');
|
||
actions += '' + poke.getName() + "'s encore ended!";
|
||
break;
|
||
case 'bide':
|
||
if (!this.fastForward) BattleOtherAnims.bideunleash.anim(this, [poke.sprite]);
|
||
actions += "" + poke.getName() + " unleashed its energy!";
|
||
break;
|
||
case 'illusion':
|
||
this.resultAnim(poke, 'Illusion ended', 'bad');
|
||
actions += "" + poke.getName() + "'s illusion wore off!";
|
||
poke.markAbility('Illusion');
|
||
break;
|
||
case 'slowstart':
|
||
this.resultAnim(poke, 'Slow Start ended', 'good');
|
||
actions += "" + poke.getName() + " finally got its act together!";
|
||
break;
|
||
case 'magnetrise':
|
||
if (poke.side.n === 0) actions += "" + poke.getName() + "'s electromagnetism wore off!";
|
||
else actions += "The electromagnetism of " + poke.getLowerName() + " wore off!";
|
||
break;
|
||
case 'perishsong': // for backwards compatibility
|
||
poke.removeVolatile('perish3');
|
||
break;
|
||
case 'substitute':
|
||
poke.sprite.animSubFade();
|
||
this.resultAnim(poke, 'Faded', 'bad');
|
||
actions += '' + poke.getName() + "'s substitute faded!";
|
||
break;
|
||
case 'uproar':
|
||
actions += "" + poke.getName() + " calmed down.";
|
||
break;
|
||
case 'stockpile':
|
||
poke.removeVolatile('stockpile1');
|
||
poke.removeVolatile('stockpile2');
|
||
poke.removeVolatile('stockpile3');
|
||
actions += "" + poke.getName() + "'s stockpiled effect wore off!";
|
||
break;
|
||
case 'bind':
|
||
case 'wrap':
|
||
case 'clamp':
|
||
case 'whirlpool':
|
||
case 'firespin':
|
||
case 'magmastorm':
|
||
case 'sandtomb':
|
||
case 'infestation':
|
||
actions += '' + poke.getName() + ' was freed from ' + effect.name + '!';
|
||
break;
|
||
default:
|
||
if (effect.effectType === 'Move') {
|
||
if (effect.name === 'Doom Desire') {
|
||
BattleOtherAnims.doomdesirehit.anim(this, [poke.sprite]);
|
||
}
|
||
if (effect.name === 'Future Sight') {
|
||
BattleOtherAnims.futuresighthit.anim(this, [poke.sprite]);
|
||
}
|
||
actions += '' + poke.getName() + " took the " + effect.name + " attack!";
|
||
} else {
|
||
actions += "" + poke.getName() + "'s " + effect.name + " ended!";
|
||
}
|
||
}
|
||
poke.side.updateStatbar();
|
||
break;
|
||
case '-singleturn':
|
||
var poke = this.getPokemon(args[1]);
|
||
var effect = Tools.getEffect(args[2]);
|
||
var ofpoke = this.getPokemon(kwargs.of);
|
||
var fromeffect = Tools.getEffect(kwargs.from);
|
||
poke.addTurnstatus(effect.id);
|
||
|
||
switch (effect.id) {
|
||
case 'roost':
|
||
this.resultAnim(poke, 'Landed', 'neutral');
|
||
//actions += '' + poke.getName() + ' landed on the ground!';
|
||
break;
|
||
case 'quickguard':
|
||
this.resultAnim(poke, 'Quick Guard', 'good');
|
||
actions += "Quick Guard protected " + poke.side.getLowerTeamName() + "!";
|
||
break;
|
||
case 'wideguard':
|
||
this.resultAnim(poke, 'Wide Guard', 'good');
|
||
actions += "Wide Guard protected " + poke.side.getLowerTeamName() + "!";
|
||
break;
|
||
case 'craftyshield':
|
||
this.resultAnim(poke, 'Crafty Shield', 'good');
|
||
actions += "Crafty Shield protected " + poke.side.getLowerTeamName() + "!";
|
||
break;
|
||
case 'matblock':
|
||
this.resultAnim(poke, 'Mat Block', 'good');
|
||
actions += '' + poke.getName() + ' intends to flip up a mat and block incoming attacks!';
|
||
break;
|
||
case 'protect':
|
||
this.resultAnim(poke, 'Protected', 'good');
|
||
actions += '' + poke.getName() + ' protected itself!';
|
||
break;
|
||
case 'endure':
|
||
this.resultAnim(poke, 'Enduring', 'good');
|
||
actions += '' + poke.getName() + ' braced itself!';
|
||
break;
|
||
case 'helpinghand':
|
||
this.resultAnim(poke, 'Helping Hand', 'good');
|
||
actions += '' + ofpoke.getName() + " is ready to help " + poke.getLowerName() + "!";
|
||
break;
|
||
case 'focuspunch':
|
||
this.resultAnim(poke, 'Focusing', 'neutral');
|
||
actions += '' + poke.getName() + ' is tightening its focus!';
|
||
poke.markMove(effect.name, 0);
|
||
break;
|
||
case 'shelltrap':
|
||
this.resultAnim(poke, 'Trap set', 'neutral');
|
||
actions += '' + poke.getName() + ' set a shell trap!';
|
||
poke.markMove(effect.name, 0);
|
||
break;
|
||
case 'snatch':
|
||
actions += '' + poke.getName() + ' waits for a target to make a move!';
|
||
break;
|
||
case 'magiccoat':
|
||
actions += '' + poke.getName() + ' shrouded itself with Magic Coat!';
|
||
break;
|
||
case 'electrify':
|
||
actions += '' + poke.getName() + '\'s moves have been electrified!';
|
||
break;
|
||
case 'followme':
|
||
case 'ragepowder':
|
||
case 'spotlight':
|
||
if (kwargs.zeffect) {
|
||
actions += '' + poke.getName() + ' became the center of attention using its Z-Power!';
|
||
} else {
|
||
actions += '' + poke.getName() + ' became the center of attention!';
|
||
}
|
||
break;
|
||
case 'powder':
|
||
actions += '' + poke.getName() + ' is covered in powder!';
|
||
break;
|
||
case 'instruct':
|
||
actions += '' + poke.getName() + ' used the move instructed by ' + ofpoke.getLowerName() + '!';
|
||
break;
|
||
case 'beakblast':
|
||
if (!this.fastForward) BattleOtherAnims.bidecharge.anim(this, [poke.sprite]);
|
||
this.resultAnim(poke, 'Beak Blast', 'neutral');
|
||
actions += '' + poke.getName() + ' started heating up its beak!';
|
||
break;
|
||
}
|
||
poke.side.updateStatbar();
|
||
break;
|
||
case '-singlemove':
|
||
var poke = this.getPokemon(args[1]);
|
||
var effect = Tools.getEffect(args[2]);
|
||
var ofpoke = this.getPokemon(kwargs.of);
|
||
var fromeffect = Tools.getEffect(kwargs.from);
|
||
poke.addMovestatus(effect.id);
|
||
|
||
switch (effect.id) {
|
||
case 'grudge':
|
||
this.resultAnim(poke, 'Grudge', 'neutral');
|
||
actions += '' + poke.getName() + ' wants its target to bear a grudge!';
|
||
break;
|
||
case 'destinybond':
|
||
this.resultAnim(poke, 'Destiny Bond', 'neutral');
|
||
actions += '' + poke.getName() + ' is hoping to take its attacker down with it!';
|
||
break;
|
||
}
|
||
break;
|
||
|
||
case '-activate':
|
||
var poke = this.getPokemon(args[1]);
|
||
var effect = Tools.getEffect(args[2]);
|
||
var ofpoke = this.getPokemon(kwargs.of);
|
||
if (effect.effectType === 'Ability') {
|
||
this.resultAnim(poke, effect.name, 'ability');
|
||
this.message('', "<small>[" + poke.getName(true) + "'s " + effect.name + "!]</small>");
|
||
poke.markAbility(effect.name);
|
||
}
|
||
switch (effect.id) {
|
||
case 'healreplacement':
|
||
actions += "" + poke.getName() + " will restore its replacement's HP using its Z-Power!";
|
||
break;
|
||
case 'confusion':
|
||
actions += "" + poke.getName() + " is confused!";
|
||
break;
|
||
case 'destinybond':
|
||
actions += '' + poke.getName() + ' took its attacker down with it!';
|
||
break;
|
||
case 'snatch':
|
||
actions += "" + poke.getName() + " snatched " + ofpoke.getLowerName() + "'s move!";
|
||
break;
|
||
case 'grudge':
|
||
actions += "" + poke.getName() + "'s " + Tools.escapeHTML(args[3]) + " lost all of its PP due to the grudge!";
|
||
poke.markMove(args[3], Infinity);
|
||
break;
|
||
case 'quickguard':
|
||
poke.addTurnstatus('quickguard');
|
||
this.resultAnim(poke, 'Quick Guard', 'good');
|
||
actions += "Quick Guard protected " + poke.getLowerName() + "!";
|
||
break;
|
||
case 'wideguard':
|
||
poke.addTurnstatus('wideguard');
|
||
this.resultAnim(poke, 'Wide Guard', 'good');
|
||
actions += "Wide Guard protected " + poke.getLowerName() + "!";
|
||
break;
|
||
case 'craftyshield':
|
||
poke.addTurnstatus('craftyshield');
|
||
this.resultAnim(poke, 'Crafty Shield', 'good');
|
||
actions += "Crafty Shield protected " + poke.getLowerName() + "!";
|
||
break;
|
||
case 'protect':
|
||
poke.addTurnstatus('protect');
|
||
this.resultAnim(poke, 'Protected', 'good');
|
||
actions += '' + poke.getName() + ' protected itself!';
|
||
break;
|
||
case 'substitute':
|
||
if (kwargs.damage) {
|
||
this.resultAnim(poke, 'Damage', 'bad');
|
||
actions += 'The substitute took damage for ' + poke.getLowerName() + '!';
|
||
} else if (kwargs.block) {
|
||
this.resultAnim(poke, 'Blocked', 'neutral');
|
||
actions += '' + poke.getName() + "'s Substitute blocked " + Tools.getMove(kwargs.block || args[3]).name + '!';
|
||
}
|
||
break;
|
||
case 'attract':
|
||
if (!this.fastForward) BattleStatusAnims['attracted'].anim(this, [poke.sprite]);
|
||
actions += '' + poke.getName() + ' is in love with ' + ofpoke.getLowerName() + '!';
|
||
break;
|
||
case 'bide':
|
||
if (!this.fastForward) BattleOtherAnims.bidecharge.anim(this, [poke.sprite]);
|
||
actions += "" + poke.getName() + " is storing energy!";
|
||
break;
|
||
case 'mist':
|
||
actions += "" + poke.getName() + " is protected by the mist!";
|
||
break;
|
||
case 'safeguard':
|
||
actions += "" + poke.getName() + " is protected by Safeguard!";
|
||
break;
|
||
case 'trapped':
|
||
actions += "" + poke.getName() + " can no longer escape!";
|
||
break;
|
||
case 'stickyweb':
|
||
actions += '' + poke.getName() + ' was caught in a sticky web!';
|
||
break;
|
||
case 'happyhour':
|
||
actions += 'Everyone is caught up in the happy atmosphere!';
|
||
break;
|
||
case 'celebrate':
|
||
actions += 'Congratulations, ' + Tools.escapeHTML(poke.side.name) + '!';
|
||
break;
|
||
|
||
// move activations
|
||
case 'aromatherapy':
|
||
this.resultAnim(poke, 'Team Cured', 'good');
|
||
actions += 'A soothing aroma wafted through the area!';
|
||
break;
|
||
case 'healbell':
|
||
this.resultAnim(poke, 'Team Cured', 'good');
|
||
actions += 'A bell chimed!';
|
||
break;
|
||
case 'trick':
|
||
case 'switcheroo':
|
||
actions += '' + poke.getName() + ' switched items with its target!';
|
||
break;
|
||
case 'brickbreak':
|
||
actions += poke.getName() + " shattered " + ofpoke.getTeamName() + " protections!";
|
||
ofpoke.removeSideCondition('Reflect');
|
||
ofpoke.removeSideCondition('LightScreen');
|
||
break;
|
||
case 'beatup':
|
||
actions += "" + Tools.escapeHTML(kwargs.of) + "'s attack!";
|
||
break;
|
||
case 'pursuit':
|
||
actions += "(" + poke.getName() + " is being withdrawn!)";
|
||
break;
|
||
case 'hyperspacefury':
|
||
case 'hyperspacehole':
|
||
case 'phantomforce':
|
||
case 'shadowforce':
|
||
case 'feint':
|
||
this.resultAnim(poke, 'Protection broken', 'bad');
|
||
if (kwargs.broken) {
|
||
actions += "It broke through " + poke.getLowerName() + "'s protection!";
|
||
} else {
|
||
actions += "" + poke.getName() + " fell for the feint!";
|
||
}
|
||
poke.removeTurnstatus('protect');
|
||
for (var k = 0; k < poke.side.pokemon.length; k++) {
|
||
poke.side.pokemon[k].removeTurnstatus('wideguard');
|
||
poke.side.pokemon[k].removeTurnstatus('quickguard');
|
||
poke.side.pokemon[k].removeTurnstatus('craftyshield');
|
||
poke.side.pokemon[k].removeTurnstatus('matblock');
|
||
poke.side.updateStatbar(poke.side.pokemon[k]);
|
||
}
|
||
break;
|
||
case 'spite':
|
||
var move = Tools.getMove(args[3]).name;
|
||
var pp = Tools.escapeHTML(args[4]);
|
||
actions += "It reduced the PP of " + poke.getLowerName() + "'s " + move + " by " + pp + "!";
|
||
poke.markMove(move, Number(pp));
|
||
break;
|
||
case 'gravity':
|
||
actions += "" + poke.getName() + " couldn't stay airborne because of gravity!";
|
||
poke.removeVolatile('magnetrise');
|
||
poke.removeVolatile('telekinesis');
|
||
poke.sprite.anim({time: 100});
|
||
break;
|
||
case 'magnitude':
|
||
actions += "Magnitude " + Tools.escapeHTML(args[3]) + "!";
|
||
break;
|
||
case 'sketch':
|
||
actions += "" + poke.getName() + " sketched " + Tools.escapeHTML(args[3]) + "!";
|
||
break;
|
||
case 'skillswap':
|
||
actions += "" + poke.getName() + " swapped Abilities with its target!";
|
||
if (this.gen <= 4) break;
|
||
var pokeability = Tools.escapeHTML(args[3]) || ofpoke.ability;
|
||
var ofpokeability = Tools.escapeHTML(args[4]) || poke.ability;
|
||
if (pokeability) {
|
||
poke.ability = pokeability;
|
||
if (!ofpoke.baseAbility) ofpoke.baseAbility = pokeability;
|
||
}
|
||
if (ofpokeability) {
|
||
ofpoke.ability = ofpokeability;
|
||
if (!poke.baseAbility) poke.baseAbility = ofpokeability;
|
||
}
|
||
if (poke.side !== ofpoke.side) {
|
||
this.resultAnim(poke, pokeability, 'ability');
|
||
this.resultAnim(ofpoke, ofpokeability, 'ability');
|
||
actions += "<br />" + poke.getName() + " acquired " + pokeability + "!";
|
||
actions += "<br />" + ofpoke.getName() + " acquired " + ofpokeability + "!";
|
||
}
|
||
break;
|
||
case 'charge':
|
||
actions += "" + poke.getName() + " began charging power!";
|
||
break;
|
||
case 'struggle':
|
||
actions += "" + poke.getName() + " has no moves left!";
|
||
break;
|
||
case 'bind':
|
||
actions += '' + poke.getName() + ' was squeezed by ' + ofpoke.getLowerName() + '!';
|
||
break;
|
||
case 'wrap':
|
||
actions += '' + poke.getName() + ' was wrapped by ' + ofpoke.getLowerName() + '!';
|
||
break;
|
||
case 'clamp':
|
||
actions += '' + ofpoke.getName() + ' clamped down on ' + poke.getLowerName() + '!';
|
||
break;
|
||
case 'whirlpool':
|
||
actions += '' + poke.getName() + ' became trapped in the vortex!';
|
||
break;
|
||
case 'firespin':
|
||
actions += '' + poke.getName() + ' became trapped in the fiery vortex!';
|
||
break;
|
||
case 'magmastorm':
|
||
actions += '' + poke.getName() + ' became trapped by swirling magma!';
|
||
break;
|
||
case 'sandtomb':
|
||
actions += '' + poke.getName() + ' became trapped by the quicksand!';
|
||
break;
|
||
case 'infestation':
|
||
actions += '' + poke.getName() + ' has been afflicted with an infestation by ' + ofpoke.getLowerName() + '!';
|
||
break;
|
||
case 'afteryou':
|
||
actions += '' + poke.getName() + ' took the kind offer!';
|
||
break;
|
||
case 'quash':
|
||
actions += "" + poke.getName() + "'s move was postponed!";
|
||
break;
|
||
case 'powersplit':
|
||
actions += '' + poke.getName() + ' shared its power with the target!';
|
||
break;
|
||
case 'guardsplit':
|
||
actions += '' + poke.getName() + ' shared its guard with the target!';
|
||
break;
|
||
case 'speedswap':
|
||
actions += '' + poke.getName() + ' switched Speed with its target!';
|
||
break;
|
||
case 'ingrain':
|
||
actions += '' + poke.getName() + ' anchored itself with its roots!';
|
||
break;
|
||
case 'matblock':
|
||
actions += '' + Tools.escapeHTML(args[3]) + ' was blocked by the kicked-up mat!';
|
||
break;
|
||
case 'powder':
|
||
actions += 'When the flame touched the powder on the Pokémon, it exploded!';
|
||
break;
|
||
case 'fairylock':
|
||
actions += 'No one will be able to run away during the next turn!';
|
||
break;
|
||
case 'lockon':
|
||
case 'mindreader':
|
||
actions += '' + poke.getName() + ' took aim at ' + ofpoke.getLowerName() + '!';
|
||
break;
|
||
case 'endure':
|
||
actions += '' + poke.getName() + ' endured the hit!';
|
||
break;
|
||
case 'electricterrain':
|
||
actions += '' + poke.getName() + ' surrounds itself with electrified terrain!';
|
||
break;
|
||
case 'mistyterrain':
|
||
actions += '' + poke.getName() + ' surrounds itself with a protective mist!';
|
||
break;
|
||
case 'psychicterrain':
|
||
actions += '' + poke.getName() + ' surrounds itself with psychic terrain!';
|
||
break;
|
||
|
||
// ability activations
|
||
case 'magicbounce':
|
||
case 'magiccoat':
|
||
case 'rebound':
|
||
break;
|
||
case 'wonderguard': // Deprecated, now uses -immune
|
||
this.resultAnim(poke, 'Immune', 'neutral');
|
||
actions += '' + poke.getName() + '\'s Wonder Guard evades the attack!';
|
||
break;
|
||
case 'forewarn':
|
||
if (this.gen >= 5) {
|
||
actions += "It was alerted to " + ofpoke.getLowerName() + "'s " + Tools.escapeHTML(args[3]) + "!";
|
||
ofpoke.markMove(args[3], 0);
|
||
} else {
|
||
actions += "" + poke.getName() + "'s Forewarn alerted it to " + Tools.escapeHTML(args[3]) + "!";
|
||
if (poke.side.foe.active.length === 1) {
|
||
poke.side.foe.active[0].markMove(args[3], 0);
|
||
}
|
||
}
|
||
break;
|
||
case 'mummy':
|
||
var ability = Tools.getAbility(args[3]);
|
||
this.resultAnim(ofpoke, ability.name, 'ability');
|
||
this.animationDelay += 700;
|
||
this.message('', "<small>[" + ofpoke.getName(true) + "'s " + ability.name + "!]</small>");
|
||
ofpoke.markAbility(ability.name);
|
||
this.resultAnim(ofpoke, 'Mummy', 'ability');
|
||
this.message('', "<small>[" + ofpoke.getName(true) + "'s Mummy!]</small>");
|
||
ofpoke.markAbility('Mummy', true);
|
||
actions += "" + ofpoke.getName() + "'s Ability became Mummy!";
|
||
break;
|
||
case 'anticipation': // Deprecated, now uses -ability. This is for replay compatability
|
||
actions += "" + poke.getName() + " shuddered!";
|
||
break;
|
||
case 'lightningrod':
|
||
case 'stormdrain':
|
||
actions += '' + poke.getName() + ' took the attack!';
|
||
break;
|
||
case 'telepathy':
|
||
actions += "" + poke.getName() + " avoids attacks by its ally Pokémon!";
|
||
break;
|
||
case 'stickyhold':
|
||
actions += "" + poke.getName() + "'s item cannot be removed!";
|
||
break;
|
||
case 'suctioncups':
|
||
actions += '' + poke.getName() + ' anchors itself!';
|
||
break;
|
||
case 'symbiosis':
|
||
actions += '' + poke.getName() + ' shared its ' + Tools.getItem(args[3]).name + ' with ' + ofpoke.getLowerName() + '!';
|
||
break;
|
||
case 'aromaveil':
|
||
actions += '' + ofpoke.getName() + ' is protected by an aromatic veil!';
|
||
break;
|
||
case 'flowerveil':
|
||
actions += '' + ofpoke.getName() + ' surrounded itself with a veil of petals!';
|
||
break;
|
||
case 'sweetveil':
|
||
actions += '' + ofpoke.getName() + ' surrounded itself with a veil of sweetness!';
|
||
break;
|
||
case 'battlebond':
|
||
actions += '' + poke.getName() + ' became fully charged due to its bond with its Trainer!';
|
||
break;
|
||
case 'disguise':
|
||
actions += 'Its disguise served it as a decoy!';
|
||
break;
|
||
case 'powerconstruct':
|
||
actions += 'You sense the presence of many!';
|
||
break;
|
||
|
||
// weather activations
|
||
case 'deltastream':
|
||
actions += "The mysterious strong winds weakened the attack!";
|
||
break;
|
||
|
||
// item activations
|
||
case 'custapberry':
|
||
case 'quickclaw':
|
||
//actions += '' + poke.getName() + ' is already preparing its next move!';
|
||
actions += '' + poke.getName() + '\'s ' + effect.name + ' let it move first!';
|
||
break;
|
||
case 'leppaberry':
|
||
actions += '' + poke.getName() + " restored PP to its " + Tools.escapeHTML(args[3]) + " move using Leppa Berry!";
|
||
break;
|
||
case 'focusband':
|
||
poke.item = 'Focus Band';
|
||
actions += '' + poke.getName() + " hung on using its Focus Band!";
|
||
break;
|
||
case 'safetygoggles':
|
||
poke.item = 'Safety Goggles';
|
||
actions += '' + poke.getName() + " is not affected by " + Tools.escapeHTML(args[3]) + " thanks to its Safety Goggles!";
|
||
break;
|
||
default:
|
||
if (kwargs.broken) { // for custom moves that break protection
|
||
this.resultAnim(poke, 'Protection broken', 'bad');
|
||
actions += "It broke through " + poke.getLowerName() + "'s protection!";
|
||
} else if (effect.effectType !== 'Ability') {
|
||
actions += "" + poke.getName() + "'s " + effect.name + " activated!";
|
||
}
|
||
}
|
||
break;
|
||
|
||
case '-sidestart':
|
||
var side = this.getSide(args[1]);
|
||
var effect = Tools.getEffect(args[2]);
|
||
side.addSideCondition(effect);
|
||
|
||
switch (effect.id) {
|
||
case 'stealthrock':
|
||
actions += "Pointed stones float in the air around " + side.getLowerTeamName() + "!";
|
||
break;
|
||
case 'spikes':
|
||
actions += "Spikes were scattered on the ground all around " + side.getLowerTeamName() + "!";
|
||
break;
|
||
case 'toxicspikes':
|
||
actions += "Poison spikes were scattered on the ground all around " + side.getLowerTeamName() + "!";
|
||
break;
|
||
case 'stickyweb':
|
||
actions += "A sticky web spreads out on the ground around " + side.getLowerTeamName() + "!";
|
||
break;
|
||
case 'tailwind':
|
||
actions += "The Tailwind blew from behind " + side.getLowerTeamName() + "!";
|
||
this.updateWeather();
|
||
break;
|
||
case 'auroraveil':
|
||
actions += "Aurora Veil made " + side.getLowerTeamName() + " stronger against physical and special moves!";
|
||
this.updateWeather();
|
||
break;
|
||
case 'reflect':
|
||
actions += "Reflect made " + side.getLowerTeamName() + " stronger against physical moves!";
|
||
this.updateWeather();
|
||
break;
|
||
case 'lightscreen':
|
||
actions += "Light Screen made " + side.getLowerTeamName() + " stronger against special moves!";
|
||
this.updateWeather();
|
||
break;
|
||
case 'safeguard':
|
||
actions += "" + side.getTeamName() + " cloaked itself in a mystical veil!";
|
||
this.updateWeather();
|
||
break;
|
||
case 'mist':
|
||
actions += "" + side.getTeamName() + " became shrouded in mist!";
|
||
this.updateWeather();
|
||
break;
|
||
case 'luckychant':
|
||
actions += 'Lucky Chant shielded ' + side.getLowerTeamName() + ' from critical hits!';
|
||
break;
|
||
case 'firepledge':
|
||
actions += "A sea of fire enveloped " + side.getLowerTeamName() + "!";
|
||
break;
|
||
case 'waterpledge':
|
||
actions += "A rainbow appeared in the sky on " + side.getLowerTeamName() + "'s side!";
|
||
break;
|
||
case 'grasspledge':
|
||
actions += "A swamp enveloped " + side.getLowerTeamName() + "!";
|
||
break;
|
||
default:
|
||
actions += "" + effect.name + " started!";
|
||
break;
|
||
}
|
||
break;
|
||
case '-sideend':
|
||
var side = this.getSide(args[1]);
|
||
var effect = Tools.getEffect(args[2]);
|
||
var from = Tools.getEffect(kwargs.from);
|
||
var ofpoke = this.getPokemon(kwargs.of);
|
||
side.removeSideCondition(effect.name);
|
||
|
||
switch (effect.id) {
|
||
case 'stealthrock':
|
||
actions += "The pointed stones disappeared from around " + side.getLowerTeamName() + "!";
|
||
break;
|
||
case 'spikes':
|
||
actions += "The spikes disappeared from the ground around " + side.getLowerTeamName() + "!";
|
||
break;
|
||
case 'toxicspikes':
|
||
actions += "The poison spikes disappeared from the ground around " + side.getLowerTeamName() + "!";
|
||
break;
|
||
case 'stickyweb':
|
||
actions += "The sticky web has disappeared from the ground around " + side.getLowerTeamName() + "!";
|
||
break;
|
||
case 'tailwind':
|
||
actions += "" + side.getTeamName() + "'s Tailwind petered out!";
|
||
break;
|
||
case 'auroraveil':
|
||
actions += "" + side.getTeamName() + "'s Aurora Veil wore off!";
|
||
break;
|
||
case 'reflect':
|
||
actions += "" + side.getTeamName() + "'s Reflect wore off!";
|
||
break;
|
||
case 'lightscreen':
|
||
actions += "" + side.getTeamName() + "'s Light Screen wore off!";
|
||
break;
|
||
case 'safeguard':
|
||
actions += "" + side.getTeamName() + " is no longer protected by Safeguard!";
|
||
break;
|
||
case 'mist':
|
||
actions += "" + side.getTeamName() + " is no longer protected by mist!";
|
||
break;
|
||
case 'luckychant':
|
||
actions += "" + side.getTeamName() + "'s Lucky Chant wore off!";
|
||
break;
|
||
case 'firepledge':
|
||
actions += "The sea of fire around " + side.getLowerTeamName() + " disappeared!";
|
||
break;
|
||
case 'waterpledge':
|
||
actions += "The rainbow on " + side.getLowerTeamName() + "'s side disappeared!";
|
||
break;
|
||
case 'grasspledge':
|
||
actions += "The swamp around " + side.getLowerTeamName() + " disappeared!";
|
||
break;
|
||
default:
|
||
actions += "" + effect.name + " ended!";
|
||
break;
|
||
}
|
||
break;
|
||
|
||
case '-weather':
|
||
var effect = Tools.getEffect(args[1]);
|
||
var poke = this.getPokemon(kwargs.of);
|
||
var ability = Tools.getEffect(kwargs.from);
|
||
this.changeWeather(effect.name, poke, kwargs.upkeep, ability);
|
||
break;
|
||
|
||
case '-fieldstart':
|
||
var effect = Tools.getEffect(args[1]);
|
||
var poke = this.getPokemon(kwargs.of);
|
||
var fromeffect = Tools.getEffect(kwargs.from);
|
||
if (fromeffect && fromeffect.effectType === 'Ability') {
|
||
this.resultAnim(poke, fromeffect.name, 'ability');
|
||
this.message('', "<small>[" + poke.getName(true) + "'s " + fromeffect.name + "!]</small>");
|
||
poke.markAbility(fromeffect.name);
|
||
}
|
||
var maxTimeLeft = 0;
|
||
if (effect.id in {'electricterrain': 1, 'grassyterrain': 1, 'mistyterrain': 1, 'psychicterrain': 1}) {
|
||
for (var i = this.pseudoWeather.length - 1; i >= 0; i--) {
|
||
var pwName = this.pseudoWeather[i][0];
|
||
if (pwName === 'Electric Terrain' || pwName === 'Grassy Terrain' || pwName === 'Misty Terrain' || pwName === 'Psychic Terrain') {
|
||
this.pseudoWeather.splice(i, 1);
|
||
continue;
|
||
}
|
||
}
|
||
if (this.gen > 6) maxTimeLeft = 8;
|
||
}
|
||
this.addPseudoWeather(effect.name, 5, maxTimeLeft);
|
||
|
||
switch (effect.id) {
|
||
case 'trickroom':
|
||
actions += "" + poke.getName() + ' twisted the dimensions!';
|
||
break;
|
||
case 'wonderroom':
|
||
actions += "It created a bizarre area in which Defense and Sp. Def stats are swapped!";
|
||
break;
|
||
case 'magicroom':
|
||
actions += "It created a bizarre area in which Pokémon's held items lose their effects!";
|
||
break;
|
||
case 'gravity':
|
||
if (!this.fastForward) {
|
||
for (var i = 0; i < this.mySide.active.length; i++) {
|
||
if (this.mySide.active[i]) {
|
||
BattleOtherAnims.gravity.anim(this, [this.mySide.active[i].sprite]);
|
||
}
|
||
if (this.yourSide.active[i]) {
|
||
BattleOtherAnims.gravity.anim(this, [this.yourSide.active[i].sprite]);
|
||
}
|
||
}
|
||
}
|
||
actions += "Gravity intensified!";
|
||
break;
|
||
case 'mudsport':
|
||
actions += "Electricity's power was weakened!";
|
||
break;
|
||
case 'watersport':
|
||
actions += "Fire's power was weakened!";
|
||
break;
|
||
case 'grassyterrain':
|
||
actions += "Grass grew to cover the battlefield!";
|
||
break;
|
||
case 'mistyterrain':
|
||
actions += "Mist swirls around the battlefield!";
|
||
break;
|
||
case 'electricterrain':
|
||
actions += "An electric current runs across the battlefield!";
|
||
break;
|
||
case 'psychicterrain':
|
||
actions += "The battlefield got weird!";
|
||
break;
|
||
default:
|
||
actions += effect.name + " started!";
|
||
break;
|
||
}
|
||
break;
|
||
|
||
case '-fieldend':
|
||
var effect = Tools.getEffect(args[1]);
|
||
var poke = this.getPokemon(kwargs.of);
|
||
this.removePseudoWeather(effect.name, poke);
|
||
|
||
switch (effect.id) {
|
||
case 'trickroom':
|
||
actions += 'The twisted dimensions returned to normal!';
|
||
break;
|
||
case 'wonderroom':
|
||
actions += 'Wonder Room wore off, and Defense and Sp. Def stats returned to normal!';
|
||
break;
|
||
case 'magicroom':
|
||
actions += "Magic Room wore off, and held items' effects returned to normal!";
|
||
break;
|
||
case 'gravity':
|
||
actions += 'Gravity returned to normal!';
|
||
break;
|
||
case 'mudsport':
|
||
actions += 'The effects of Mud Sport have faded.';
|
||
break;
|
||
case 'watersport':
|
||
actions += 'The effects of Water Sport have faded.';
|
||
break;
|
||
case 'grassyterrain':
|
||
actions += "The grass disappeared from the battlefield.";
|
||
break;
|
||
case 'mistyterrain':
|
||
actions += "The mist disappeared from the battlefield.";
|
||
break;
|
||
case 'electricterrain':
|
||
actions += "The electricity disappeared from the battlefield.";
|
||
break;
|
||
case 'psychicterrain':
|
||
actions += "The weirdness disappeared from the battlefield!";
|
||
break;
|
||
default:
|
||
actions += effect.name + " ended!";
|
||
break;
|
||
}
|
||
break;
|
||
|
||
case '-fieldactivate':
|
||
var effect = Tools.getEffect(args[1]);
|
||
switch (effect.id) {
|
||
case 'perishsong':
|
||
actions += 'All Pokémon that heard the song will faint in three turns!';
|
||
this.mySide.updateStatbar();
|
||
this.yourSide.updateStatbar();
|
||
break;
|
||
case 'payday':
|
||
actions += 'Coins were scattered everywhere!';
|
||
break;
|
||
case 'iondeluge':
|
||
actions += 'A deluge of ions showers the battlefield!';
|
||
break;
|
||
default:
|
||
actions += '' + effect.name + ' hit!';
|
||
break;
|
||
}
|
||
break;
|
||
|
||
case '-message':
|
||
actions += Tools.escapeHTML(args[1]);
|
||
break;
|
||
|
||
case '-anim':
|
||
var poke = this.getPokemon(args[1]);
|
||
var move = Tools.getMove(args[2]);
|
||
if (this.checkActive(poke)) return;
|
||
poke2 = this.getPokemon(args[3]);
|
||
poke.sprite.beforeMove();
|
||
kwargs.silent = true;
|
||
this.useMove(poke, move, poke2, kwargs);
|
||
poke.sprite.afterMove();
|
||
break;
|
||
|
||
case '-hint':
|
||
this.message('', '<small>(' + Tools.escapeHTML(args[1]) + ')</small>');
|
||
break;
|
||
|
||
default:
|
||
this.logConsole('Unknown minor: ' + args[0]);
|
||
if (this.errorCallback) this.errorCallback(this);
|
||
break;
|
||
}
|
||
}
|
||
if (actions) {
|
||
this.message('<small>' + actions + '</small>', '');
|
||
}
|
||
};
|
||
/*
|
||
Battle.prototype.parseSpriteData = function (name) {
|
||
var siden = 0,
|
||
foe = false;
|
||
while (true) {
|
||
if (name.substr(0, 6) === 'foeof-') {
|
||
foe = true;
|
||
name = name.substr(6);
|
||
} else if (name.substr(0, 9) === 'switched-') name = name.substr(9);
|
||
else if (name.substr(0, 9) === 'existing-') name = name.substr(9);
|
||
else if (name.substr(0, 4) === 'foe-') {
|
||
siden = this.p2.n;
|
||
name = name.substr(4);
|
||
} else if (name.substr(0, 5) === 'ally-') {
|
||
siden = this.p1.n;
|
||
name = name.substr(5);
|
||
} else break;
|
||
}
|
||
if (name.substr(name.length - 1) === ')') {
|
||
var parenIndex = name.lastIndexOf('(');
|
||
if (parenIndex > 0) {
|
||
var species = name.substr(parenIndex + 1);
|
||
name = species.substr(0, species.length - 1);
|
||
}
|
||
}
|
||
if (foe) siden = (siden ? 0 : 1);
|
||
|
||
var data = Tools.getTemplate(name);
|
||
return data.spriteData[siden];
|
||
};
|
||
*/
|
||
Battle.prototype.parseDetails = function (name, pokemonid, details, output) {
|
||
if (!output) output = {};
|
||
if (!details) details = "";
|
||
output.details = details;
|
||
output.name = name;
|
||
output.species = name;
|
||
output.level = 100;
|
||
output.shiny = false;
|
||
output.gender = '';
|
||
output.ident = (name ? pokemonid : '');
|
||
output.searchid = (name ? (pokemonid + '|' + details) : '');
|
||
var splitDetails = details.split(', ');
|
||
if (splitDetails[splitDetails.length - 1] === 'shiny') {
|
||
output.shiny = true;
|
||
splitDetails.pop();
|
||
}
|
||
if (splitDetails[splitDetails.length - 1] === 'M' || splitDetails[splitDetails.length - 1] === 'F') {
|
||
output.gender = splitDetails[splitDetails.length - 1];
|
||
splitDetails.pop();
|
||
}
|
||
if (splitDetails[1]) {
|
||
output.level = parseInt(splitDetails[1].substr(1), 10) || 100;
|
||
}
|
||
if (splitDetails[0]) {
|
||
output.species = splitDetails[0];
|
||
}
|
||
return output;
|
||
};
|
||
Battle.prototype.parseHealth = function (hpstring, output) {
|
||
if (!output) output = {};
|
||
var hp = hpstring.split(' ');
|
||
var status = hp[1];
|
||
hp = hp[0];
|
||
|
||
// hp parse
|
||
output.hpcolor = '';
|
||
if (hp === '0' || hp === '0.0') {
|
||
output.hp = 0;
|
||
output.zerohp = true;
|
||
} else if (hp.indexOf('/') > 0) {
|
||
var hp = hp.split('/');
|
||
if (isNaN(parseFloat(hp[0])) || isNaN(parseFloat(hp[1]))) {
|
||
return false;
|
||
}
|
||
output.hp = parseFloat(hp[0]);
|
||
output.maxhp = parseFloat(hp[1]);
|
||
if (output.hp > output.maxhp) output.hp = output.maxhp;
|
||
var colorchar = hp[1].substr(hp[1].length - 1);
|
||
if ((colorchar === 'y') || (colorchar === 'g')) {
|
||
output.hpcolor = colorchar;
|
||
}
|
||
if (!output.hp) {
|
||
output.zerohp = true;
|
||
}
|
||
} else if (!isNaN(parseFloat(hp))) {
|
||
output.hp = output.maxhp * parseFloat(hp) / 100;
|
||
}
|
||
|
||
// status parse
|
||
if (!status) {
|
||
output.status = '';
|
||
} else if (status === 'par' || status === 'brn' || status === 'slp' || status === 'frz' || status === 'tox') {
|
||
output.status = status;
|
||
} else if (status === 'psn' && output.status !== 'tox') {
|
||
output.status = status;
|
||
} else if (status === 'fnt') {
|
||
output.hp = 0;
|
||
output.zerohp = true;
|
||
output.fainted = true;
|
||
}
|
||
return output;
|
||
};
|
||
Battle.prototype.getPokemon = function (pokemonid, details) {
|
||
var isNew = false; // if true, don't match any pokemon that already exists (for Team Preview)
|
||
var isSwitch = false; // if true, don't match an active, fainted, or immediately-previously switched-out pokemon
|
||
var isInactive = false; // if true, don't match an active pokemon
|
||
var createIfNotFound = false; // if true, create the pokemon if a match wasn't found
|
||
|
||
if (pokemonid === undefined || pokemonid === '??') return null;
|
||
if (pokemonid.substr(0, 5) === 'new: ') {
|
||
pokemonid = pokemonid.substr(5);
|
||
isNew = true;
|
||
createIfNotFound = true; // obviously
|
||
}
|
||
if (pokemonid.substr(0, 10) === 'switchin: ') {
|
||
pokemonid = pokemonid.substr(10);
|
||
isSwitch = true;
|
||
createIfNotFound = true;
|
||
}
|
||
|
||
var name = pokemonid;
|
||
|
||
var siden = -1;
|
||
var slot = -1; // if there is an explicit slot for this pokemon
|
||
var slotChart = {a: 0, b: 1, c: 2, d: 3, e: 4, f: 5};
|
||
if (name.substr(0, 4) === 'p2: ' || name === 'p2') {
|
||
siden = this.p2.n;
|
||
name = name.substr(4);
|
||
} else if (name.substr(0, 4) === 'p1: ' || name === 'p1') {
|
||
siden = this.p1.n;
|
||
name = name.substr(4);
|
||
} else if (name.substr(0, 2) === 'p2' && name.substr(3, 2) === ': ') {
|
||
slot = slotChart[name.substr(2, 1)];
|
||
siden = this.p2.n;
|
||
name = name.substr(5);
|
||
pokemonid = 'p2: ' + name;
|
||
} else if (name.substr(0, 2) === 'p1' && name.substr(3, 2) === ': ') {
|
||
slot = slotChart[name.substr(2, 1)];
|
||
siden = this.p1.n;
|
||
name = name.substr(5);
|
||
pokemonid = 'p1: ' + name;
|
||
}
|
||
|
||
if (!details) {
|
||
if (siden < 0) return null;
|
||
if (this.sides[siden].active[slot]) return this.sides[siden].active[slot];
|
||
if (slot >= 0) isInactive = true;
|
||
}
|
||
|
||
var searchid = '';
|
||
if (details) searchid = pokemonid + '|' + details;
|
||
|
||
// search p1's pokemon
|
||
if (siden !== this.p2.n && !isNew) {
|
||
if (this.p1.active[slot] && this.p1.active[slot].searchid === searchid && !isSwitch) {
|
||
this.p1.active[slot].slot = slot;
|
||
return this.p1.active[slot];
|
||
}
|
||
for (var i = 0; i < this.p1.pokemon.length; i++) {
|
||
var pokemon = this.p1.pokemon[i];
|
||
if (pokemon.fainted && (isNew || isSwitch)) continue;
|
||
if (isSwitch || isInactive) {
|
||
if (this.p1.active.indexOf(pokemon) >= 0) continue;
|
||
}
|
||
if (isSwitch && pokemon == this.p1.lastPokemon && !this.p1.active[slot]) continue;
|
||
if ((searchid && pokemon.searchid === searchid) || // exact match
|
||
(!pokemon.searchid && pokemon.checkDetails(details)) || // switch-in matches Team Preview entry
|
||
(!searchid && pokemon.ident === pokemonid)) { // name matched, good enough
|
||
if (!pokemon.searchid && createIfNotFound) {
|
||
pokemon.name = name;
|
||
pokemon.searchid = searchid;
|
||
pokemon.ident = pokemonid;
|
||
if (pokemon.needsReplace) {
|
||
pokemon = this.p1.newPokemon(this.parseDetails(name, pokemonid, details), i);
|
||
}
|
||
}
|
||
if (slot >= 0) pokemon.slot = slot;
|
||
return pokemon;
|
||
}
|
||
}
|
||
}
|
||
|
||
// search p2's pokemon
|
||
if (siden !== this.p1.n && !isNew) {
|
||
if (this.p2.active[slot] && this.p2.active[slot].searchid === searchid && !isSwitch) {
|
||
if (slot >= 0) this.p2.active[slot].slot = slot;
|
||
return this.p2.active[slot];
|
||
}
|
||
for (var i = 0; i < this.p2.pokemon.length; i++) {
|
||
var pokemon = this.p2.pokemon[i];
|
||
if (pokemon.fainted && (isNew || isSwitch)) continue;
|
||
if (isSwitch || isInactive) {
|
||
if (this.p2.active.indexOf(pokemon) >= 0) continue;
|
||
}
|
||
if (isSwitch && pokemon == this.p2.lastPokemon && !this.p2.active[slot]) continue;
|
||
if ((searchid && pokemon.searchid === searchid) || // exact match
|
||
(!pokemon.searchid && pokemon.checkDetails(details)) || // switch-in matches Team Preview entry
|
||
(!searchid && pokemon.ident === pokemonid)) { // name matched, good enough
|
||
if (!pokemon.searchid && createIfNotFound) {
|
||
pokemon.name = name;
|
||
pokemon.searchid = searchid;
|
||
pokemon.ident = pokemonid;
|
||
if (pokemon.needsReplace) {
|
||
pokemon = this.p2.newPokemon(this.parseDetails(name, pokemonid, details), i);
|
||
}
|
||
}
|
||
if (slot >= 0) pokemon.slot = slot;
|
||
return pokemon;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (!details || !createIfNotFound) return false;
|
||
|
||
// pokemon not found, create a new pokemon object for it
|
||
|
||
if (siden < 0) throw new Error("Invalid pokemonid passed to getPokemon");
|
||
|
||
var species = name;
|
||
var gender = '';
|
||
var level = 100;
|
||
var shiny = false;
|
||
if (details) {
|
||
var splitDetails = details.split(', ');
|
||
if (splitDetails[splitDetails.length - 1] === 'shiny') {
|
||
shiny = true;
|
||
splitDetails.pop();
|
||
}
|
||
if (splitDetails[splitDetails.length - 1] === 'M' || splitDetails[splitDetails.length - 1] === 'F') {
|
||
gender = splitDetails[splitDetails.length - 1];
|
||
splitDetails.pop();
|
||
}
|
||
if (splitDetails[1]) {
|
||
level = parseInt(splitDetails[1].substr(1), 10) || 100;
|
||
}
|
||
if (splitDetails[0]) {
|
||
species = splitDetails[0];
|
||
}
|
||
}
|
||
if (slot < 0) slot = 0;
|
||
var pokemon = this.sides[siden].newPokemon({
|
||
species: species,
|
||
details: details,
|
||
name: name,
|
||
ident: (name ? pokemonid : ''),
|
||
searchid: (name ? (pokemonid + '|' + details) : ''),
|
||
level: level,
|
||
gender: gender,
|
||
shiny: shiny,
|
||
slot: slot
|
||
});
|
||
return pokemon;
|
||
};
|
||
Battle.prototype.getSide = function (sidename) {
|
||
if (sidename === 'p1' || sidename.substr(0, 3) === 'p1:') return this.p1;
|
||
if (sidename === 'p2' || sidename.substr(0, 3) === 'p2:') return this.p2;
|
||
if (this.mySide.id == sidename) return this.mySide;
|
||
if (this.yourSide.id == sidename) return this.yourSide;
|
||
if (this.mySide.name == sidename) return this.mySide;
|
||
if (this.yourSide.name == sidename) return this.yourSide;
|
||
return {
|
||
name: sidename,
|
||
id: sidename.replace(/ /g, '')
|
||
};
|
||
};
|
||
|
||
Battle.prototype.add = function (command, fastForward) {
|
||
if (this.playbackState === 0) {
|
||
this.playbackState = 1;
|
||
this.activityQueue.push(command);
|
||
} else if (this.playbackState === 4) {
|
||
this.playbackState = 2;
|
||
this.paused = false;
|
||
this.activityQueue.push(command);
|
||
this.activityQueueActive = true;
|
||
this.soundStart();
|
||
if (fastForward) {
|
||
this.fastForwardTo(-1);
|
||
} else {
|
||
this.nextActivity();
|
||
}
|
||
} else {
|
||
this.activityQueue.push(command);
|
||
}
|
||
};
|
||
Battle.prototype.instantAdd = function (command) {
|
||
this.run(command, true);
|
||
this.preemptActivityQueue.push(command);
|
||
this.add(command);
|
||
};
|
||
Battle.prototype.teamPreview = function (start) {
|
||
for (var k = 0; k < 2; k++) {
|
||
var textBuf = '';
|
||
var buf = '';
|
||
var buf2 = '';
|
||
this.spriteElems[k].empty();
|
||
if (!start) {
|
||
this.sides[k].updateSprites();
|
||
continue;
|
||
}
|
||
for (var i = 0; i < this.sides[k].pokemon.length; i++) {
|
||
var pokemon = this.sides[k].pokemon[i];
|
||
|
||
var spriteData = Tools.getSpriteData(pokemon, k, {
|
||
afd: this.tier === "[Seasonal] Fools Festival",
|
||
gen: this.gen
|
||
});
|
||
var y = 0;
|
||
var x = 0;
|
||
if (k) {
|
||
y = 48 + 50 + 3 * (i + 6 - this.sides[k].pokemon.length);
|
||
x = 48 + 180 + 50 * (i + 6 - this.sides[k].pokemon.length);
|
||
} else {
|
||
y = 48 + 200 + 3 * i;
|
||
x = 48 + 100 + 50 * i;
|
||
}
|
||
if (textBuf) textBuf += ' / ';
|
||
textBuf += pokemon.species;
|
||
var url = spriteData.url;
|
||
// if (this.paused) url.replace('/xyani', '/xy').replace('.gif', '.png');
|
||
buf += '<img src="' + url + '" width="' + spriteData.w + '" height="' + spriteData.h + '" style="position:absolute;top:' + Math.floor(y - spriteData.h / 2) + 'px;left:' + Math.floor(x - spriteData.w / 2) + 'px" />';
|
||
buf2 += '<div style="position:absolute;top:' + (y + 45) + 'px;left:' + (x - 40) + 'px;width:80px;font-size:10px;text-align:center;color:#FFF;">';
|
||
if (pokemon.gender === 'F') {
|
||
buf2 += '<img src="' + Tools.resourcePrefix + 'fx/gender-f.png" width="7" height="10" alt="F" style="margin-bottom:-1px" /> ';
|
||
} else if (pokemon.gender === 'M') {
|
||
buf2 += '<img src="' + Tools.resourcePrefix + 'fx/gender-m.png" width="7" height="10" alt="M" style="margin-bottom:-1px" /> ';
|
||
}
|
||
if (pokemon.level !== 100) {
|
||
buf2 += '<span style="text-shadow:#000 1px 1px 0,#000 1px -1px 0,#000 -1px 1px 0,#000 -1px -1px 0"><small>L</small>' + pokemon.level + '</span>';
|
||
}
|
||
if (pokemon.item) {
|
||
buf2 += ' <img src="' + Tools.resourcePrefix + 'fx/item.png" width="8" height="10" alt="F" style="margin-bottom:-1px" />';
|
||
}
|
||
buf2 += '</div>';
|
||
}
|
||
this.sides[k].totalPokemon = i;
|
||
this.sides[k].updateSidebar();
|
||
if (textBuf) {
|
||
this.log('<div class="chat"><strong>' + Tools.escapeHTML(this.sides[k].name) + '\'s team:</strong> <em style="color:#445566;display:block;">' + Tools.escapeHTML(textBuf) + '</em></div>');
|
||
}
|
||
this.spriteElems[k].html(buf + buf2);
|
||
}
|
||
};
|
||
Battle.prototype.runMajor = function (args, kwargs, preempt) {
|
||
switch (args[0]) {
|
||
case 'start':
|
||
this.teamPreview(false);
|
||
this.mySide.active[0] = null;
|
||
this.yourSide.active[0] = null;
|
||
if (this.waitForResult()) return;
|
||
this.start();
|
||
break;
|
||
case 'upkeep':
|
||
this.usesUpkeep = true;
|
||
this.updatePseudoWeatherLeft();
|
||
break;
|
||
case 'turn':
|
||
if (this.endPrevAction()) return;
|
||
this.setTurn(args[1]);
|
||
break;
|
||
case 'tier':
|
||
if (!args[1]) args[1] = '';
|
||
for (var i in kwargs) args[1] += '[' + i + '] ' + kwargs[i];
|
||
this.log('<div style="padding:5px 0"><small>Format:</small> <br /><strong>' + Tools.escapeHTML(args[1]) + '</strong></div>');
|
||
this.tier = args[1];
|
||
if (this.tier === 'Random Battle') {
|
||
this.speciesClause = true;
|
||
}
|
||
break;
|
||
case 'gametype':
|
||
this.gameType = args[1];
|
||
switch (args[1]) {
|
||
default:
|
||
this.mySide.active = [null];
|
||
this.yourSide.active = [null];
|
||
break;
|
||
case 'doubles':
|
||
this.mySide.active = [null, null];
|
||
this.yourSide.active = [null, null];
|
||
break;
|
||
case 'triples':
|
||
case 'rotation':
|
||
this.mySide.active = [null, null, null];
|
||
this.yourSide.active = [null, null, null];
|
||
break;
|
||
}
|
||
break;
|
||
case 'variation':
|
||
this.log('<div><small>Variation: <em>' + Tools.escapeHTML(args[1]) + '</em></small></div>');
|
||
break;
|
||
case 'rule':
|
||
var ruleArgs = args[1].split(': ');
|
||
this.log('<div><small><em>' + Tools.escapeHTML(ruleArgs[0]) + (ruleArgs[1] ? ':' : '') + '</em> ' + Tools.escapeHTML(ruleArgs[1] || '') + '</div>');
|
||
break;
|
||
case 'rated':
|
||
this.rated = true;
|
||
this.log('<div class="rated"><strong>Rated battle</strong></div>');
|
||
break;
|
||
case 'chat':
|
||
case 'c':
|
||
var pipeIndex = args[1].indexOf('|');
|
||
var name = args[1].slice(0, pipeIndex);
|
||
var rank = name.charAt(0);
|
||
if (this.ignoreSpects && (rank === ' ' || rank === '+')) break;
|
||
if (this.ignoreOpponent && (rank === '\u2605' || rank === '\u2606') && toUserid(name) !== app.user.get('userid')) break;
|
||
if (window.app && app.ignore && app.ignore[toUserid(name)] && (rank === ' ' || rank === '+' || rank === '\u2605' || rank === '\u2606')) break;
|
||
var message = args[1].slice(pipeIndex + 1);
|
||
var isHighlighted = window.app && app.rooms && app.rooms[this.roomid].getHighlight(message);
|
||
var parsedMessage = Tools.parseChatMessage(message, name, '', isHighlighted);
|
||
if (!$.isArray(parsedMessage)) parsedMessage = [parsedMessage];
|
||
for (var i = 0; i < parsedMessage.length; i++) {
|
||
if (!parsedMessage[i]) continue;
|
||
this.log(parsedMessage[i], preempt);
|
||
}
|
||
if (isHighlighted) {
|
||
var notifyTitle = "Mentioned by " + name + " in " + this.roomid;
|
||
app.rooms[this.roomid].notifyOnce(notifyTitle, "\"" + message + "\"", 'highlight');
|
||
}
|
||
break;
|
||
case 'chatmsg':
|
||
this.log('<div class="chat">' + Tools.escapeHTML(args[1]) + '</div>', preempt);
|
||
break;
|
||
case 'chatmsg-raw':
|
||
case 'raw':
|
||
case 'html':
|
||
this.log('<div class="chat">' + Tools.sanitizeHTML(args[1]) + '</div>', preempt);
|
||
break;
|
||
case 'error':
|
||
this.log('<div class="chat message-error">' + Tools.escapeHTML(args[1]) + '</div>', preempt);
|
||
break;
|
||
case 'pm':
|
||
this.log('<div class="chat"><strong>' + Tools.escapeHTML(args[1]) + ':</strong> <span class="message-pm"><i style="cursor:pointer" onclick="selectTab(\'lobby\');rooms.lobby.popupOpen(\'' + Tools.escapeHTML(args[2], true) + '\')">(Private to ' + Tools.escapeHTML(args[3]) + ')</i> ' + Tools.parseMessage(args[4], args[1]) + '</span>');
|
||
break;
|
||
case 'askreg':
|
||
this.log('<div class="broadcast-blue"><b>Register an account to protect your ladder rating!</b><br /><button name="register" value="' + Tools.escapeHTML(args[1]) + '"><b>Register</b></button></div>');
|
||
break;
|
||
case 'inactive':
|
||
if (!this.kickingInactive) this.kickingInactive = true;
|
||
if (args[1].slice(0, 9) === "You have ") {
|
||
// this is ugly but parseInt is documented to work this way
|
||
// so I'm going to be lazy and not chop off the rest of the
|
||
// sentence
|
||
this.kickingInactive = parseInt(args[1].slice(9), 10) || true;
|
||
return;
|
||
} else if (args[1].slice(-14) === ' seconds left.') {
|
||
var hasIndex = args[1].indexOf(' has ');
|
||
var userid = (window.app && app.user && app.user.get('userid'));
|
||
if (toId(args[1].slice(0, hasIndex)) === userid) {
|
||
this.kickingInactive = parseInt(args[1].slice(hasIndex + 5), 10) || true;
|
||
}
|
||
}
|
||
this.log('<div class="chat message-error">' + Tools.escapeHTML(args[1]) + '</div>', preempt);
|
||
break;
|
||
case 'inactiveoff':
|
||
this.kickingInactive = false;
|
||
this.log('<div class="chat message-error">' + Tools.escapeHTML(args[1]) + '</div>', preempt);
|
||
break;
|
||
case 'timer':
|
||
break;
|
||
case 'join':
|
||
case 'j':
|
||
if (this.roomid) app.rooms[this.roomid].users[toUserid(args[1])] = ' ' + args[1];
|
||
if (!this.ignoreSpects) {
|
||
this.log('<div class="chat"><small>' + Tools.escapeHTML(args[1]) + ' joined.</small></div>', preempt);
|
||
}
|
||
break;
|
||
case 'leave':
|
||
case 'l':
|
||
if (this.roomid) delete app.rooms[this.roomid].users[toUserid(args[1])];
|
||
if (!this.ignoreSpects) {
|
||
this.log('<div class="chat"><small>' + Tools.escapeHTML(args[1]) + ' left.</small></div>', preempt);
|
||
}
|
||
break;
|
||
case 'J':
|
||
case 'L':
|
||
case 'N':
|
||
case 'n':
|
||
case 'spectator':
|
||
case 'spectatorleave':
|
||
break;
|
||
case 'player':
|
||
this.getSide(args[1]).setName(args[2]);
|
||
this.getSide(args[1]).setSprite(args[3]);
|
||
break;
|
||
case 'teamsize':
|
||
this.getSide(args[1]).totalPokemon = parseInt(args[2], 10);
|
||
this.getSide(args[1]).updateSidebar();
|
||
break;
|
||
case 'win':
|
||
this.winner(args[1]);
|
||
break;
|
||
case 'tie':
|
||
this.winner();
|
||
break;
|
||
case 'prematureend':
|
||
this.prematureEnd();
|
||
break;
|
||
case 'clearpoke':
|
||
this.p1.pokemon = [];
|
||
this.p2.pokemon = [];
|
||
for (var i = 0; i < this.p1.active.length; i++) {
|
||
this.p1.active[i] = null;
|
||
this.p2.active[i] = null;
|
||
}
|
||
break;
|
||
case 'poke':
|
||
var pokemon = this.getPokemon('new: ' + args[1], args[2]);
|
||
if (args[3] === 'item') {
|
||
pokemon.item = '(exists)';
|
||
}
|
||
break;
|
||
case 'detailschange':
|
||
if (this.waitForResult()) return;
|
||
var poke = this.getPokemon(args[1]);
|
||
poke.removeVolatile('formechange');
|
||
poke.removeVolatile('typeadd');
|
||
poke.removeVolatile('typechange');
|
||
|
||
var newSpecies;
|
||
var commaIndex = args[2].indexOf(',');
|
||
if (commaIndex === -1) {
|
||
newSpecies = args[2];
|
||
} else {
|
||
newSpecies = args[2].substr(0, commaIndex);
|
||
}
|
||
var template = Tools.getTemplate(newSpecies);
|
||
var spriteData = {'shiny': poke.sprite.sp.shiny};
|
||
poke.sprite.animTransform($.extend(spriteData, template), true);
|
||
poke.sprite.oldsp = null;
|
||
poke.spriteid = template.spriteid;
|
||
poke.side.updateStatbar();
|
||
|
||
poke.species = newSpecies;
|
||
poke.ability = poke.baseAbility = (template.abilities ? template.abilities['0'] : '');
|
||
poke.baseStats = template.baseStats;
|
||
poke.weightkg = template.weightkg;
|
||
poke.types = template.types && template.types.slice(0);
|
||
|
||
poke.details = args[2];
|
||
poke.searchid = args[1].substr(0, 2) + args[1].substr(3) + '|' + args[2];
|
||
if (poke.statbarElem) {
|
||
poke.statbarElem.html(poke.side.getStatbarHTML(poke, true));
|
||
}
|
||
poke.side.updateStatbar(poke, true);
|
||
poke.side.updateSidebar();
|
||
if (toId(newSpecies) === 'greninjaash') {
|
||
this.message('<small>' + poke.getName() + ' became Ash-Greninja!</small>');
|
||
} else if (toId(newSpecies) === 'mimikyubusted') {
|
||
this.message('<small>' + poke.getName() + "'s disguise was busted!</small>");
|
||
} else if (toId(newSpecies) === 'zygardecomplete') {
|
||
this.message('<small>' + poke.getName() + ' transformed into its Complete Forme!</small>');
|
||
}
|
||
break;
|
||
case 'teampreview':
|
||
this.teamPreview(true);
|
||
this.teamPreviewCount = args[1];
|
||
break;
|
||
case 'switch':
|
||
case 'drag':
|
||
case 'replace':
|
||
this.endLastTurn();
|
||
if (this.waitForResult()) return;
|
||
var poke = this.getPokemon('switchin: ' + args[1], args[2]);
|
||
var slot = poke.slot;
|
||
poke.healthParse(args[3]);
|
||
poke.removeVolatile('itemremoved');
|
||
if (args[0] === 'switch') {
|
||
if (poke.side.active[slot]) {
|
||
poke.side.switchOut(poke.side.active[slot]);
|
||
if (this.waitForResult()) return;
|
||
}
|
||
poke.side.switchIn(poke);
|
||
} else if (args[0] === 'replace') {
|
||
poke.side.replace(poke);
|
||
} else {
|
||
poke.side.dragIn(poke);
|
||
}
|
||
break;
|
||
case 'faint':
|
||
if (this.waitForResult()) return;
|
||
var poke = this.getPokemon(args[1]);
|
||
poke.side.faint(poke);
|
||
break;
|
||
case 'swap':
|
||
if (isNaN(Number(args[2]))) {
|
||
var poke = this.getPokemon(args[1]);
|
||
poke.side.swapWith(poke, this.getPokemon(args[2]), kwargs);
|
||
} else {
|
||
var poke = this.getPokemon(args[1]);
|
||
poke.side.swapTo(poke, args[2], kwargs);
|
||
}
|
||
break;
|
||
case 'move':
|
||
this.endLastTurn();
|
||
if ((!kwargs.from || kwargs.from === 'lockedmove') && this.waitForResult()) return;
|
||
var poke = this.getPokemon(args[1]);
|
||
var move = Tools.getMove(args[2]);
|
||
if (this.checkActive(poke)) return;
|
||
var poke2 = this.getPokemon(args[3]);
|
||
poke.sprite.beforeMove();
|
||
this.useMove(poke, move, poke2, kwargs);
|
||
poke.sprite.afterMove();
|
||
break;
|
||
case 'cant':
|
||
this.endLastTurn();
|
||
if (this.waitForResult()) return;
|
||
var poke = this.getPokemon(args[1]);
|
||
var effect = Tools.getEffect(args[2]);
|
||
var move = Tools.getMove(args[3]);
|
||
this.cantUseMove(poke, effect, move, kwargs);
|
||
break;
|
||
case 'message':
|
||
this.message(Tools.escapeHTML(args[1]));
|
||
break;
|
||
case 'done':
|
||
case '':
|
||
if (this.ended || this.endPrevAction()) return;
|
||
break;
|
||
case 'warning':
|
||
this.message('<strong>Warning:</strong> ' + Tools.escapeHTML(args[1]));
|
||
this.message('Bug? Report it to <a href="http://www.smogon.com/forums/showthread.php?t=3453192">the replay viewer\'s Smogon thread</a>');
|
||
this.activityWait(1000);
|
||
break;
|
||
case 'gen':
|
||
this.gen = parseInt(args[1], 10);
|
||
this.updateGen();
|
||
break;
|
||
case 'callback':
|
||
args.shift();
|
||
if (this.customCallback) this.customCallback(this, args[0], args, kwargs);
|
||
break;
|
||
case 'debug':
|
||
args.shift();
|
||
name = args.join(' ');
|
||
this.log('<div class="debug"><div class="chat"><small style="color:#999">[DEBUG] ' + Tools.escapeHTML(name) + '.</small></div></div>', preempt);
|
||
break;
|
||
case 'seed':
|
||
case 'choice':
|
||
break;
|
||
case 'unlink':
|
||
if (Tools.prefs('nounlink')) return;
|
||
var user = toId(args[2]) || toId(args[1]);
|
||
var $messages = $('.chatmessage-' + user);
|
||
if (!$messages.length) break;
|
||
$messages.find('a').contents().unwrap();
|
||
if (window.BattleRoom && args[2]) {
|
||
$messages.hide().addClass('revealed').find('button').parent().remove();
|
||
this.log('<div class="chatmessage-' + user + '"><button name="toggleMessages" value="' + user + '" class="subtle"><small>(' + $messages.length + ' line' + ($messages.length > 1 ? 's' : '') + ' from ' + user + ' hidden)</small></button></div>');
|
||
}
|
||
break;
|
||
default:
|
||
this.logConsole('unknown command: ' + args[0]);
|
||
this.log('<div>Unknown command: ' + Tools.escapeHTML(args[0]) + '</div>');
|
||
if (this.errorCallback) this.errorCallback(this);
|
||
break;
|
||
}
|
||
};
|
||
Battle.prototype.run = function (str, preempt) {
|
||
if (this.preemptActivityQueue.length && str === this.preemptActivityQueue[0]) {
|
||
this.preemptActivityQueue.shift();
|
||
this.preemptCatchup();
|
||
return;
|
||
}
|
||
if (!str) return;
|
||
if (str.charAt(0) !== '|' || str.substr(0, 2) === '||') {
|
||
if (str.charAt(0) === '|') str = str.substr(2);
|
||
this.log('<div class="chat">' + Tools.escapeHTML(str) + '</div>', preempt);
|
||
return;
|
||
}
|
||
var args = ['done'], kwargs = {};
|
||
if (str !== '|') {
|
||
args = str.substr(1).split('|');
|
||
}
|
||
switch (args[0]) {
|
||
case 'c': case 'chat':
|
||
case 'chatmsg': case 'chatmsg-raw': case 'raw': case 'error': case 'html':
|
||
case 'inactive': case 'inactiveoff': case 'warning':
|
||
// chat is preserved untouched
|
||
args = [args[0], str.slice(args[0].length + 2)];
|
||
break;
|
||
default:
|
||
// parse kwargs
|
||
while (args.length) {
|
||
var argstr = args[args.length - 1];
|
||
if (argstr.substr(0, 1) !== '[') break;
|
||
var bracketPos = argstr.indexOf(']');
|
||
if (bracketPos <= 0) break;
|
||
// default to '.' so it evaluates to boolean true
|
||
kwargs[argstr.substr(1, bracketPos - 1)] = ($.trim(argstr.substr(bracketPos + 1)) || '.');
|
||
args.pop();
|
||
}
|
||
}
|
||
|
||
// parse the next line if it's a minor: runMinor needs it parsed to determine when to merge minors
|
||
var nextLine = '', nextArgs = [''], nextKwargs = {};
|
||
nextLine = this.activityQueue[this.activityStep + 1] || '';
|
||
if (nextLine && nextLine.substr(0, 2) === '|-') {
|
||
nextLine = $.trim(nextLine.substr(1));
|
||
nextArgs = nextLine.split('|');
|
||
while (nextArgs[nextArgs.length - 1] && nextArgs[nextArgs.length - 1].substr(0, 1) === '[') {
|
||
var bracketPos = nextArgs[nextArgs.length - 1].indexOf(']');
|
||
if (bracketPos <= 0) break;
|
||
var argstr = nextArgs.pop();
|
||
// default to '.' so it evaluates to boolean true
|
||
nextKwargs[argstr.substr(1, bracketPos - 1)] = ($.trim(argstr.substr(bracketPos + 1)) || '.');
|
||
}
|
||
}
|
||
|
||
if (this.debug) {
|
||
if (args[0].substr(0, 1) === '-') {
|
||
this.runMinor(args, kwargs, preempt, nextArgs, nextKwargs);
|
||
} else {
|
||
this.runMajor(args, kwargs, preempt);
|
||
}
|
||
} else try {
|
||
if (args[0].substr(0, 1) === '-') {
|
||
this.runMinor(args, kwargs, preempt, nextArgs, nextKwargs);
|
||
} else {
|
||
this.runMajor(args, kwargs, preempt);
|
||
}
|
||
} catch (e) {
|
||
this.log('<div class="chat">Error parsing: ' + Tools.escapeHTML(str) + ' (' + Tools.escapeHTML('' + e) + ')</div>', preempt);
|
||
if (e.stack) {
|
||
var stack = Tools.escapeHTML('' + e.stack).split('\n');
|
||
for (var i = 0; i < stack.length; i++) {
|
||
if (/\brun\b/.test(stack[i])) {
|
||
stack.length = i;
|
||
break;
|
||
}
|
||
}
|
||
this.log('<div class="chat">' + stack.join('<br>') + '</div>', preempt);
|
||
}
|
||
if (this.errorCallback) this.errorCallback(this);
|
||
}
|
||
|
||
if (this.fastForward > 0 && this.fastForward < 1) {
|
||
if (nextLine.substr(0, 6) === '|start') {
|
||
this.fastForwardOff();
|
||
if (this.endCallback) this.endCallback(this);
|
||
}
|
||
}
|
||
};
|
||
Battle.prototype.endPrevAction = function () {
|
||
if (this.minorQueue.length) {
|
||
this.runMinor();
|
||
this.activityStep--;
|
||
return true;
|
||
}
|
||
if (this.resultWaiting || this.messageActive) {
|
||
this.endAction();
|
||
this.activityStep--;
|
||
this.resultWaiting = false;
|
||
this.multiHitMove = null;
|
||
this.activeMoveIsSpread = null;
|
||
return true;
|
||
}
|
||
return false;
|
||
};
|
||
Battle.prototype.checkActive = function (poke) {
|
||
if (!poke.side.active[poke.slot]) {
|
||
// SOMEONE jumped in in the middle of a replay. <_<
|
||
poke.side.replace(poke);
|
||
}
|
||
return false;
|
||
};
|
||
Battle.prototype.waitForResult = function () {
|
||
if (this.endPrevAction()) return true;
|
||
this.resultWaiting = true;
|
||
return false;
|
||
};
|
||
Battle.prototype.doBeforeThis = function (act) {
|
||
if (act()) {
|
||
this.activityStep--;
|
||
return true;
|
||
}
|
||
return false;
|
||
};
|
||
Battle.prototype.doAfterThis = function (act) {
|
||
this.activityAfter = act;
|
||
};
|
||
|
||
Battle.prototype.queue1 = function () {
|
||
if (this.activeQueue === this.queue1) this.nextActivity();
|
||
};
|
||
Battle.prototype.queue2 = function () {
|
||
if (this.activeQueue === this.queue2) this.nextActivity();
|
||
};
|
||
Battle.prototype.swapQueues = function () {
|
||
if (this.activeQueue === this.queue1) this.activeQueue = this.queue2;
|
||
else this.activeQueue = this.queue2;
|
||
};
|
||
|
||
Battle.prototype.pause = function () {
|
||
this.elem.find(':animated').finish();
|
||
this.paused = true;
|
||
this.playbackState = 3;
|
||
if (this.resumeButton) {
|
||
this.frameElem.append('<div class="playbutton"><button data-action="resume"><i class="fa fa-play icon-play"></i> Resume</button></div>');
|
||
this.frameElem.find('div.playbutton button').click(this.resumeButton);
|
||
}
|
||
this.soundPause();
|
||
};
|
||
Battle.prototype.play = function (dontResetSound) {
|
||
if (this.fastForward) {
|
||
this.paused = false;
|
||
this.playbackState = 5;
|
||
} else if (this.paused) {
|
||
this.paused = false;
|
||
if (!dontResetSound && this.playbackState === 1) {
|
||
this.soundStop();
|
||
}
|
||
this.playbackState = 2;
|
||
if (!dontResetSound && !this.ended) {
|
||
this.soundStart();
|
||
}
|
||
this.nextActivity();
|
||
}
|
||
this.frameElem.find('div.playbutton').remove();
|
||
};
|
||
Battle.prototype.skipTurn = function () {
|
||
this.fastForwardTo(this.turn + 1);
|
||
};
|
||
Battle.prototype.fastForwardTo = function (time) {
|
||
this.playbackState = 5;
|
||
if (this.fastForward) return;
|
||
if (time === 0 || time === '0') {
|
||
time = 0.5;
|
||
} else {
|
||
time = Math.floor(Number(time));
|
||
}
|
||
if (isNaN(time)) return;
|
||
if (this.activityStep >= this.activityQueue.length - 1 && time >= this.turn + 1 && !this.activityQueueActive) return;
|
||
if (this.ended && time >= this.turn + 1) return;
|
||
this.messagebarElem.empty().css({
|
||
opacity: 0,
|
||
height: 0
|
||
});
|
||
if (time <= this.turn && time !== -1) {
|
||
var paused = this.paused;
|
||
this.reset(true);
|
||
this.activityQueueActive = true;
|
||
if (paused) this.pause();
|
||
else this.paused = false;
|
||
if (time) {
|
||
this.fastForward = time;
|
||
this.fastForwardWillScroll = true;
|
||
this.elem.append('<div class="seeking"><strong>seeking...</strong></div>');
|
||
$.fx.off = true;
|
||
}
|
||
this.elem.find(':animated').finish();
|
||
this.swapQueues();
|
||
this.nextActivity();
|
||
return;
|
||
}
|
||
this.fxElem.empty();
|
||
this.fastForward = time;
|
||
this.fastForwardWillScroll = (this.logFrameElem.scrollTop() + 60 >= this.logElem.height() + this.logPreemptElem.height() - this.optionsElem.height() - this.logFrameElem.height());
|
||
this.elem.append('<div class="seeking"><strong>seeking...</strong></div>');
|
||
$.fx.off = true;
|
||
this.elem.find(':animated').finish();
|
||
if (this.yourSide.active[0] && this.yourSide.active[0].sprite) {
|
||
this.yourSide.active[0].sprite.animReset();
|
||
}
|
||
if (this.mySide.active[0] && this.mySide.active[0].sprite) {
|
||
this.mySide.active[0].sprite.animReset();
|
||
}
|
||
this.swapQueues();
|
||
this.nextActivity();
|
||
};
|
||
Battle.prototype.fastForwardOff = function () {
|
||
this.fastForward = false;
|
||
this.elem.find('.seeking').remove();
|
||
$.fx.off = false;
|
||
if (this.p1) this.p1.updateStatbar(null, true, true);
|
||
if (this.p2) this.p2.updateStatbar(null, true, true);
|
||
this.updateWeather(undefined, true);
|
||
if (this.fastForwardWillScroll) {
|
||
this.logFrameElem.scrollTop(this.logElem.height() + this.logPreemptElem.height());
|
||
this.fastForwardWillScroll = false;
|
||
}
|
||
if (!this.paused) this.soundStart();
|
||
this.playbackState = 2;
|
||
};
|
||
Battle.prototype.nextActivity = function () {
|
||
if (this.paused && !this.fastForward) {
|
||
return;
|
||
}
|
||
this.activityQueueActive = true;
|
||
this.fxElem.empty();
|
||
this.animationDelay = 0;
|
||
while (true) {
|
||
this.activityAnimations = $();
|
||
if (this.activityStep >= this.activityQueue.length) {
|
||
this.activityQueueActive = false;
|
||
this.paused = true;
|
||
this.fastForwardOff();
|
||
if (this.ended) {
|
||
this.soundStop();
|
||
}
|
||
this.playbackState = 4;
|
||
if (this.endCallback) this.endCallback(this);
|
||
return;
|
||
}
|
||
var ret;
|
||
if (this.activityAfter) {
|
||
ret = this.activityAfter();
|
||
this.activityAfter = null;
|
||
}
|
||
if (this.paused && !this.fastForward) return;
|
||
if (!ret) {
|
||
this.run(this.activityQueue[this.activityStep]);
|
||
this.activityStep++;
|
||
}
|
||
if (this.activityDelay) {
|
||
this.delayElem.delay(this.activityDelay);
|
||
this.activityWait(this.delayElem);
|
||
this.activityDelay = 0;
|
||
}
|
||
if (this.activityAnimations.length) break;
|
||
}
|
||
var self = this;
|
||
this.activityAnimations.promise().done(this.activeQueue.bind(this));
|
||
};
|
||
Battle.prototype.activityWait = function (elem) {
|
||
if (typeof elem === 'number' && elem > this.activityDelay) {
|
||
this.activityDelay = elem;
|
||
return;
|
||
}
|
||
this.activityAnimations = this.activityAnimations.add(elem);
|
||
};
|
||
|
||
Battle.prototype.newBattle = function () {
|
||
this.reset();
|
||
this.activityQueue = [];
|
||
};
|
||
Battle.prototype.setQueue = function (queue) {
|
||
this.reset();
|
||
this.activityQueue = queue;
|
||
|
||
/* for (var i = 0; i < queue.length && i < 20; i++) {
|
||
if (queue[i].substr(0, 8) === 'pokemon ') {
|
||
var sp = this.parseSpriteData(queue[i].substr(8));
|
||
BattleSound.loadEffect(sp.cryurl);
|
||
this.preloadImage(sp.url);
|
||
if (sp.url === '/sprites/bwani/meloetta.gif') {
|
||
this.preloadImage('/sprites/bwani/meloetta-pirouette.gif');
|
||
}
|
||
if (sp.url === '/sprites/bwani-back/meloetta.gif') {
|
||
this.preloadImage('/sprites/bwani-back/meloetta-pirouette.gif');
|
||
}
|
||
}
|
||
} */
|
||
this.playbackState = 1;
|
||
};
|
||
|
||
Battle.prototype.preloadImage = function (url) {
|
||
var token = url.replace(/\.(gif|png)$/, '').replace(/\//g, '-');
|
||
if (this.preloadCache[token]) {
|
||
return;
|
||
}
|
||
this.preloadNeeded++;
|
||
this.preloadCache[token] = new Image();
|
||
var self = this;
|
||
this.preloadCache[token].onload = function () {
|
||
self.preloadDone++;
|
||
self.preloadCallback(self.preloadNeeded === self.preloadDone, self.preloadDone, self.preloadNeeded);
|
||
};
|
||
this.preloadCache[token].src = url;
|
||
};
|
||
Battle.prototype.preloadCallback = function () {};
|
||
Battle.prototype.preloadEffects = function () {
|
||
for (var i in BattleEffects) {
|
||
if (i === 'alpha' || i === 'omega') continue;
|
||
if (BattleEffects[i].url) this.preloadImage(BattleEffects[i].url);
|
||
}
|
||
this.preloadImage(Tools.fxPrefix + 'weather-raindance.jpg'); // rain is used often enough to precache
|
||
this.preloadImage(Tools.resourcePrefix + 'sprites/xyani/substitute.gif');
|
||
this.preloadImage(Tools.resourcePrefix + 'sprites/xyani-back/substitute.gif');
|
||
//this.preloadImage(Tools.fxPrefix + 'bg.jpg');
|
||
};
|
||
Battle.prototype.dogarsCheck = function (pokemon) {
|
||
if (pokemon.side.n === 1) return;
|
||
|
||
if (pokemon.species === 'Koffing' && pokemon.name.match(/dogars/i)) {
|
||
if (window.forceBgm !== -1) {
|
||
window.originalBgm = window.bgmNum;
|
||
window.forceBgm = -1;
|
||
this.preloadBgm();
|
||
this.soundStart();
|
||
}
|
||
} else if (window.forceBgm === -1) {
|
||
window.forceBgm = null;
|
||
if (window.originalBgm || window.originalBgm === 0) {
|
||
window.forceBgm = window.originalBgm;
|
||
}
|
||
this.preloadBgm();
|
||
this.soundStart();
|
||
}
|
||
};
|
||
Battle.prototype.preloadBgm = function () {
|
||
var bgmNum = Math.floor(Math.random() * 13);
|
||
|
||
if (window.forceBgm || window.forceBgm === 0) bgmNum = window.forceBgm;
|
||
window.bgmNum = bgmNum;
|
||
var ext = window.nodewebkit ? '.ogg' : '.mp3';
|
||
switch (bgmNum) {
|
||
case -1:
|
||
BattleSound.loadBgm('audio/bw2-homika-dogars' + ext, 1661, 68131);
|
||
this.bgm = 'audio/bw2-homika-dogars' + ext;
|
||
break;
|
||
case 0:
|
||
BattleSound.loadBgm('audio/hgss-kanto-trainer' + ext, 13003, 94656);
|
||
this.bgm = 'audio/hgss-kanto-trainer' + ext;
|
||
break;
|
||
case 1:
|
||
BattleSound.loadBgm('audio/bw-subway-trainer' + ext, 15503, 110984);
|
||
this.bgm = 'audio/bw-subway-trainer' + ext;
|
||
break;
|
||
case 2:
|
||
BattleSound.loadBgm('audio/bw-trainer' + ext, 14629, 110109);
|
||
this.bgm = 'audio/bw-trainer' + ext;
|
||
break;
|
||
case 3:
|
||
BattleSound.loadBgm('audio/bw-rival' + ext, 19180, 57373);
|
||
this.bgm = 'audio/bw-rival' + ext;
|
||
break;
|
||
case 4:
|
||
BattleSound.loadBgm('audio/dpp-trainer' + ext, 13440, 96959);
|
||
this.bgm = 'audio/dpp-trainer' + ext;
|
||
break;
|
||
case 5:
|
||
BattleSound.loadBgm('audio/hgss-johto-trainer' + ext, 23731, 125086);
|
||
this.bgm = 'audio/hgss-johto-trainer' + ext;
|
||
break;
|
||
case 6:
|
||
BattleSound.loadBgm('audio/dpp-rival' + ext, 13888, 66352);
|
||
this.bgm = 'audio/dpp-rival' + ext;
|
||
break;
|
||
case 7:
|
||
BattleSound.loadBgm('audio/bw2-kanto-gym-leader' + ext, 14626, 58986);
|
||
this.bgm = 'audio/bw2-kanto-gym-leader' + ext;
|
||
break;
|
||
case 8:
|
||
BattleSound.loadBgm('audio/bw2-rival' + ext, 7152, 68708);
|
||
this.bgm = 'audio/bw2-rival' + ext;
|
||
break;
|
||
case 9:
|
||
BattleSound.loadBgm('audio/xy-trainer' + ext, 7802, 82469);
|
||
this.bgm = 'audio/xy-trainer' + ext;
|
||
break;
|
||
case 10:
|
||
BattleSound.loadBgm('audio/xy-rival' + ext, 7802, 58634);
|
||
this.bgm = 'audio/xy-rival' + ext;
|
||
break;
|
||
case 11:
|
||
BattleSound.loadBgm('audio/oras-trainer' + ext, 13579, 91548);
|
||
this.bgm = 'audio/oras-trainer' + ext;
|
||
break;
|
||
case 12:
|
||
BattleSound.loadBgm('audio/sm-trainer' + ext, 8323, 89230);
|
||
this.bgm = 'audio/sm-trainer' + ext;
|
||
break;
|
||
case 13:
|
||
BattleSound.loadBgm('audio/sm-rival' + ext, 11389, 62158);
|
||
this.bgm = 'audio/sm-rival' + ext;
|
||
break;
|
||
default:
|
||
BattleSound.loadBgm('audio/oras-rival' + ext, 14303, 69149);
|
||
this.bgm = 'audio/oras-rival' + ext;
|
||
break;
|
||
}
|
||
};
|
||
Battle.prototype.setMute = function (mute) {
|
||
BattleSound.setMute(mute);
|
||
};
|
||
Battle.prototype.soundStart = function () {
|
||
if (!this.bgm) this.preloadBgm();
|
||
BattleSound.playBgm(this.bgm);
|
||
};
|
||
Battle.prototype.soundStop = function () {
|
||
BattleSound.stopBgm();
|
||
};
|
||
Battle.prototype.soundPause = function () {
|
||
BattleSound.pauseBgm();
|
||
};
|
||
|
||
return Battle;
|
||
})();
|