(function() { if (this.PokeBattle == null) { this.PokeBattle = {}; } PokeBattle.battles = null; PokeBattle.events = {}; _.extend(PokeBattle.events, Backbone.Events); }).call(this); (function() { PokeBattle.events.once("ready", function() { var $loading; $loading = $(".loading-container"); return $loading.fadeOut(function() { return $loading.remove(); }); }); }).call(this); (function() { Backbone.Associations.EVENTS_NC = true; }).call(this); (function() { var __slice = [].slice; this.makeBiasedRng = function(battle) { var biasedRNGFuncs, funcName, _fn, _i, _len, _ref; biasedRNGFuncs = {}; _ref = ['next', 'randInt']; _fn = (function(_this) { return function(funcName) { var oldFunc; oldFunc = battle.rng[funcName].bind(battle.rng); return battle.rng[funcName] = function() { var args, func, id; args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; id = args[args.length - 1]; func = biasedRNGFuncs[funcName]; return (id in func ? func[id] : oldFunc.apply(null, args)); }; }; })(this); for (_i = 0, _len = _ref.length; _i < _len; _i++) { funcName = _ref[_i]; _fn(funcName); } return battle.rng.bias = function(funcName, id, returns) { biasedRNGFuncs[funcName] || (biasedRNGFuncs[funcName] = {}); return biasedRNGFuncs[funcName][id] = returns; }; }; }).call(this); (function() { var CannedText, allTexts, cannedMap, cannedMapReverse, cannedTextName, cannedTextNames, cannedTexts, counter, generation, generationName, i, language, _i, _j, _len, _len1, _ref, __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; CannedText = { bw: { en: { MOVE_MISS: "$p avoided the attack!", MOVE_FAIL: "But it failed!", SUPER_EFFECTIVE: "It's super effective!", NOT_VERY_EFFECTIVE: "It's not very effective...", CRITICAL_HIT: "A critical hit!", GOT_HIT: "$p took $1% damage!", DRAIN: "$p had its energy drained!", ABSORB: "$p absorbed some HP!", NO_TARGET: "But there was no target...", RECOIL: "$p was hit by recoil!", IMMUNITY: "But it doesn't affect $p...", FLINCH: "$p flinched!", IS_CONFUSED: "$p is confused!", CONFUSION_START: "$p became confused!", CONFUSION_END: "$p snapped out of confusion!", CONFUSION_HURT_SELF: "$p hurt itself in confusion!", FATIGUE: "$p became confused due to fatigue!", NO_MOVES_LEFT: "$p has no moves left!", NO_PP_LEFT: "But there was no PP left for the move!", SUN_START: "The sunlight turned harsh!", RAIN_START: "It started to rain!", SAND_START: "A sandstorm kicked up!", HAIL_START: "It started to hail!", SUN_END: "The sunlight faded.", RAIN_END: "The rain stopped.", SAND_END: "The sandstorm subsided.", HAIL_END: "The hail stopped.", SAND_CONTINUE: "The sandstorm rages.", HAIL_CONTINUE: "The hail crashes down.", SAND_HURT: "$p is buffeted by the sandstorm!", HAIL_HURT: "$p is buffeted by the hail!", DISABLE_START: "$p's $m was disabled!", DISABLE_CONTINUE: "$p's $m is disabled!", DISABLE_END: "$p is no longer disabled!", YAWN_BEGIN: "$p grew drowsy!", TAUNT_START: "$p fell for the taunt!", TAUNT_PREVENT: "$p can't use $m after the taunt!", TAUNT_END: "$p's taunt wore off!", WISH_END: "$1's wish came true!", PERISH_SONG_START: "All Pokemon hearing the song will faint in three turns!", PERISH_SONG_CONTINUE: "$p's perish count fell to $1!", TAILWIND_END: "The tailwind petered out!", ENCORE_END: "$p's Encore ended!", TORMENT_START: "$p was subjected to Torment!", SPIKES_START: "Spikes were scattered all around $ts's feet!", SPIKES_HURT: "$p is hurt by the spikes!", SPIKES_END: "The spikes disappeared from around $ts's feet!", STEALTH_ROCK_START: "Pointed stones float in the air around $ts!", STEALTH_ROCK_HURT: "Pointed stones dug into $p!", STEALTH_ROCK_END: "The pointed stones disappeared from around $ts!", TOXIC_SPIKES_START: "Poison spikes were scattered all around $ts's feet!", TOXIC_SPIKES_END: "The poison spikes disappeared from around $ts's feet!", TRAP_HURT: "$p is hurt by $m!", LEECH_SEED_START: "$p was seeded!", LEECH_SEED_HURT: "$p's health is sapped by Leech Seed!", PROTECT_CONTINUE: "$p protected itself!", DESTINY_BOND_START: "$p is trying to take its foe down with it!", DESTINY_BOND_CONTINUE: "$p took its attacker down with it!", SUBSTITUTE_START: "$p put in a substitute!", SUBSTITUTE_EXISTS: "$p already has a substitute!", SUBSTITUTE_WEAK: "It was too weak to make a substitute!", SUBSTITUTE_END: "$p's substitute faded!", SUBSTITUTE_HURT: "The substitute took damage for $p!", BOUNCE_MOVE: "$p bounced the $m back!", TRICK_ROOM_START: "$p twisted the dimensions!", TRICK_ROOM_END: "The twisted dimensions returned to normal!", PARALYZE_START: '$p was paralyzed!', FREEZE_START: '$p was frozen!', POISON_START: '$p was poisoned!', TOXIC_START: '$p was badly poisoned!', SLEEP_START: '$p fell asleep!', BURN_START: '$p was burned!', PARALYZE_CONTINUE: '$p is fully paralyzed!', FREEZE_CONTINUE: "$p is frozen solid!", POISON_CONTINUE: "$p was hurt by poison!", SLEEP_CONTINUE: "$p is fast asleep.", BURN_CONTINUE: "$p was hurt by its burn!", RECOVER_HP: "$p's HP was restored.", TRICK_START: "$p switched items with its target!", TRICK_END: "$p obtained one $i!", THIEF_START: "$p stole $p's $i!", RESET_STATS: "$p's stat changes were removed!", RESET_ALL_STATS: "All stat changes were eliminated!", JUMP_KICK_MISS: "$p kept going and crashed!", FREE_FROM: "$p was freed from $1!", TRANSFORM: '$p transformed!', TRANSFORM_INTO: '$p transformed into $p!', TRANSFORM_TYPE: "$p transformed into the $y type!", ACQUIRE_ABILITY: "$p acquired $a!", REFLECT_START: "Reflect raised $ts's defense!", LIGHT_SCREEN_START: "Light Screen raised $ts's special defense!", REFLECT_END: "$ts's Reflect wore off!", LIGHT_SCREEN_END: "$ts's Light Screen wore off!", STICKY_WEB_START: "A sticky web has been laid out beneath $ts's feet!", STICKY_WEB_CONTINUE: "$p was caught in a sticky web!", STICKY_WEB_END: "The sticky web has disappeared from beneath $ts's feet!", RATING_UPDATE: "$t's rating: $1 -> $2", KNOCK_OFF: "$p knocked off $p's $i!", PAIN_SPLIT: "The battlers shared their pain!", PAY_DAY: "Coins were scattered everywhere!", PSYCH_UP: "$p copied $p's stat changes!", MENTAL_HERB: "$p used its Mental Herb to come back to its senses!", WHITE_HERB: "$p restored its status using its White Herb!", RED_CARD: "$p held up its Red Card against $p!", EJECT_BUTTON: "$p is switched out with the Eject Button!", HANG_ON: "$p hung on using its $i!", MOVE_FIRST: "$p's $i let it move first!", SAFEGUARD_START: "$t's team became cloaked in a mystical veil!", SAFEGUARD_END: "$t's Safeguard wore off!", ITEM_RESTORE: "$p restored a little HP using its $i!", ITEM_WEAKEN: "The $i weakened the damage to $p!", POKEMON_HURT_BY_ITEM: "$p is hurt by $p's $i!", ITEM_SELF_HURT: "$p is hurt by its $i!", POKEMON_HURT: "$p is hurt!", BERRY_RESTORE: "$p restored its health using its $i!", BERRY_RAISE_STAT: "The $i raised $p's $1!", GEM_BOOST: "The $i strengthened $m's power!", ENDURE: "$p endured the hit!", ANCHOR: "$p anchors itself!", AVOID_ALLIES: "$p avoids attacks by its ally Pokemon!", TRACE: "It traced the foe's $a!", TRUANT: "$p is loafing around!", WEATHER_DISABLED: "The effects of weather disappeared.", MOLD_BREAKER: "$p breaks the mold!", TERAVOLT: "$p is radiating a bursting aura!", TURBOBLAZE: "$p is radiating a blazing aura!", ANTICIPATION: "$p shuddered!", BAD_DREAMS: "$p is tormented!", COLOR_CHANGE: "$p's Color Change made it the $1 type!", FLASH_FIRE: "The power of $p's Fire-type moves rose!", FOREWARN: "It was alerted to $p's $m!", FRISK: "$p frisked its target and found one $i!", HARVEST: "$p harvested one $i!", PRESSURE: "$p is exerting its pressure!", MUMMY: "$p's ability became Mummy!", PICKPOCKET: "$p stole $p's $i!", SLOW_START_START: "$p can't get it going!", SLOW_START_END: "$p finally got its act together!", WITHDREW: "$t withdrew $p!", SENT_OUT: "$t sent out $p!", SWAP_ABILITY: "$p swapped Abilities with its target!", TELEKINESIS_START: "$p was hurled into the air!", TELEKINESIS_END: "$p was freed from the telekinesis!", HEAL_BLOCK_START: "$p was prevented from healing!", HEAL_BLOCK_END: "$p's Heal Block wore off!", HEAL_BLOCK_PREVENT: "$p can't use $m because of Heal Block!", HEAL_BLOCK_TRY_HEAL: "$p was prevented from healing due to Heal Block!", HEAL_BLOCK_FAIL: "But it failed to affect $p!", FOUND_ITEM: "$p found one $i!", MOON_START: "$p's Noctem darkened the sky!", MOON_END: "The sky brightened again.", MOON_CONTINUE: "The sky is dark.", LIVEWIRE_START: "A wire was set at the feet of the foe", LIVEWIRE_END: "$p absorbed the Livewire!", LIVEWIRE_HURT: "$p was shocked by the Livewire!", LIVEWIRE_MISS: "$p avoided the Livewire!", FIRE_ROCK_START: "Molten rocks float in the air around $ts!", FIRE_ROCK_HURT: "$p is hurt by molten rocks!", FIRE_ROCK_END: "The molten rocks disappeared from around $ts!", ILLUSION_BROKE: "The foes $p broke it's illusion!" } } }; cannedMap = {}; cannedMapReverse = {}; allTexts = []; counter = 0; cannedTextNames = []; for (generationName in CannedText) { generation = CannedText[generationName]; for (language in generation) { cannedTexts = generation[language]; _ref = Object.keys(cannedTexts); for (_i = 0, _len = _ref.length; _i < _len; _i++) { cannedTextName = _ref[_i]; if (__indexOf.call(cannedTextNames, cannedTextName) < 0) { cannedTextNames.push(cannedTextName); } } } } cannedTextNames.sort(); for (i = _j = 0, _len1 = cannedTextNames.length; _j < _len1; i = ++_j) { cannedTextName = cannedTextNames[i]; counter = i + 1; cannedMap[cannedTextName] = counter; cannedMapReverse[counter] = cannedTextName; } this.CannedText = cannedMap; this.CannedMap = CannedText; this.CannedMapReverse = cannedMapReverse; }).call(this); (function() { var self, _base; self = (typeof window !== "undefined" && window !== null ? (_base = window.PokeBattle).conditions != null ? _base.conditions : _base.conditions = {} : this); this.Conditions = { TEAM_PREVIEW: 1, RATED_BATTLE: 2, PBV_1000: 3, TIMED_BATTLE: 4, SLEEP_CLAUSE: 5, SPECIES_CLAUSE: 6, EVASION_CLAUSE: 7, OHKO_CLAUSE: 8, UNRELEASED_BAN: 9, PRANKSTER_SWAGGER_CLAUSE: 10, PBV_500: 11, VISIBLE_TEAM: 12, TIER_LC: 13, TIER_PU: 14, TIER_NU: 15, TIER_RU: 16, TIER_UU: 17, TIER_OU: 18, TIER_Uber: 19 }; this.SelectableConditions = [this.Conditions.VISIBLE_TEAM, this.Conditions.TIMED_BATTLE, this.Conditions.SLEEP_CLAUSE, this.Conditions.EVASION_CLAUSE, this.Conditions.SPECIES_CLAUSE, this.Conditions.PRANKSTER_SWAGGER_CLAUSE, this.Conditions.OHKO_CLAUSE, this.Conditions.UNRELEASED_BAN]; this.HumanizedConditions = { en: { VISIBLE_TEAM: "Visible Teams", TEAM_PREVIEW: "Team Preview", SLEEP_CLAUSE: "Sleep Clause", RATED_BATTLE: "Rated Battle", TIMED_BATTLE: "Timed Battle", SPECIES_CLAUSE: "Species Clause", EVASION_CLAUSE: "Evasion Clause", OHKO_CLAUSE: "One-Hit KO Clause", UNRELEASED_BAN: "Unreleased Ban", PRANKSTER_SWAGGER_CLAUSE: "Prankster + Swagger Clause" } }; self.PresetFormats = { insur1000: { name: 'insur1000', humanName: 'Insurgence 1000', generation: 'in', conditions: [this.Conditions.PBV_1000, this.Conditions.TEAM_PREVIEW], playable: true, priority: 5, tierBased: false }, xy1000: { name: 'xy1000', humanName: '1,000 PBV XY', generation: 'xy', conditions: [this.Conditions.PBV_1000, this.Conditions.TEAM_PREVIEW], playable: true, priority: 10, tierBased: false }, xy500: { name: 'xy500', humanName: '500 PBV XY', generation: 'xy', conditions: [this.Conditions.PBV_500, this.Conditions.TEAM_PREVIEW], playable: true, priority: 10, tierBased: false } }; this.GenerationCondition = { 'in': { conditionname: 'insur', humanName: 'Insurgence' } }; self.Formats_ = {}; self.Formats = function() { if (Object.keys(this.Formats_).length === 0) { this.setFormats(); return this.Formats_; } else { return this.Formats_; } }; self.setFormats = function() { var Tiers, conditions, finalobj, format, formatname, gen, humanname, key, newformats, playablegens, priority, sortedformatsarr, tier, tierData, tierbased, _, _conditions, _i, _j, _len, _len1; playablegens = ['in']; newformats = this.PresetFormats; if (typeof window !== "undefined" && window !== null) { Tiers = window.PokeBattle.Tier.Tiers; conditions = Conditions; _ = window._; } else { Tiers = require('./tier').Tiers; conditions = this.Conditions; _ = require('underscore')._; } for (key in conditions) { if ((key.search(/TIER_/)) === 0) { tier = key.replace(/TIER_/, ""); tierData = Tiers[tier]; if (tierData.playable) { for (_i = 0, _len = playablegens.length; _i < _len; _i++) { gen = playablegens[_i]; tierbased = true; if (typeof window !== "undefined" && window !== null) { formatname = GenerationCondition[gen].conditionname + tier; _conditions = [Conditions[key], Conditions.TEAM_PREVIEW]; priority = tierData.priority; humanname = "" + GenerationCondition[gen].humanName + " " + tierData.humanName; } else { formatname = this.GenerationCondition[gen].conditionname + tier; _conditions = [this.Conditions[key], this.Conditions.TEAM_PREVIEW]; priority = tierData.priority; humanname = "" + this.GenerationCondition[gen].humanName + " " + tierData.humanName; } newformats[formatname] = { name: formatname, humanName: humanname, generation: gen, conditions: _conditions, priority: priority, tierBased: tierbased }; } } } } sortedformatsarr = _.sortBy(newformats, 'priority'); finalobj = {}; for (_j = 0, _len1 = sortedformatsarr.length; _j < _len1; _j++) { format = sortedformatsarr[_j]; finalobj[format.name] = format; } return this.Formats_ = finalobj; }; this.DEFAULT_FORMAT = 'insurOU'; }).call(this); (function() { var error, errors, i, self, _i, _len, _ref; self = (typeof module !== "undefined" && module !== null ? module.exports : void 0) || (window.PokeBattle.errors = {}); errors = "FIND_BATTLE\nBATTLE_DNE\nINVALID_SESSION\nBANNED\nCOMMAND_ERROR\nPRIVATE_MESSAGE\nINVALID_ALT_NAME"; _ref = errors.trim().split(/\s+/); for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) { error = _ref[i]; self[error] = i + 1; } }).call(this); (function() { var self; self = (typeof module !== "undefined" && module !== null ? module.exports : window.HiddenPower != null ? window.HiddenPower : window.HiddenPower = {}); if (self.BW == null) { self.BW = {}; } self.BW.types = ['Fighting', 'Flying', 'Poison', 'Ground', 'Rock', 'Bug', 'Ghost', 'Steel', 'Fire', 'Water', 'Grass', 'Electric', 'Psychic', 'Ice', 'Dragon', 'Dark']; self.BW.basePower = function(ivs) { var base; base = 0; if (ivs['hp'] % 4 > 1) { base += 1; } if (ivs['attack'] % 4 > 1) { base += 2; } if (ivs['defense'] % 4 > 1) { base += 4; } if (ivs['speed'] % 4 > 1) { base += 8; } if (ivs['specialAttack'] % 4 > 1) { base += 16; } if (ivs['specialDefense'] % 4 > 1) { base += 32; } return Math.floor(base * (40 / 63) + 30); }; self.BW.type = function(ivs) { var value; value = 0; if (ivs['hp'] % 2 === 1) { value += 1; } if (ivs['attack'] % 2 === 1) { value += 2; } if (ivs['defense'] % 2 === 1) { value += 4; } if (ivs['speed'] % 2 === 1) { value += 8; } if (ivs['specialAttack'] % 2 === 1) { value += 16; } if (ivs['specialDefense'] % 2 === 1) { value += 32; } return self.BW.types[Math.floor(value * 15 / 63)]; }; self.BW.ivs = { bug: { attack: 30, defense: 30, specialDefense: 30 }, dark: {}, dragon: { attack: 30 }, electric: { specialAttack: 30 }, fighting: { defense: 30, specialAttack: 30, specialDefense: 30, speed: 30 }, fire: { attack: 30, specialAttack: 30, speed: 30 }, flying: { hp: 30, attack: 30, defense: 30, specialAttack: 30, specialDefense: 30 }, ghost: { defense: 30, specialDefense: 30 }, grass: { attack: 30, specialAttack: 30 }, ground: { specialAttack: 30, specialDefense: 30 }, ice: { attack: 30, defense: 30 }, poison: { defense: 30, specialAttack: 30, specialDefense: 30 }, psychic: { attack: 30, speed: 30 }, rock: { defense: 30, specialDefense: 30, speed: 30 }, steel: { specialDefense: 30 }, water: { attack: 30, defense: 30, specialAttack: 30 } }; }).call(this); (function() { var gen, i, _i, _j, _len, _len1, _ref, _ref1; this.ALL_GENERATIONS = ['rb', 'gs', 'rs', 'dp', 'bw', 'xy', 'in']; this.SUPPORTED_GENERATIONS = ['xy', 'in']; this.DEFAULT_GENERATION = 'in'; this.INT_TO_GENERATION = {}; _ref = this.ALL_GENERATIONS; for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) { gen = _ref[i]; this.INT_TO_GENERATION[i + 1] = gen; } this.GENERATION_TO_INT = {}; _ref1 = this.ALL_GENERATIONS; for (i = _j = 0, _len1 = _ref1.length; _j < _len1; i = ++_j) { gen = _ref1[i]; this.GENERATION_TO_INT[gen] = i + 1; } }).call(this); (function() { var EventPokemon, INT_TO_GENERATION, checkMove, getGenerationFromInt, getMinimumGeneration, loopLearnsets, mustLearnMove, self, switchableFormes, unportableGenerations, unsketchableMoves, _, _ref, __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; self = (typeof module !== "undefined" && module !== null ? module.exports : void 0) || window; if (typeof module !== "undefined" && module !== null ? module.exports : void 0) { EventPokemon = require('./event_pokemon'); INT_TO_GENERATION = require('./ladders').INT_TO_GENERATION; _ = require('underscore')._; } else { EventPokemon = (_ref = window.EventPokemon) != null ? _ref : {}; INT_TO_GENERATION = window.INT_TO_GENERATION; _ = window._; } unportableGenerations = [1, 3]; unportableGenerations.sort(function(a, b) { return b - a; }); switchableFormes = ["Deoxys", "Rotom", "Shaymin"]; unsketchableMoves = ["Chatter", "Hyperspace Hole", "Light of Ruin", "Steam Eruption", "Struggle", "Thousand Arrows", "Thousand Waves"]; mustLearnMove = { "Mamoswine": "AncientPower", "Yanmega": "AncientPower", "Tangrowth": "AncientPower", "Mr. Mime": "Mimic", "Sudowoodo": "Mimic", "Ambipom": "Double Hit", "Lickilicky": "Rollout" }; getMinimumGeneration = function(generation) { var minGeneration, unportableGen, _i, _len; for (_i = 0, _len = unportableGenerations.length; _i < _len; _i++) { unportableGen = unportableGenerations[_i]; if (unportableGen <= generation) { return unportableGen; } } minGeneration = Math.min.apply(Math, unportableGenerations); throw new Error("Gen. '" + generation + "' must be greater than " + minGeneration + "."); }; getGenerationFromInt = function(generationInteger) { return INT_TO_GENERATION[generationInteger].toUpperCase(); }; loopLearnsets = function(Generations, pokemon, forGeneration, iterator) { var FormeData, SpeciesData, ability, finalForme, forme, formeName, generation, hasHiddenAbility, learnset, minimumGeneration, species, theFormes, thePokemon, _i, _j, _k, _len, _len1, _ref1; minimumGeneration = getMinimumGeneration(forGeneration); species = pokemon.species, forme = pokemon.forme, ability = pokemon.ability; formeName = forme || "default"; thePokemon = []; theFormes = [formeName]; _ref1 = Generations[getGenerationFromInt(forGeneration)], SpeciesData = _ref1.SpeciesData, FormeData = _ref1.FormeData; finalForme = FormeData[species][formeName]; while (species) { thePokemon.push(species); if (__indexOf.call(switchableFormes, species) >= 0 && __indexOf.call(theFormes, species) < 0) { theFormes.push.apply(theFormes, (function() { var _results; _results = []; for (forme in FormeData[species]) { _results.push(forme); } return _results; })()); } species = SpeciesData[species].evolvedFrom; } if (ability == null) { ability = finalForme.abilities[0]; } hasHiddenAbility = ability === finalForme.hiddenAbility && __indexOf.call(finalForme.abilities, ability) < 0; for (_i = 0, _len = thePokemon.length; _i < _len; _i++) { species = thePokemon[_i]; for (_j = 0, _len1 = theFormes.length; _j < _len1; _j++) { formeName = theFormes[_j]; for (generation = _k = minimumGeneration; minimumGeneration <= forGeneration ? _k <= forGeneration : _k >= forGeneration; generation = minimumGeneration <= forGeneration ? ++_k : --_k) { FormeData = Generations[getGenerationFromInt(generation)].FormeData; if (FormeData[species] == null) { continue; } if (!(formeName in FormeData[species])) { formeName = "default"; } forme = FormeData[species][formeName]; if (!forme.learnset) { formeName = "default"; } learnset = forme.learnset; if (!learnset) { continue; } if (hasHiddenAbility && (forme.hiddenAbility == null)) { continue; } if (iterator(learnset, species, formeName, generation) === true) { return true; } } } } return false; }; self.learnableMoves = function(Generations, pokemon, forGeneration) { var learnable; learnable = []; loopLearnsets(Generations, pokemon, forGeneration, function(learnset, pokemonSpecies, formeName) { var event, events, method, moveName, moves, _i, _len, _ref1, _results; events = EventPokemon[pokemonSpecies] || []; events = events.filter(function(event) { return event.forme === formeName; }); for (_i = 0, _len = events.length; _i < _len; _i++) { event = events[_i]; learnable.push(event.moves); } for (method in learnset) { moves = learnset[method]; if ((method === 'level-up' || method === 'tutor' || method === 'machine' || method === 'egg') || ((pokemon.forme || "default") === formeName)) { learnable.push((function() { var _results; _results = []; for (moveName in moves) { _results.push(moveName); } return _results; })()); } } if ((_ref1 = learnset["level-up"]) != null ? _ref1["Sketch"] : void 0) { _results = []; for (moveName in Generations[getGenerationFromInt(forGeneration)].MoveData) { if (__indexOf.call(unsketchableMoves, moveName) < 0) { _results.push(learnable.push(moveName)); } else { _results.push(void 0); } } return _results; } }); return _.chain(learnable).flatten().sort().unique().value(); }; self.checkMoveset = function(Generations, pokemon, generation, moves) { var FormeData, checksOut, eggMoves, forme, learnset, leftoverMoves, level, looper, lsetLeftovers, m, move, nonstandardGroups, pokemonForme, pokemonLevel, pokemonSpecies, rsForme, _ref1, _ref2, _ref3; looper = loopLearnsets.bind(null, Generations, pokemon, generation); pokemonSpecies = pokemon.species; pokemonForme = pokemon.forme || "default"; pokemonLevel = pokemon.level || 100; FormeData = Generations[getGenerationFromInt(generation)].FormeData; forme = FormeData[pokemonSpecies][pokemonForme]; if (generation === 4) { rsForme = ((_ref1 = Generations.DP.FormeData[pokemonSpecies]) != null ? _ref1[pokemonForme] : void 0) || {}; learnset = ((_ref2 = rsForme.learnset) != null ? _ref2['form-change'] : void 0) || {}; for (move in learnset) { level = learnset[move]; if (__indexOf.call(moves, move) < 0 || pokemonLevel < level) { return false; } } } leftoverMoves = (function() { var _i, _len, _results; _results = []; for (_i = 0, _len = moves.length; _i < _len; _i++) { m = moves[_i]; if (!checkMove(looper, pokemon, m)) { _results.push(m); } } return _results; })(); learnset = ((_ref3 = forme.learnset) != null ? _ref3['form-change'] : void 0) || {}; lsetLeftovers = leftoverMoves.filter(function(move) { return pokemonLevel >= learnset[move]; }); if (lsetLeftovers.length === leftoverMoves.length) { return true; } checksOut = looper(function(learnset, pokemonSpecies, formeName) { var event, events, _i, _len; events = EventPokemon[pokemonSpecies] || []; events = events.filter(function(event) { return event.forme === formeName; }); for (_i = 0, _len = events.length; _i < _len; _i++) { event = events[_i]; lsetLeftovers = leftoverMoves.filter(function(move) { return __indexOf.call(event.moves, move) >= 0 && pokemonLevel >= event.level; }); if (lsetLeftovers.length === leftoverMoves.length) { return true; } } }); if (checksOut) { return true; } nonstandardGroups = ["light-ball-egg", "stadium-surfing-pikachu"]; checksOut = looper(function(learnset) { var group, total, _i, _len; for (_i = 0, _len = nonstandardGroups.length; _i < _len; _i++) { group = nonstandardGroups[_i]; if (!learnset[group]) { continue; } total = ((function() { var _j, _len1, _results; _results = []; for (_j = 0, _len1 = leftoverMoves.length; _j < _len1; _j++) { m = leftoverMoves[_j]; if (m in learnset[group]) { _results.push(m); } } return _results; })()).length; if (total === leftoverMoves.length) { return true; } } }); if (checksOut) { return true; } checksOut = looper(function(learnset) { var dreamWorldMoves, moveName; if (!learnset['dreamWorld']) { return; } dreamWorldMoves = []; for (moveName in learnset['dreamWorld']) { if (__indexOf.call(dreamWorldMoves, moveName) >= 0 || __indexOf.call(leftoverMoves, moveName) < 0) { continue; } dreamWorldMoves.push(moveName); } if (leftoverMoves.length === dreamWorldMoves.length) { return true; } }); if (checksOut) { return true; } eggMoves = []; looper(function(learnset) { var moveName, _results; if (!learnset['egg']) { return; } _results = []; for (moveName in learnset['egg']) { if (__indexOf.call(eggMoves, moveName) >= 0 || __indexOf.call(leftoverMoves, moveName) < 0) { continue; } _results.push(eggMoves.push(moveName)); } return _results; }); if (eggMoves.length === 4 && mustLearnMove[pokemon.species]) { return false; } if (eggMoves.length === leftoverMoves.length) { return true; } return false; }; checkMove = function(looper, pokemon, move) { var checksOut, level; level = pokemon.level; level || (level = 100); checksOut = looper(function(learnset) { var _ref1, _ref2, _ref3, _ref4; if (((_ref1 = learnset["level-up"]) != null ? _ref1[move] : void 0) <= level || ((_ref2 = learnset["machine"]) != null ? _ref2[move] : void 0) <= level || ((_ref3 = learnset["tutor"]) != null ? _ref3[move] : void 0) <= level) { return true; } if (((_ref4 = learnset["level-up"]) != null ? _ref4["Sketch"] : void 0) <= level && __indexOf.call(unsketchableMoves, move) < 0) { return true; } }); if (checksOut) { return true; } return false; }; }).call(this); (function() { var BATON_PASS_PBV, self, _base, __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; self = (typeof window !== "undefined" && window !== null ? (_base = window.PokeBattle).PBV != null ? _base.PBV : _base.PBV = {} : this); BATON_PASS_PBV = 15; self.determinePBV = function(genData, pokemonArray) { var bpers, forme, item, mega, megaForme, megaSpecies, p, pbv, pokemon, species, speciesData, total, _i, _len, _ref, _ref1; if (!(pokemonArray instanceof Array)) { pokemonArray = [pokemonArray]; } total = 0; for (_i = 0, _len = pokemonArray.length; _i < _len; _i++) { pokemon = pokemonArray[_i]; species = pokemon.species; forme = pokemon.forme || "default"; item = pokemon.item; speciesData = genData != null ? genData.FormeData[species] : void 0; mega = genData != null ? (_ref = genData.ItemData[item]) != null ? _ref.mega : void 0 : void 0; if (mega) { megaSpecies = mega[0], megaForme = mega[1]; if (species === megaSpecies) { forme = megaForme; } } pbv = (speciesData != null ? (_ref1 = speciesData[forme]) != null ? _ref1.pokeBattleValue : void 0 : void 0) || 0; if (item === 'Eviolite') { pbv = Math.round(1.3 * pbv / 5) * 5; } total += pbv; } bpers = (function() { var _j, _len1, _results; _results = []; for (_j = 0, _len1 = pokemonArray.length; _j < _len1; _j++) { p = pokemonArray[_j]; if (__indexOf.call(p.moves || [], "Baton Pass") >= 0) { _results.push(p); } } return _results; })(); if (bpers.length > 0) { total += BATON_PASS_PBV * Math.pow(2, bpers.length - 1); } return total; }; }).call(this); (function() { this.Protocol = { CHANGE_HP: 1, SWITCH_IN: 2, CHANGE_PP: 3, REQUEST_ACTIONS: 4, START_TURN: 5, RAW_MESSAGE: 6, FAINT: 7, MAKE_MOVE: 8, END_BATTLE: 9, FORFEIT_BATTLE: 10, MOVE_SUCCESS: 11, SWITCH_OUT: 12, POKEMON_ATTACH: 13, TEAM_ATTACH: 14, BATTLE_ATTACH: 15, POKEMON_UNATTACH: 16, TEAM_UNATTACH: 17, BATTLE_UNATTACH: 18, START_BATTLE: 19, RECEIVE_TEAM: 20, CHANGE_EXACT_HP: 21, SPRITE_CHANGE: 22, BOOSTS: 23, RESET_BOOSTS: 24, MOVESET_UPDATE: 26, TEAM_PREVIEW: 27, INITIALIZE: 28, REARRANGE_TEAMS: 29, TIMER_WIN: 30, WEATHER_CHANGE: 32, ACTIVATE_ABILITY: 35, CANNED_TEXT: 36, CONTINUE_TURN: 37, BATTLE_EXPIRED: 38, SET_BOOSTS: 39, END_MOVE: 40, NAME_CHANGE: 41, ILLUSION_CHANGE: 42, VISIBLE_TEAM: 43 }; }).call(this); (function() { var Tiers, actualtiers, conditions, self, _, _base, _ref; self = (typeof window !== "undefined" && window !== null ? (_base = window.PokeBattle).Tier != null ? _base.Tier : _base.Tier = {} : this); if (typeof window === "undefined" || window === null) { Tiers = require('./conditions').Tiers; _ = require('underscore')._; actualtiers = Tiers; } else { conditions = (_ref = window.conditions) != null ? _ref : {}; actualtiers = Tiers; _ = window._; } self.Tiers = { Unsorted: { name: "Unsorted", humanName: "Unsorted", tierRank: -1, playable: false }, PA: { name: "PA", humanName: "Pathetic", tierRank: 0, playable: false }, LC: { name: "LC", humanName: "Little Cup", tierRank: 1, playable: false }, PU: { name: "PU", humanName: "Poorly Used", tierRank: 2, playable: false }, NU: { name: "NU", humanName: "Never Used", tierRank: 3, playable: false }, RU: { name: "RU", humanName: "Rarely Used", tierRank: 4, playable: false }, UU: { name: "UU", humanName: "Under Used", tierRank: 5, playable: true, priority: 1 }, OU: { name: "OU", humanName: "Over Used", tierRank: 6, playable: true, priority: 0 }, Uber: { name: "Uber", humanName: "Ubers", tierRank: 7, playable: true, priority: 2 }, AG: { name: "AG", humanName: "Anything Goes", tierRank: 8, playable: false } }; self.determineTier = function(genData, pokemonArray) { var actualtier, forme, item, mega, megaForme, megaSpecies, pokemon, species, speciesData, tier, tierdata, tierrank, _i, _len, _ref1, _ref2; actualtiers = this.Tiers; if (!(pokemonArray instanceof Array)) { pokemonArray = [pokemonArray]; } tierrank = -1; for (_i = 0, _len = pokemonArray.length; _i < _len; _i++) { pokemon = pokemonArray[_i]; species = pokemon.species; forme = pokemon.forme || "default"; item = pokemon.item; speciesData = genData != null ? genData.FormeData[species] : void 0; mega = genData != null ? (_ref1 = genData.ItemData[item]) != null ? _ref1.mega : void 0 : void 0; if (mega) { megaSpecies = mega[0], megaForme = mega[1]; if (species === megaSpecies) { forme = megaForme; } } tier = (speciesData != null ? (_ref2 = speciesData[forme]) != null ? _ref2.tier[0] : void 0 : void 0) || 'Unsorted'; tierdata = actualtiers[tier]; if (typeof tierdata === 'undefined') { tierdata = actualtiers['Unsorted']; } if (tierdata.tierRank > tierrank) { tierrank = tierdata.tierRank; } } actualtier = _.findWhere(actualtiers, { tierRank: tierrank }); return actualtier; }; }).call(this); (function() { var self; self = (typeof module !== "undefined" && module !== null ? module.exports : void 0) || window; self.Weather = { SUN: 'Sun', RAIN: 'Rain', HAIL: 'Hail', SAND: 'Sand', NONE: 'None', MOON: 'Moon', DELTASTREAM: 'DeltaStream', HARSHSUN: 'HarshSun' }; }).call(this); (function() { var _base; if (this.PokeBattle == null) { this.PokeBattle = {}; } if ((_base = this.PokeBattle).mixins == null) { _base.mixins = {}; } }).call(this); (function() { var __slice = [].slice; this.PokeBattle.mixins.BattleProtocolParser = { update: function(actions) { var hadStuff, _ref; if (actions.length === 0) { return; } this.notify(); hadStuff = this.updateQueue.length > 0; (_ref = this.updateQueue).push.apply(_ref, actions); if (!hadStuff) { return this._update(); } }, _update: function(wasAtBottom) { var ability, action, arrangements, attachment, boosts, cannedInteger, change, deltaBoosts, done, doneSpeedTimeout, doneTimeout, e, effect, forfeiter, fromSlot, key, message, moveIndex, moveName, movesetJSON, newForme, newHP, newName, newPP, newPercent, newSpecies, newWeather, player, pokemon, protocol, queue, rest, slot, targetSlots, team, teams, toSlot, turn, type, validActions, value, view, winner, _ref; view = this.view; queue = this.updateQueue; if (!queue) { return; } if (queue.length === 0) { view.renderUserInfo(); view.resetPopovers(); if (wasAtBottom || (view.skip != null)) { view.chatView.scrollToBottom(); } if (view.skip != null) { delete view.skip; view.$('.battle_pane').show(); } return; } wasAtBottom || (wasAtBottom = view.chatView.isAtBottom()); action = queue.shift(); type = action[0], rest = 2 <= action.length ? __slice.call(action, 1) : []; protocol = ((function() { var _results; _results = []; for (key in Protocol) { value = Protocol[key]; if (value === type) { _results.push(key); } } return _results; })())[0]; try { if (window.localStorage.debug === 'true') { console.log("Received protocol: " + protocol + " with args: " + rest); } } catch (_error) { } done = (function(_this) { return function() { if (done.called) { return; } done.called = true; if (view.skip != null) { return _this._update.call(_this, wasAtBottom); } else { return setTimeout(_this._update.bind(_this, wasAtBottom), 0); } }; })(this); doneTimeout = function() { return setTimeout(done, 0); }; doneSpeedTimeout = (function(_this) { return function() { if ((view.skip != null) || view.speed <= 1) { return done(); } else { return setTimeout(done, (view.speed - 1) * 1000); } }; })(this); try { switch (type) { case Protocol.CHANGE_HP: player = rest[0], slot = rest[1], newPercent = rest[2]; pokemon = this.getPokemon(player, slot); pokemon.set('percent', newPercent); if (view.skip != null) { done(); } else { setTimeout(done, 500); } break; case Protocol.CHANGE_EXACT_HP: player = rest[0], slot = rest[1], newHP = rest[2]; pokemon = this.getPokemon(player, slot); pokemon.set('hp', newHP); done(); break; case Protocol.SWITCH_OUT: player = rest[0], slot = rest[1]; view.switchOut(player, slot, done); break; case Protocol.SWITCH_IN: player = rest[0], toSlot = rest[1], fromSlot = rest[2]; team = this.getTeam(player).get('pokemon').models; _ref = [team[fromSlot], team[toSlot]], team[toSlot] = _ref[0], team[fromSlot] = _ref[1]; view.switchIn(player, toSlot, fromSlot, doneSpeedTimeout); break; case Protocol.CHANGE_PP: player = rest[0], slot = rest[1], moveIndex = rest[2], newPP = rest[3]; pokemon = this.getPokemon(player, slot); pokemon.setPP(moveIndex, newPP); done(); break; case Protocol.REQUEST_ACTIONS: validActions = rest[0]; view.enableButtons(validActions); PokeBattle.notifyUser(PokeBattle.NotificationTypes.ACTION_REQUESTED, this.id + "_" + this.get('turn')); done(); break; case Protocol.START_TURN: turn = rest[0]; view.beginTurn(turn, doneTimeout); break; case Protocol.CONTINUE_TURN: view.continueTurn(doneTimeout); break; case Protocol.RAW_MESSAGE: message = rest[0]; view.addLog("" + message + "
"); done(); break; case Protocol.FAINT: player = rest[0], slot = rest[1]; view.faint(player, slot, done); break; case Protocol.MAKE_MOVE: player = rest[0], slot = rest[1], moveName = rest[2]; view.logMove(player, slot, moveName, done); break; case Protocol.END_BATTLE: winner = rest[0]; view.announceWinner(winner, done); break; case Protocol.FORFEIT_BATTLE: forfeiter = rest[0]; view.announceForfeit(forfeiter, done); break; case Protocol.TIMER_WIN: winner = rest[0]; view.announceTimer(winner, done); break; case Protocol.BATTLE_EXPIRED: view.announceExpiration(done); break; case Protocol.MOVE_SUCCESS: player = rest[0], slot = rest[1], targetSlots = rest[2], moveName = rest[3]; view.moveSuccess(player, slot, targetSlots, moveName, done); break; case Protocol.CANNED_TEXT: cannedInteger = rest.splice(0, 1); view.parseCannedText(cannedInteger, rest, done); break; case Protocol.EFFECT_END: player = rest[0], slot = rest[1], effect = rest[2]; view.endEffect(player, slot, effect, done); break; case Protocol.POKEMON_ATTACH: player = rest[0], slot = rest[1], attachment = rest[2]; view.attachPokemon(player, slot, attachment, done); break; case Protocol.TEAM_ATTACH: player = rest[0], attachment = rest[1]; view.attachTeam(player, attachment, done); break; case Protocol.BATTLE_ATTACH: attachment = rest[0]; view.attachBattle(attachment, done); break; case Protocol.POKEMON_UNATTACH: player = rest[0], slot = rest[1], attachment = rest[2]; view.unattachPokemon(player, slot, attachment, done); break; case Protocol.TEAM_UNATTACH: player = rest[0], attachment = rest[1]; view.unattachTeam(player, attachment, done); break; case Protocol.BATTLE_UNATTACH: attachment = rest[0]; view.unattachBattle(attachment, done); break; case Protocol.INITIALIZE: teams = rest[0]; this.receiveTeams(teams); view.preloadImages(); if (!this.get('spectating')) { PokeBattle.notifyUser(PokeBattle.NotificationTypes.BATTLE_STARTED, this.id); } done(); break; case Protocol.START_BATTLE: view.removeTeamPreview(); view.renderBattle(); done(); break; case Protocol.REARRANGE_TEAMS: arrangements = rest; this.get('teams').forEach(function(team, i) { return team.rearrange(arrangements[i]); }); done(); break; case Protocol.RECEIVE_TEAM: team = rest[0]; this.receiveTeam(team); done(); break; case Protocol.SPRITE_CHANGE: player = rest[0], slot = rest[1], newSpecies = rest[2], newForme = rest[3]; pokemon = this.getPokemon(player, slot); pokemon.set('species', newSpecies); pokemon.set('forme', newForme); view.changeSprite(player, slot, newSpecies, newForme, done); break; case Protocol.NAME_CHANGE: player = rest[0], slot = rest[1], newName = rest[2]; pokemon = this.getPokemon(player, slot); view.changeName(player, slot, newName, done); break; case Protocol.BOOSTS: player = rest[0], slot = rest[1], deltaBoosts = rest[2]; view.boost(player, slot, deltaBoosts, { floatText: true }); done(); break; case Protocol.SET_BOOSTS: player = rest[0], slot = rest[1], boosts = rest[2]; view.setBoosts(player, slot, boosts); done(); break; case Protocol.RESET_BOOSTS: player = rest[0], slot = rest[1]; view.resetBoosts(player, slot); done(); break; case Protocol.MOVESET_UPDATE: player = rest[0], slot = rest[1], movesetJSON = rest[2]; pokemon = this.getPokemon(player, slot); pokemon.set(movesetJSON); done(); break; case Protocol.WEATHER_CHANGE: newWeather = rest[0]; view.changeWeather(newWeather, done); break; case Protocol.TEAM_PREVIEW: view.renderTeamPreview(); done(); break; case Protocol.ACTIVATE_ABILITY: player = rest[0], slot = rest[1], ability = rest[2]; pokemon = this.getPokemon(player, slot); pokemon.set('ability', ability); view.activateAbility(player, slot, ability, done); break; case Protocol.END_MOVE: doneSpeedTimeout(); break; case Protocol.ILLUSION_CHANGE: player = rest[0], slot = rest[1], change = rest[2]; pokemon = this.getPokemon(player, slot); pokemon.setIllu(change); done(); break; case Protocol.VISIBLE_TEAM: view.setVisibleTeam(); break; default: done(); } } catch (_error) { e = _error; console.error(e); console.error(e.stack); done(); } if (wasAtBottom && !view.chatView.isAtBottom()) { return view.chatView.scrollToBottom(); } } }; }).call(this); (function() { var MINUS, PLUS, natures, statAbbreviations, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; this.Pokemon = (function(_super) { __extends(Pokemon, _super); function Pokemon() { this.getTeam = __bind(this.getTeam, this); this.defaults = __bind(this.defaults, this); return Pokemon.__super__.constructor.apply(this, arguments); } Pokemon.prototype.defaults = function() { return { moves: [], percent: 100, ivs: { hp: 31, attack: 31, defense: 31, specialAttack: 31, specialDefense: 31, speed: 31 }, evs: { hp: 0, attack: 0, defense: 0, specialAttack: 0, specialDefense: 0, speed: 0 } }; }; Pokemon.prototype.initialize = function(attributes) { var genders, hiddenPowerType; if (attributes == null) { attributes = {}; } if (!this.has('species') && this.has('name')) { this.set('species', this.get('name')); } if (!this.has('forme')) { this.set('forme', 'default'); } this.set('illu', false); this.normalizeStats(this.get('ivs'), 31); this.normalizeStats(this.get('evs'), 0); this.resetBoosts(); this.isNull = false; if (this.get('teambuilder') !== true) { return; } this.on('change:ivs', (function(_this) { return function(model, ivs) { var type; type = HiddenPower.BW.type(ivs).toLowerCase(); return _this.set("hiddenPowerType", type, { silent: true }); }; })(this)); this.on('change:hiddenPowerType', (function(_this) { return function(model, type) { var hpIVs, iv, ivs, stat; hpIVs = HiddenPower.BW.ivs[type.toLowerCase()]; ivs = _this.get('ivs'); for (stat in ivs) { iv = ivs[stat]; ivs[stat] = hpIVs[stat] || 31; } return _this.set('ivs', ivs, { silent: true }); }; })(this)); if (!attributes.ability) { this.set('ability', this.getAbilities()[0]); } if (!attributes.level) { this.set('level', 100); } if (isNaN(attributes.happiness)) { this.set('happiness', 100); } if (!attributes.nature) { this.set('nature', 'Hardy'); } hiddenPowerType = HiddenPower.BW.type(this.get('ivs')).toLowerCase(); this.set('hiddenPowerType', hiddenPowerType, { silent: true }); if (!this.has('gender')) { genders = this.getGenders(); if (genders.length === 1) { return this.set('gender', genders[0], { silent: true }); } } }; Pokemon.prototype.resetBoosts = function() { return this.set('stages', { hp: 0, attack: 0, defense: 0, specialAttack: 0, specialDefense: 0, speed: 0, accuracy: 0, evasion: 0 }); }; Pokemon.prototype.normalizeStats = function(hash, defaultValue) { var stat, stats, _i, _len, _results; stats = ["hp", "attack", "defense", "specialAttack", "specialDefense", "speed"]; _results = []; for (_i = 0, _len = stats.length; _i < _len; _i++) { stat = stats[_i]; _results.push(hash[stat] != null ? hash[stat] : hash[stat] = defaultValue); } return _results; }; Pokemon.prototype.getName = function() { var sanitizedName; sanitizedName = $('
').text(this.get('name')).html(); sanitizedName = sanitizedName.replace(/[\u0300-\u036F\u20D0-\u20FF\uFE20-\uFE2F]/g, ''); return sanitizedName; }; Pokemon.prototype.getGeneration = function(generation) { var gen, _ref; gen = generation || ((_ref = this.collection) != null ? _ref.generation : void 0) || DEFAULT_GENERATION; gen = gen.toUpperCase(); return window.Generations[gen]; }; Pokemon.prototype.getSpecies = function() { return this.getGeneration().SpeciesData[this.get('species')]; }; Pokemon.prototype.getItem = function() { return this.getGeneration().ItemData[this.get('item')]; }; Pokemon.prototype.getForme = function(forme, generation) { var _ref; forme || (forme = this.get('forme')); return (_ref = this.getGeneration(generation).FormeData[this.get('species')]) != null ? _ref[forme] : void 0; }; Pokemon.prototype.getFormes = function() { var forme, _results; _results = []; for (forme in this.getGeneration().FormeData[this.get('species')]) { _results.push(forme); } return _results; }; Pokemon.prototype.getSelectableFormes = function() { return _(this.getFormes()).reject((function(_this) { return function(forme) { return _this.getForme(forme).isBattleOnly; }; })(this)); }; Pokemon.prototype.getMegaFormes = function() { return _(this.getFormes()).reject((function(_this) { return function(forme) { return forme.indexOf('mega') !== 0; }; })(this)); }; Pokemon.prototype.getAbilities = function() { var abilities, forme; forme = this.getForme(); abilities = _.clone(forme.abilities); if (forme.hiddenAbility) { abilities.push(forme.hiddenAbility); } return _.unique(abilities); }; Pokemon.prototype.getGenders = function() { var genders, species; species = this.getSpecies(); genders = []; switch (species.genderRatio) { case -1: genders.push("Genderless"); break; case 0: genders.push("M"); break; case 8: genders.push("F"); break; default: genders.push("M", "F"); } return genders; }; Pokemon.prototype.hasSelectedMove = function(moveName) { return moveName && __indexOf.call(this.moves, moveName) >= 0; }; Pokemon.prototype.getMovepool = function() { var MoveData, SpeciesData, generation, learnset, _ref, _ref1; _ref = this.getGeneration(), SpeciesData = _ref.SpeciesData, MoveData = _ref.MoveData; generation = GENERATION_TO_INT[((_ref1 = this.collection) != null ? _ref1.generation : void 0) || DEFAULT_GENERATION]; learnset = learnableMoves(window.Generations, this.attributes, generation); return _(learnset).map(function(moveName) { var move; move = _(MoveData[moveName]).clone(); move['name'] = moveName; return move; }); }; Pokemon.prototype.getTotalEVs = function(options) { var stat, total, value, _ref; if (options == null) { options = {}; } total = 0; _ref = this.get("evs"); for (stat in _ref) { value = _ref[stat]; if (stat !== options.exclude) { total += value; } } return total; }; Pokemon.prototype.getTeam = function() { var _ref; return (_ref = this.collection) != null ? _ref.parents[0] : void 0; }; Pokemon.prototype.setIv = function(stat, value) { var ivs; ivs = _.clone(this.get("ivs")); ivs[stat] = value; return this.set("ivs", ivs); }; Pokemon.prototype.setEv = function(stat, value) { var evs; evs = _.clone(this.get("evs")); value = value - (value % 4); evs[stat] = value; this.set("evs", evs); return value; }; Pokemon.prototype.iv = function(stat) { var _ref; return (_ref = this.get("ivs")[stat]) != null ? _ref : 31; }; Pokemon.prototype.ev = function(stat) { var _ref; return (_ref = this.get("evs")[stat]) != null ? _ref : 0; }; Pokemon.prototype.natureBoost = function(stat) { var nature, _ref; nature = (_ref = this.get('nature')) != null ? _ref.toLowerCase() : void 0; if (nature in natures) { return natures[nature][stat] || 1; } else { return 1; } }; Pokemon.prototype.base = function(key) { var base, forme; forme = this.getForme(); return base = forme["stats"][key]; }; Pokemon.prototype.stat = function(key) { var base, ev, iv, level, total; base = this.base(key); if (base === 1) { return 1; } level = this.get('level') || 100; iv = this.iv(key); ev = Math.floor(this.ev(key) / 4); return total = key === 'hp' ? Math.floor((2 * base + iv + ev) * (level / 100) + level + 10) : Math.floor(((2 * base + iv + ev) * (level / 100) + 5) * this.natureBoost(key)); }; Pokemon.prototype.getNatures = function() { var invertedStats, label, minusStat, name, nature, natureResults, plusStat, stats; natureResults = []; for (nature in natures) { stats = natures[nature]; name = nature[0].toUpperCase() + nature.substr(1); invertedStats = _(stats).invert(); label = name; if (invertedStats[PLUS]) { plusStat = statAbbreviations[invertedStats[PLUS]]; minusStat = statAbbreviations[invertedStats[MINUS]]; label = "" + name + " (+" + plusStat + ", -" + minusStat + ")"; } natureResults.push([name, label]); } return natureResults; }; Pokemon.prototype.getPBV = function() { var gen; gen = this.getGeneration(); return PokeBattle.PBV.determinePBV(gen, this.attributes); }; Pokemon.prototype.getTier = function() { var gen; gen = this.getGeneration(); return PokeBattle.Tier.determineTier(gen, this.attributes); }; Pokemon.prototype.setPP = function(moveIndex, newPP) { var array; array = _.clone(this.get('pp')); array[moveIndex] = newPP; return this.set('pp', array); }; Pokemon.prototype.getPercentHP = function() { return Math.max(this.get('percent'), 0); }; Pokemon.prototype.getHPColor = function() { var percent; percent = this.getPercentHP(); switch (false) { case !(percent <= 20): return 'red'; case !(percent <= 50): return 'yellow'; default: return 'green'; } }; Pokemon.prototype.isFainted = function() { return this.get('percent') <= 0; }; Pokemon.prototype.getStatus = function() { var status; status = this.get('status'); if (status) { return "" + (status[0].toUpperCase()) + (status.substr(1)); } else { return "Healthy"; } }; Pokemon.prototype.canMegaEvolve = function() { var forme, item, species, _ref; item = this.getItem(); if (item.type !== 'megastone') { return false; } _ref = item.mega, species = _ref[0], forme = _ref[1]; if (this.get('species') !== species || this.get('forme') !== 'default') { return false; } return true; }; Pokemon.prototype.getPossibleMegaForme = function() { var forme, item, species, _ref; item = this.getItem(); if ((item != null ? item.type : void 0) !== 'megastone') { return null; } _ref = item.mega, species = _ref[0], forme = _ref[1]; if (this.get('species') === species && this.get('forme') === 'default') { return forme; } return null; }; Pokemon.prototype.getPokedexUrl = function() { var slugForme, slugSpecies, slugify; slugify = function(str) { return str.toLowerCase().replace(/[^a-z0-9]/g, '-').replace(/\-{2,}/g, '-'); }; slugSpecies = slugify(this.get('species')); slugForme = slugify(this.get('forme')); return "//pokebattle.com/dex/pokemon/" + slugSpecies + "/" + slugForme; }; Pokemon.prototype.getIllu = function() { return this.get('illu'); }; Pokemon.prototype.setIllu = function(y) { return this.set('illu', y); }; Pokemon.prototype.toJSON = function() { var attributes; attributes = _.clone(this.attributes); if (attributes.gender === 'Genderless') { delete attributes.gender; } delete attributes.hiddenPowerType; delete attributes.teambuilder; return attributes; }; return Pokemon; })(Backbone.Model); statAbbreviations = { 'hp': 'HP', 'attack': 'Atk', 'defense': 'Def', 'specialAttack': 'SAtk', 'specialDefense': 'SDef', 'speed': 'Spe' }; PLUS = 1.1; MINUS = 0.9; natures = { lonely: { attack: PLUS, defense: MINUS }, brave: { attack: PLUS, speed: MINUS }, adamant: { attack: PLUS, specialAttack: MINUS }, naughty: { attack: PLUS, specialDefense: MINUS }, bold: { defense: PLUS, attack: MINUS }, relaxed: { defense: PLUS, speed: MINUS }, impish: { defense: PLUS, specialAttack: MINUS }, lax: { defense: PLUS, specialDefense: MINUS }, timid: { speed: PLUS, attack: MINUS }, hasty: { speed: PLUS, defense: MINUS }, jolly: { speed: PLUS, specialAttack: MINUS }, naive: { speed: PLUS, specialDefense: MINUS }, modest: { specialAttack: PLUS, attack: MINUS }, mild: { specialAttack: PLUS, defense: MINUS }, quiet: { specialAttack: PLUS, speed: MINUS }, rash: { specialAttack: PLUS, specialDefense: MINUS }, calm: { specialDefense: PLUS, attack: MINUS }, gentle: { specialDefense: PLUS, defense: MINUS }, sassy: { specialDefense: PLUS, speed: MINUS }, careful: { specialDefense: PLUS, specialAttack: MINUS }, hardy: {}, docile: {}, serious: {}, bashful: {}, quirky: {} }; this.NullPokemon = (function(_super) { __extends(NullPokemon, _super); function NullPokemon() { return NullPokemon.__super__.constructor.apply(this, arguments); } NullPokemon.prototype.initialize = function() { this.set('species', null); this.set('forme', 'default'); return this.isNull = true; }; NullPokemon.prototype.getNatures = function() { return []; }; NullPokemon.prototype.getPBV = function() { return 0; }; NullPokemon.prototype.base = function() { return 0; }; NullPokemon.prototype.stat = function() { return null; }; NullPokemon.prototype.iv = function() { return null; }; NullPokemon.prototype.ev = function() { return null; }; NullPokemon.prototype.getSpecies = function() { return { id: 0, genderRatio: -1, generation: 1 }; }; NullPokemon.prototype.getForme = function() { return this.getFormes()['default']; }; NullPokemon.prototype.getFormes = function() { return { "default": { abilities: [], hiddenAbility: null, isBattleOnly: false, learnset: {}, types: [] } }; }; return NullPokemon; })(Pokemon); }).call(this); (function() { var PokemonCollection, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; PokemonCollection = (function(_super) { __extends(PokemonCollection, _super); function PokemonCollection() { this.model = __bind(this.model, this); return PokemonCollection.__super__.constructor.apply(this, arguments); } PokemonCollection.prototype.model = function(attrs, options) { if (attrs.name || attrs.species) { attrs.teambuilder = this.parents[0].get('teambuilder'); return new Pokemon(attrs, options); } else { return new NullPokemon(); } }; return PokemonCollection; })(Backbone.Collection); this.Team = (function(_super) { __extends(Team, _super); function Team() { this.setRandomOrder = __bind(this.setRandomOrder, this); this.getRandomOrder = __bind(this.getRandomOrder, this); this.sync = __bind(this.sync, this); this.hasNonNullPokemon = __bind(this.hasNonNullPokemon, this); this.getNonNullPokemon = __bind(this.getNonNullPokemon, this); this.getMaxTier = __bind(this.getMaxTier, this); this.getMaxTierName = __bind(this.getMaxTierName, this); this.hasTier = __bind(this.hasTier, this); this.hasPBV = __bind(this.hasPBV, this); this.getMaxPBV = __bind(this.getMaxPBV, this); this.getTier = __bind(this.getTier, this); this.getPBV = __bind(this.getPBV, this); this.getFormat = __bind(this.getFormat, this); this.clone = __bind(this.clone, this); this.toNonNullJSON = __bind(this.toNonNullJSON, this); this.replace = __bind(this.replace, this); this.indexOf = __bind(this.indexOf, this); this.at = __bind(this.at, this); this.toJSON = __bind(this.toJSON, this); this.getName = __bind(this.getName, this); this.initialize = __bind(this.initialize, this); return Team.__super__.constructor.apply(this, arguments); } Team.prototype.relations = [ { type: Backbone.Many, key: 'pokemon', collectionType: PokemonCollection } ]; Team.prototype.initialize = function(attrs, options) { if (attrs == null) { attrs = {}; } if (options == null) { options = {}; } this.owner = attrs.owner; if (!attrs.generation) { this.set('generation', DEFAULT_GENERATION); } if (options.teambuilder) { this.set('teambuilder', true); } if (!attrs.pokemon) { return this.set('pokemon', []); } }; Team.prototype.getName = function() { return this.get('name') || "Untitled team"; }; Team.prototype.toJSON = function() { var json; json = {}; if (this.id) { json['id'] = this.id; } json['name'] = this.get('name'); json['generation'] = this.get('generation'); json['pokemon'] = this.get('pokemon').toJSON(); return json; }; Team.prototype.at = function(idx) { return this.get('pokemon').at(idx); }; Team.prototype.indexOf = function(idx) { return this.get('pokemon').indexOf(idx); }; Team.prototype.replace = function(idx, newPokemon) { this.get('pokemon').remove(this.get('pokemon').at(idx)); return this.get('pokemon').add(newPokemon, { at: idx }); }; Team.prototype.toNonNullJSON = function() { return { id: this.id, name: this.get('name'), generation: this.get('generation'), pokemon: this.get('pokemon').reject(function(pokemon) { return pokemon.isNull; }).map(function(pokemon) { return pokemon.toJSON(); }) }; }; Team.prototype.clone = function() { var attrs; attrs = _(this.attributes).clone(); attrs.pokemon = this.get('pokemon').toJSON(); return new Team(attrs); }; Team.prototype.rearrange = function(arrangement) { var index, pokemon; pokemon = this.get('pokemon'); pokemon.reset((function() { var _i, _len, _results; _results = []; for (_i = 0, _len = arrangement.length; _i < _len; _i++) { index = arrangement[_i]; _results.push(pokemon.models[index]); } return _results; })()); return true; }; Team.prototype.getFormat = function() { var allformats, format; format = this.get('generation'); allformats = window.PokeBattle.conditions.Formats(); if (!(format in allformats)) { format = DEFAULT_FORMAT; } return allformats[format]; }; Team.prototype.getGeneration = function(generation) { var gen; gen = generation || this.getFormat().generation; gen = gen.toUpperCase(); return window.Generations[gen]; }; Team.prototype.getPBV = function() { var gen, pokemon; gen = this.getGeneration(); pokemon = this.get('pokemon').toJSON(); return PokeBattle.PBV.determinePBV(gen, pokemon); }; Team.prototype.getTier = function() { var gen, pokemon; gen = this.getGeneration(); pokemon = this.get('pokemon').toJSON(); return PokeBattle.Tier.determineTier(gen, pokemon); }; Team.prototype.getMaxPBV = function() { var conditions, _ref, _ref1; conditions = this.getFormat().conditions; if (_ref = Conditions.PBV_1000, __indexOf.call(conditions, _ref) >= 0) { return 1000; } else if (_ref1 = Conditions.PBV_500, __indexOf.call(conditions, _ref1) >= 0) { return 500; } else { return 0; } }; Team.prototype.hasPBV = function() { return this.getMaxPBV() > 0; }; Team.prototype.hasTier = function() { return typeof this.getMaxTier() !== 'undefined'; }; Team.prototype.getMaxTierName = function() { var condition, conditions, tier, tiername, _i, _len; conditions = this.getFormat().conditions; for (_i = 0, _len = conditions.length; _i < _len; _i++) { condition = conditions[_i]; tiername = _.invert(Conditions)[condition]; if ((tiername.search(/TIER_/)) === 0) { tier = tiername.replace(/TIER_/, ""); } } return tier; }; Team.prototype.getMaxTier = function() { var tier, tiername; tiername = this.getMaxTierName(); if (tiername) { tier = PokeBattle.Tier.Tiers[tiername]; } return tier; }; Team.prototype.getNonNullPokemon = function() { return this.get('pokemon').where({ isNull: false }); }; Team.prototype.hasNonNullPokemon = function() { return this.get('pokemon').some(function(pokemon) { return !pokemon.isNull; }); }; Team.prototype.sync = function(method) { switch (method) { case 'create': case 'patch': case 'update': this.set('saving', true, { silent: true }); this.trigger('remoteSync', this); return PokeBattle.primus.send('saveTeam', this.toJSON(), (function(_this) { return function(id) { _this.set('id', id); _this.set('saving', false, { silent: true }); return _this.trigger('remoteSync', _this); }; })(this)); case 'delete': if (this.id) { return PokeBattle.primus.send('destroyTeam', this.id); } } }; Team.prototype.getRandomOrder = function() { var order; order = this.get('randomorder'); if (typeof order === 'undefined') { this.setRandomOrder(); order = this.get('randomorder'); return order; } else { order = this.get('randomorder'); return order; } }; Team.prototype.setRandomOrder = function() { var team, teamshuffled; team = this.get('pokemon').toJSON(); teamshuffled = _.shuffle(team); return this.set('randomorder', teamshuffled); }; return Team; })(Backbone.AssociatedModel); }).call(this); (function() { var Teams, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; Teams = (function(_super) { __extends(Teams, _super); function Teams() { return Teams.__super__.constructor.apply(this, arguments); } Teams.prototype.model = Team; return Teams; })(Backbone.Collection); this.Battle = (function(_super) { __extends(Battle, _super); function Battle() { this.notify = __bind(this.notify, this); this.forfeit = __bind(this.forfeit, this); this.isPlaying = __bind(this.isPlaying, this); this.getPokemon = __bind(this.getPokemon, this); this.getOpponentTeam = __bind(this.getOpponentTeam, this); this.getTeam = __bind(this.getTeam, this); this["switch"] = __bind(this["switch"], this); this.arrangeTeam = __bind(this.arrangeTeam, this); this.makeCancel = __bind(this.makeCancel, this); this.makeSwitch = __bind(this.makeSwitch, this); this.makeMove = __bind(this.makeMove, this); this.receiveTeam = __bind(this.receiveTeam, this); this.receiveTeams = __bind(this.receiveTeams, this); this.initialize = __bind(this.initialize, this); return Battle.__super__.constructor.apply(this, arguments); } Battle.prototype.relations = [ { type: Backbone.Many, key: 'teams', relatedModel: Team, collectionType: Teams } ]; Battle.prototype.defaults = { spectating: true, finished: false }; _.extend(Battle.prototype, PokeBattle.mixins.BattleProtocolParser); Battle.prototype.initialize = function(attributes) { var allformats, spectators; this.updateQueue = []; this.numActive = attributes.numActive, spectators = attributes.spectators; if (!!spectators) { this.spectators = new UserList(spectators); } allformats = window.PokeBattle.conditions.Formats(); this.set('generation', allformats[this.get('format')].generation); this.set('notifications', 0); this.set('turn', 0); this.set('teams', [ { hidden: true }, { hidden: true } ]); this.set('spectating', !this.has('index')); if (!this.has('index')) { return this.set('index', Math.floor(2 * Math.random())); } }; Battle.prototype.receiveTeams = function(receivedTeams) { var i, receivedTeam, team, teams, _i, _len, _results; teams = this.get('teams'); _results = []; for (i = _i = 0, _len = receivedTeams.length; _i < _len; i = ++_i) { receivedTeam = receivedTeams[i]; receivedTeam.hidden = true; team = teams.at(i); if (team.get('hidden')) { _results.push(team.set(receivedTeam)); } else { _results.push(void 0); } } return _results; }; Battle.prototype.receiveTeam = function(team) { var teams; teams = this.get('teams'); return teams.at(this.get('index')).unset('hidden', { silent: true }).set(team); }; Battle.prototype.makeMove = function(moveName, forSlot, callback) { var options, pokemon; pokemon = this.getPokemon(this.get('index'), forSlot); options = {}; if (pokemon.get('megaEvolve')) { options['megaEvolve'] = pokemon.get('megaEvolve'); } return PokeBattle.primus.send('sendMove', this.id, moveName, forSlot, this.get('turn'), options, callback); }; Battle.prototype.makeSwitch = function(toSlot, forSlot, callback) { return PokeBattle.primus.send('sendSwitch', this.id, toSlot, forSlot, this.get('turn'), callback); }; Battle.prototype.makeCancel = function() { return PokeBattle.primus.send('sendCancelAction', this.id, this.get('turn')); }; Battle.prototype.arrangeTeam = function(arrangement) { return PokeBattle.primus.send('arrangeTeam', this.id, arrangement); }; Battle.prototype["switch"] = function(fromIndex, toIndex) { var you, _ref; you = this.getTeam().pokemon; return _ref = [you[toIndex], you[fromIndex]], you[fromIndex] = _ref[0], you[toIndex] = _ref[1], _ref; }; Battle.prototype.getTeam = function(playerIndex) { if (playerIndex == null) { playerIndex = this.get('index'); } return this.get("teams").at(playerIndex); }; Battle.prototype.getOpponentTeam = function(playerIndex) { if (playerIndex == null) { playerIndex = this.get('index'); } return this.get("teams").at(1 - playerIndex); }; Battle.prototype.getPokemon = function(playerIndex, slot) { var team; if (slot == null) { slot = 0; } team = this.getTeam(playerIndex); return team.at(slot); }; Battle.prototype.isPlaying = function() { return !this.get('finished') && !this.get('spectating'); }; Battle.prototype.forfeit = function() { return PokeBattle.primus.send('forfeit', this.id); }; Battle.prototype.notify = function() { return this.set('notifications', this.get('notifications') + 1); }; return Battle; })(Backbone.AssociatedModel); }).call(this); (function() { var MAX_LOG_LENGTH, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, __slice = [].slice; MAX_LOG_LENGTH = 50; this.PrivateMessage = (function(_super) { __extends(PrivateMessage, _super); function PrivateMessage() { this.logKey = __bind(this.logKey, this); this.saveLog = __bind(this.saveLog, this); this.loadLog = __bind(this.loadLog, this); this.getLog = __bind(this.getLog, this); this.closeChallenge = __bind(this.closeChallenge, this); this.cancelChallenge = __bind(this.cancelChallenge, this); this.openChallenge = __bind(this.openChallenge, this); this.add = __bind(this.add, this); this.initialize = __bind(this.initialize, this); return PrivateMessage.__super__.constructor.apply(this, arguments); } PrivateMessage.prototype.initialize = function() { this.loadLog(); return this.set('notifications', 0); }; PrivateMessage.prototype.add = function(username, message, opts) { var log; if (opts == null) { opts = {}; } if (username === this.id) { this.set('notifications', this.get('notifications') + 1); } this.trigger("receive", this, this.id, username, message, opts); log = this.get('log'); log.push({ username: username, message: message, opts: opts }); if (log.length > (2 * MAX_LOG_LENGTH)) { log.splice(0, log.length - MAX_LOG_LENGTH); } return this.saveLog(); }; PrivateMessage.prototype.openChallenge = function() { var args; args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; return this.trigger.apply(this, ["openChallenge"].concat(__slice.call(args))); }; PrivateMessage.prototype.cancelChallenge = function() { var args; args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; return this.trigger.apply(this, ["cancelChallenge"].concat(__slice.call(args))); }; PrivateMessage.prototype.closeChallenge = function() { var args; args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; return this.trigger.apply(this, ["closeChallenge"].concat(__slice.call(args))); }; PrivateMessage.prototype.getLog = function() { var log; log = this.get('log'); if (log.length > 50) { log.splice(0, log.length - 50); } return log; }; PrivateMessage.prototype.loadLog = function() { var log; try { log = JSON.parse(window.localStorage.getItem(this.logKey())) || []; return this.set('log', log); } catch (_error) { return this.set('log', []); } }; PrivateMessage.prototype.saveLog = function() { try { return window.localStorage.setItem(this.logKey(), JSON.stringify(this.getLog())); } catch (_error) {} }; PrivateMessage.prototype.logKey = function() { var key; key = [this.id, PokeBattle.username]; key.sort(); return key.join(':'); }; return PrivateMessage; })(Backbone.Model); }).call(this); (function() { var __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, __slice = [].slice; this.Room = (function(_super) { var eventName, _fn, _i, _len, _ref; __extends(Room, _super); function Room() { return Room.__super__.constructor.apply(this, arguments); } Room.prototype.relations = [ { type: Backbone.Many, key: 'users', relatedModel: 'User', collectionType: 'UserList' } ]; Room.prototype.EVENTS = "userMessage rawMessage announce clear setTopic".split(/\s+/); _ref = Room.prototype.EVENTS; _fn = function(eventName) { return Room.prototype[eventName] = function() { var args; args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; return this.trigger.apply(this, [eventName].concat(__slice.call(args))); }; }; for (_i = 0, _len = _ref.length; _i < _len; _i++) { eventName = _ref[_i]; _fn(eventName); } Room.prototype.sendChat = function(message) { if (!((message != null ? message.replace(/\s+$/).length : void 0) > 0)) { return false; } if (!PokeBattle.commands.execute(this, message)) { PokeBattle.primus.send('sendChat', this.id, message); } return true; }; return Room; })(Backbone.AssociatedModel); }).call(this); (function() { var AuthorityMap, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; AuthorityMap = { "1": "", "2": "+", "3": "%", "4": "@", "5": "~" }; this.User = (function(_super) { __extends(User, _super); function User() { this.isAlt = __bind(this.isAlt, this); this.getDisplayName = __bind(this.getDisplayName, this); this.initialize = __bind(this.initialize, this); return User.__super__.constructor.apply(this, arguments); } User.prototype.initialize = function(attributes) {}; User.prototype.getDisplayName = function() { var authorityString, _ref; authorityString = (_ref = AuthorityMap[this.get('authority')]) != null ? _ref : ""; return "" + authorityString + (this.get('id')); }; User.prototype.isAlt = function() { return this.get('isAlt'); }; return User; })(Backbone.Model); }).call(this); (function() { var __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; this.BattleCollection = (function(_super) { __extends(BattleCollection, _super); function BattleCollection() { return BattleCollection.__super__.constructor.apply(this, arguments); } BattleCollection.prototype.model = Battle; BattleCollection.prototype.isPlaying = function() { return this.find(function(battle) { return battle.isPlaying(); }) != null; }; BattleCollection.prototype.playingBattles = function() { return this.filter(function(battle) { return battle.isPlaying(); }); }; return BattleCollection; })(Backbone.Collection); }).call(this); (function() { var __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; this.PrivateMessages = (function(_super) { __extends(PrivateMessages, _super); function PrivateMessages() { return PrivateMessages.__super__.constructor.apply(this, arguments); } PrivateMessages.prototype.model = PrivateMessage; return PrivateMessages; })(Backbone.Collection); }).call(this); (function() { var __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, __slice = [].slice; this.Rooms = (function(_super) { var eventName, _fn, _i, _len, _ref; __extends(Rooms, _super); function Rooms() { return Rooms.__super__.constructor.apply(this, arguments); } Rooms.prototype.model = Room; _ref = Room.prototype.EVENTS; _fn = function(eventName) { return Rooms.prototype[eventName] = function() { var args; args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; return this.each(function(room) { return room[eventName].apply(room, args); }); }; }; for (_i = 0, _len = _ref.length; _i < _len; _i++) { eventName = _ref[_i]; _fn(eventName); } return Rooms; })(Backbone.Collection); }).call(this); (function() { var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; this.UserList = (function(_super) { __extends(UserList, _super); function UserList() { this.initialize = __bind(this.initialize, this); this.comparator = __bind(this.comparator, this); return UserList.__super__.constructor.apply(this, arguments); } UserList.prototype.model = User; UserList.prototype.comparator = function(a, b) { var aAuthority, aName, bAuthority, bName; aAuthority = a.get('authority'); bAuthority = b.get('authority'); aName = ("" + a.id).toLowerCase(); bName = ("" + b.id).toLowerCase(); if (aAuthority < bAuthority) { return 1; } else if (aAuthority > bAuthority) { return -1; } else if (aName < bName) { return -1; } else if (aName > bName) { return 1; } else { return 0; } }; UserList.prototype.initialize = function() {}; return UserList; })(Backbone.Collection); }).call(this); (function() { var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }, __slice = [].slice; this.BattleView = (function(_super) { __extends(BattleView, _super); function BattleView() { this.setVisibleTeam = __bind(this.setVisibleTeam, this); this.pokemonHtml = __bind(this.pokemonHtml, this); this.remove = __bind(this.remove, this); this.getPokemonPosition = __bind(this.getPokemonPosition, this); this.addPokemonImage = __bind(this.addPokemonImage, this); this.preloadImages = __bind(this.preloadImages, this); this.afterAction = __bind(this.afterAction, this); this.afterSelection = __bind(this.afterSelection, this); this.megaEvolve = __bind(this.megaEvolve, this); this.cancelAction = __bind(this.cancelAction, this); this.switchPokemon = __bind(this.switchPokemon, this); this.makeMove = __bind(this.makeMove, this); this.continueTurn = __bind(this.continueTurn, this); this.beginTurn = __bind(this.beginTurn, this); this.addSummary = __bind(this.addSummary, this); this.addLog = __bind(this.addLog, this); this.isIllusioned = __bind(this.isIllusioned, this); this.addMoveMessage = __bind(this.addMoveMessage, this); this.disableButtons = __bind(this.disableButtons, this); this.enableButtons = __bind(this.enableButtons, this); this.resetPopovers = __bind(this.resetPopovers, this); this.faint = __bind(this.faint, this); this.isFront = __bind(this.isFront, this); this.$projectile = __bind(this.$projectile, this); this.$sprite = __bind(this.$sprite, this); this.$spriteContainer = __bind(this.$spriteContainer, this); this.$pokemon = __bind(this.$pokemon, this); this.changeBattleSpeed = __bind(this.changeBattleSpeed, this); this.returnToLobby = __bind(this.returnToLobby, this); this.saveLog = __bind(this.saveLog, this); this.saveReplay = __bind(this.saveReplay, this); this.shouldRenderEnd = __bind(this.shouldRenderEnd, this); this.handleRemoval = __bind(this.handleRemoval, this); this.handleEnd = __bind(this.handleEnd, this); this.announceWin = __bind(this.announceWin, this); this.announceExpiration = __bind(this.announceExpiration, this); this.announceTimer = __bind(this.announceTimer, this); this.announceForfeit = __bind(this.announceForfeit, this); this.announceWinner = __bind(this.announceWinner, this); this.$playerInfo = __bind(this.$playerInfo, this); this.resumeTimer = __bind(this.resumeTimer, this); this.pauseTimer = __bind(this.pauseTimer, this); this.renderTimer = __bind(this.renderTimer, this); this.countdownTimers = __bind(this.countdownTimers, this); this.renderTimers = __bind(this.renderTimers, this); this.updateTimers = __bind(this.updateTimers, this); this.unattachBattle = __bind(this.unattachBattle, this); this.unattachTeam = __bind(this.unattachTeam, this); this.addPokemonEffect = __bind(this.addPokemonEffect, this); this.mapStatusForDisplay = __bind(this.mapStatusForDisplay, this); this.showSpinner = __bind(this.showSpinner, this); this.handleStatus = __bind(this.handleStatus, this); this.handlePercent = __bind(this.handlePercent, this); this.resetBoosts = __bind(this.resetBoosts, this); this.setBoosts = __bind(this.setBoosts, this); this.unattachPokemon = __bind(this.unattachPokemon, this); this.boost = __bind(this.boost, this); this.unattachScreen = __bind(this.unattachScreen, this); this.attachScreen = __bind(this.attachScreen, this); this.attachBattle = __bind(this.attachBattle, this); this.attachTeam = __bind(this.attachTeam, this); this.attachPokemon = __bind(this.attachPokemon, this); this.changeWeather = __bind(this.changeWeather, this); this.changeName = __bind(this.changeName, this); this.changeSprite = __bind(this.changeSprite, this); this.activateAbility = __bind(this.activateAbility, this); this.getCannedText = __bind(this.getCannedText, this); this.actOnCannedText = __bind(this.actOnCannedText, this); this.parseCannedText = __bind(this.parseCannedText, this); this.cannedText = __bind(this.cannedText, this); this.moveSuccess = __bind(this.moveSuccess, this); this.logMove = __bind(this.logMove, this); this.removePokeball = __bind(this.removePokeball, this); this.makePokeball = __bind(this.makePokeball, this); this.switchOut = __bind(this.switchOut, this); this.switchIn = __bind(this.switchIn, this); this.floatText = __bind(this.floatText, this); this.floatPercent = __bind(this.floatPercent, this); this.removeTeamPreview = __bind(this.removeTeamPreview, this); this.submitTeamPreview = __bind(this.submitTeamPreview, this); this.togglePokemonOrSwitch = __bind(this.togglePokemonOrSwitch, this); this.renderTeamPreview = __bind(this.renderTeamPreview, this); this.pokemonPopover = __bind(this.pokemonPopover, this); this.movePopover = __bind(this.movePopover, this); this.renderUserInfo = __bind(this.renderUserInfo, this); this.renderWaiting = __bind(this.renderWaiting, this); this.renderActions = __bind(this.renderActions, this); this.renderChat = __bind(this.renderChat, this); this.renderControls = __bind(this.renderControls, this); this.renderPokemon = __bind(this.renderPokemon, this); this.renderBattle = __bind(this.renderBattle, this); this.render = __bind(this.render, this); this.initialize = __bind(this.initialize, this); return BattleView.__super__.constructor.apply(this, arguments); } BattleView.prototype.battle_template = JST['battle']; BattleView.prototype.user_info_template = JST['battle_user_info']; BattleView.prototype.action_template = JST['battle_actions']; BattleView.prototype.team_preview_template = JST['battle_team_preview']; BattleView.prototype.battle_end_template = JST['battle_end']; BattleView.prototype.battle_controls_template = JST['battle_controls']; BattleView.prototype.SPEEDS = { Instant: 0, Fast: 1, Medium: 1.5, Slow: 2 }; BattleView.prototype.events = { 'click .move': 'makeMove', 'click .switch': 'switchPokemon', 'click .mega-evolve': 'megaEvolve', 'click .cancel': 'cancelAction', 'click .save-replay': 'saveReplay', 'click .save-log': 'saveLog', 'click .return-to-lobby': 'returnToLobby', 'click .arrange_pokemon': 'togglePokemonOrSwitch', 'click .submit_arrangement': 'submitTeamPreview', 'change .battle-speed': 'changeBattleSpeed' }; BattleView.prototype.initialize = function(options) { var _ref; this.chatView = null; this.lastMove = null; this.skip = null; this.room = (_ref = PokeBattle.rooms) != null ? _ref.add({ id: this.model.id, users: [] }) : void 0; try { this.speed = Number(window.localStorage.getItem('battle_speed')); } catch (_error) { } this.speed || (this.speed = 1); this.listenTo(this.model, 'change:teams[*].pokemon[*].status', this.handleStatus); this.listenTo(this.model, 'change:teams[*].pokemon[*].percent', this.handlePercent); this.listenTo(this.model, 'change:finished', this.handleEnd); if (this.model.collection) { this.listenTo(this.model.collection, 'remove', this.handleRemoval); } this.battleStartTime = $.now(); this.timers = []; this.timerUpdatedAt = []; this.timerFrozenAt = []; this.timerIterations = 0; this.countdownTimers(); return this.render(); }; BattleView.prototype.render = function() { this.renderChat(); return this; }; BattleView.prototype.renderBattle = function() { var locals; locals = { yourTeam: this.model.getTeam(), opponentTeam: this.model.getOpponentTeam(), numActive: this.model.numActive, yourIndex: this.model.get('index'), window: window }; this.$('.battle_pane').html(this.battle_template(locals)); this.renderPokemon(); this.renderControls(); return this; }; BattleView.prototype.renderPokemon = function($images, callback) { var battle, self; $images || ($images = this.$('.preload')); battle = this.model; self = this; $images.each(function() { var $pokemon, $this, forme, front, gen, id, player, scale, shiny, slot, species, url, _ref; $this = $(this); $pokemon = $this.closest('.pokemon'); _ref = [$pokemon.data('team'), $pokemon.data('slot')], player = _ref[0], slot = _ref[1]; front = $pokemon.hasClass('top'); species = $this.data('species'); forme = $this.data('forme'); shiny = $this.data('shiny'); gen = battle.get('generation').toUpperCase(); id = window.Generations[gen].SpeciesData[species].id; url = PokemonSprite(id, forme, { front: front, shiny: shiny }); scale = front ? 0.7 : 0.9; return self.addPokemonImage($this, url, { scale: scale, callback: function($image) { var height, image, width, x, y, _ref1; image = $image[0]; width = image.width, height = image.height; _ref1 = self.getPokemonPosition(player, slot), x = _ref1[0], y = _ref1[1]; x -= width >> 1; y -= height >> 1; if (!front) { y += 30; } $image.css({ top: y, left: x }).show(); return typeof callback === "function" ? callback($image) : void 0; } }); }); return this; }; BattleView.prototype.renderControls = function() { var html; html = this.battle_controls_template({ speeds: this.SPEEDS, currentSpeed: this.speed }); this.$el.find('.battle-controls').html(html); return this; }; BattleView.prototype.renderChat = function() { this.chatView = new ChatView({ el: this.$('.chat'), model: this.room, noisy: true }).render(); return this; }; BattleView.prototype.renderActions = function(validActions) { var $actions, $button, locals, pokemon, _ref; if (validActions == null) { validActions = []; } locals = { yourTeam: this.model.getTeam(), validActions: validActions[0] || {}, window: window }; $actions = this.$('.battle_actions'); $actions.html(this.action_template(locals)); pokemon = this.model.getPokemon(this.model.get('index'), 0); if (((_ref = pokemon.getItem()) != null ? _ref.type : void 0) === 'megastone') { $button = $actions.find('.mega-evolve'); $button.removeClass("hidden"); if (!pokemon.canMegaEvolve()) { $button.addClass('disabled'); } } $actions.find('.move.button').each((function(_this) { return function(i, el) { var $this, gen, moveData, moveName, _ref1; $this = $(el); moveName = $this.data('move-id'); gen = _this.model.get('generation').toUpperCase(); moveData = (_ref1 = window.Generations[gen]) != null ? _ref1.MoveData[moveName] : void 0; return _this.movePopover($this, moveName, moveData); }; })(this)); $actions.find('.switch.button').each((function(_this) { return function(i, el) { var $this, slot; $this = $(el); slot = $this.data('slot'); pokemon = _this.model.getPokemon(_this.model.get('index'), slot); return _this.pokemonPopover($this, pokemon); }; })(this)); return this; }; BattleView.prototype.renderWaiting = function() { var $actions; $actions = this.$('.battle_actions'); $actions.find('.move.button').popover('destroy'); return $actions.html("
\n Waiting for opponent...\n Cancel\n
"); }; BattleView.prototype.renderUserInfo = function() { var $userInfo, locals; locals = { yourTeam: this.model.getTeam(), opponentTeam: this.model.getOpponentTeam(), numActive: this.model.numActive, yourIndex: this.model.get('index'), window: window }; $userInfo = this.$('.battle_user_info'); $userInfo.find('.pokemon_icon').popover('destroy'); $userInfo.html(this.user_info_template(locals)); $userInfo.find('.pokemon_icon').each((function(_this) { return function(i, el) { var $this, pokemon, slot, team; $this = $(el); team = $this.data('team'); slot = $this.data('slot'); pokemon = _this.model.getPokemon(team, slot); return _this.pokemonPopover($this, pokemon); }; })(this)); this.renderTimers(); return this; }; BattleView.prototype.movePopover = function($this, moveName, move) { var damage, damageFriendly, displayName, options, targetFriendly, type; type = move.type, damage = move.damage; damageFriendly = move.damage[0].toUpperCase() + move.damage.substr(1); targetFriendly = move.target[0].toUpperCase() + move.target.substr(1); displayName = []; displayName.push(moveName); displayName.push("\""\n\""\n\"""); options = { title: displayName.join('
'), html: true, content: JST['move_hover_info']({ window: window, move: move }), trigger: 'hover', animation: false, placement: 'top', container: 'body' }; return $this.popover(options); }; BattleView.prototype.pokemonPopover = function($this, pokemon) { var displayName, options, type, _i, _len, _ref; if (this.isIllusioned(pokemon)) { pokemon = pokemon.getTeam().attributes.pokemon.at(pokemon.getTeam().attributes.pokemon.length - 1); } displayName = pokemon.get('species'); if (pokemon.has('item')) { displayName += " @ " + (pokemon.get('item')); } displayName += "
"; _ref = pokemon.getForme().types; for (_i = 0, _len = _ref.length; _i < _len; _i++) { type = _ref[_i]; displayName += "\"""; } options = { title: displayName, html: true, content: JST['battle_hover_info']({ window: window, pokemon: pokemon }), trigger: 'hover', animation: false, container: 'body' }; return $this.popover(options); }; BattleView.prototype.renderTeamPreview = function() { var locals; locals = { battle: this.model, window: window }; return this.$('.battle_container').append(this.team_preview_template(locals)); }; BattleView.prototype.togglePokemonOrSwitch = function(e) { var $activePokemon, $currentTarget; $currentTarget = $(e.currentTarget); $activePokemon = this.$('.arrange_pokemon.active'); if ($currentTarget.is('.active')) { return $activePokemon.removeClass('active'); } else if ($activePokemon.length > 0) { $activePokemon.removeClass('active'); return this.swapElements($currentTarget.get(0), $activePokemon.get(0)); } else { return $currentTarget.addClass('active'); } }; BattleView.prototype.swapElements = function(element1, element2) { var next1, next2, parent1, parent2, _ref, _ref1; _ref = [element1.parentNode, element1.nextSibling], parent1 = _ref[0], next1 = _ref[1]; _ref1 = [element2.parentNode, element2.nextSibling], parent2 = _ref1[0], next2 = _ref1[1]; parent1.insertBefore(element2, next1); return parent2.insertBefore(element1, next2); }; BattleView.prototype.submitTeamPreview = function(e) { var $currentTarget, $teamPreview, element, indices; $currentTarget = $(e.currentTarget); if ($currentTarget.hasClass('disabled')) { return; } $currentTarget.addClass('disabled'); $teamPreview = this.$('.battle_teams'); indices = (function() { var _i, _len, _ref, _results; _ref = this.$('.arrange_team .pokemon_icon'); _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { element = _ref[_i]; _results.push($(element).data('index')); } return _results; }).call(this); this.model.arrangeTeam(indices); return $teamPreview.transition({ opacity: 0 }, 250, (function(_this) { return function() { return _this.removeTeamPreview(); }; })(this)); }; BattleView.prototype.removeTeamPreview = function() { var $teamPreview; $teamPreview = this.$('.battle_teams'); return $teamPreview.remove(); }; BattleView.prototype.floatPercent = function(player, slot, percent) { var kind, percentText; if (this.skip != null) { return; } kind = (percent >= 0 ? "" : "red"); percentText = "" + percent; if (percent >= 0) { percentText = "+" + percentText; } percentText += "%"; return this.floatText(player, slot, percentText, kind); }; BattleView.prototype.floatText = function(player, slot, text, kind) { var $sprite, $text, x, y, _ref; if (kind == null) { kind = ""; } if (this.skip != null) { return; } $sprite = this.$sprite(player, slot); _ref = this.getPokemonPosition(player, slot), x = _ref[0], y = _ref[1]; $text = $('').addClass("percentage " + kind).text(text); $text.hide().appendTo(this.$('.battle_pane')); x -= $text.width() / 2; y -= 20; $text.css({ position: 'absolute', top: y, left: x }).show(); if (kind === 'red') { $text.transition({ top: "+=30" }, 1000, 'easeOutCubic'); $text.delay(1000); return $text.transition({ opacity: 0 }, 1000, function() { return $text.remove(); }); } else { $text.transition({ top: "-=30" }, 1000, 'easeOutCubic'); $text.delay(1000); return $text.transition({ opacity: 0 }, 1000, function() { return $text.remove(); }); } }; BattleView.prototype.switchIn = function(player, slot, fromSlot, done) { var $newPokemon, $newSprite, $oldPokemon, $pokeball, pokemon, releasePokemon, x, y, _ref; $oldPokemon = this.$pokemon(player, slot); $newPokemon = this.$pokemon(player, fromSlot); $newSprite = this.$sprite(player, fromSlot); pokemon = this.model.getPokemon(player, slot); this.renderUserInfo(); $oldPokemon.attr('data-slot', fromSlot); $newPokemon.attr('data-slot', slot); $newPokemon.removeClass('hidden'); this.pokemonPopover($newSprite, pokemon); this.cannedText('SENT_OUT', player, player, slot); if (this.skip != null) { $oldPokemon.css({ opacity: 0 }); $newPokemon.css({ opacity: 1 }); done(); return; } _ref = this.getPokemonPosition(player, slot), x = _ref[0], y = _ref[1]; $pokeball = this.makePokeball(x, y); $pokeball.css({ opacity: 0 }); $pokeball.appendTo(this.$(".battle_pane")); $oldPokemon.css({ opacity: 0 }); $newPokemon.css({ opacity: 0 }); $pokeball.css({ opacity: 1 }); releasePokemon = (function(_this) { return function() { $pokeball.css({ opacity: 0 }); $newSprite.transition({ y: -15, scale: .1 }, 0).transition({ scale: 1 }, 250 * _this.speed).transition({ y: 0 }, 250 * _this.speed, 'out', function() { return _this.removePokeball($pokeball); }); setTimeout(done, 500 * _this.speed); return $newPokemon.transition({ opacity: 1 }); }; })(this); return setTimeout(releasePokemon, 250 * this.speed); }; BattleView.prototype.switchOut = function(player, slot, done) { var $pokemon, $sprite, height, width; $pokemon = this.$pokemon(player, slot); $sprite = this.$sprite(player, slot); this.cannedText('WITHDREW', player, player, slot); if (this.skip != null) { $pokemon.addClass('hidden'); $sprite.popover('destroy'); done(); return; } width = $sprite.width(); height = $sprite.height(); $sprite.transition({ scale: 0.1, x: width >> 1, y: height }, 150 * this.speed); $pokemon.transition({ opacity: 0 }, 250 * this.speed, function() { $pokemon.addClass('hidden').css({ opacity: 1 }); $sprite.popover('destroy'); return $sprite.transition({ scale: 1, x: 0, y: 0 }, 0); }); return setTimeout(done, 250 * this.speed); }; BattleView.prototype.makePokeball = function(x, y) { var $pokeball, func, id, size; $pokeball = $("
"); $pokeball.css({ top: y, left: x }); size = 22; $pokeball.width(size).height(size); func = function() { $pokeball.css({ backgroundPositionY: -10 - func.counter * 40 }); return func.counter = (func.counter + 1) % 8; }; func.counter = 1; id = setInterval(func, 40); $pokeball.data('animation-id', id); return $pokeball; }; BattleView.prototype.removePokeball = function($pokeball) { var id; id = $pokeball.data('animation-id'); clearTimeout(id); return $pokeball.remove(); }; BattleView.prototype.logMove = function(player, slot, moveName, done) { var owner, pokemon; owner = this.model.getTeam(player).escape('owner'); pokemon = this.model.getPokemon(player, slot); this.addMoveMessage(owner, pokemon, moveName); this.lastMove = moveName; return done(); }; BattleView.prototype.moveSuccess = function(player, slot, targetSlots, moveName, done) { var $attacker, $defender, $projectile, ax, ay, dx, dy, front, gen, moveData, scale, speed, targetPlayer, targetSlot, transX, transY, _ref, _ref1, _ref2, _ref3, _ref4, _ref5; if (this.skip != null) { return done(); } gen = this.model.get('generation').toUpperCase(); moveData = (_ref = window.Generations[gen]) != null ? _ref.MoveData[moveName] : void 0; if (!moveData) { console.error("Could not display animation for " + moveName + " as it does not exist in " + gen + "."); done(); return; } _ref1 = targetSlots[0], targetPlayer = _ref1[0], targetSlot = _ref1[1]; $attacker = this.$sprite(player, slot); $defender = this.$sprite(targetPlayer, targetSlot); _ref2 = this.getPokemonPosition(player, slot), ax = _ref2[0], ay = _ref2[1]; _ref3 = this.getPokemonPosition(targetPlayer, targetSlot), dx = _ref3[0], dy = _ref3[1]; front = this.isFront(player); scale = (front ? 1.3 : 1 / 1.3); if (moveName === 'Earthquake') { speed = this.speed; $attacker.add($defender).each(function(index) { return $(this).transition({ x: -75 }, 62.5 * speed, 'easeInOutCubic').transition({ x: 75 }, 125 * speed, 'easeInOutCubic').transition({ x: -30 }, 125 * speed, 'easeInOutCubic').transition({ x: 30 }, 125 * speed, 'easeInOutCubic').transition({ x: 0 }, 62.5 * speed, 'easeInOutCubic'); }); return setTimeout(done, 500 * this.speed); } else if (__indexOf.call(moveData.flags, 'contact') >= 0) { $attacker.transition({ x: dx - ax, y: dy - ay, scale: scale }, 250 * this.speed, 'in').transition({ x: 0, y: 0, scale: 1 }, 250 * this.speed, 'out'); $defender.delay(400 * this.speed).transition({ x: (front ? -16 : 8) }, 50 * this.speed, 'easeOutCubic').transition({ x: 0 }, 50 * this.speed, 'easeInOutCubic'); return setTimeout(done, 500 * this.speed); } else if (moveData['power'] > 0) { $projectile = this.$projectile(player, slot, moveData); _ref4 = [dx - ax, dy - ay], transX = _ref4[0], transY = _ref4[1]; $projectile.transition({ x: transX / 2, y: transY / 2, scale: (scale + 1) / 2 }, 200 * this.speed, 'easeOutCubic').transition({ x: transX, y: transY, scale: scale }, 200 * this.speed, 'easeOutCubic').transition({ opacity: 0 }, 100 * this.speed, function() { return $projectile.remove(); }); $defender.delay(400 * this.speed).transition({ x: -4 }, 0, 'linear').delay(50 * this.speed).transition({ x: 4 }, 0, 'linear').delay(50 * this.speed).transition({ x: 0 }, 0, 'linear'); return setTimeout(done, 500 * this.speed); } else if (player !== targetPlayer || slot !== targetSlot) { $projectile = this.$projectile(player, slot, moveData); _ref5 = [dx - ax, dy - ay], transX = _ref5[0], transY = _ref5[1]; $projectile.transition({ x: transX * 2 / 3, y: transY / 3 }, 150 * this.speed, 'easeInOutSine').transition({ x: transX / 3, y: transY * 2 / 3 }, 100 * this.speed, 'easeInOutSine').transition({ x: transX, y: transY }, 150 * this.speed, 'easeInOutSine').transition({ opacity: 0 }, 100 * this.speed, 'easeInOutSine', function() { return $projectile.remove(); }); return setTimeout(done, 500 * this.speed); } else { $attacker = this.$sprite(player, slot); $attacker.transition({ x: -16 }, 125 * this.speed, 'easeInOutSine').transition({ x: 16 }, 250 * this.speed, 'easeInOutSine').transition({ x: 0 }, 125 * this.speed, 'easeInOutSine'); return setTimeout(done, 500 * this.speed); } }; BattleView.prototype.cannedText = function() { var args, cannedString; cannedString = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; return this.parseCannedText(CannedText[cannedString], args, function() {}); }; BattleView.prototype.parseCannedText = function(cannedInteger, args, done) { var cannedText, cannedTextName; cannedTextName = CannedMapReverse[cannedInteger]; cannedText = this.getCannedText(cannedTextName, args); this.addLog(cannedText); return this.actOnCannedText(cannedTextName, cannedText, done); }; BattleView.prototype.actOnCannedText = function(cannedTextName, cannedText, done) { if (this.skip != null) { return done(); } switch (cannedTextName) { case 'MOVE_MISS': case 'JUMP_KICK_MISS': case 'MOVE_FAIL': case 'IMMUNITY': this.addSummary(cannedText); return setTimeout(done, 500 * this.speed); case 'PARALYZE_CONTINUE': case 'FREEZE_CONTINUE': case 'SLEEP_CONTINUE': case 'SUN_END': case 'RAIN_END': case 'SAND_END': case 'HAIL_END': case 'SAND_CONTINUE': case 'HAIL_CONTINUE': this.addSummary(cannedText, { newline: true }); return done(); default: this.addSummary(cannedText); return done(); } }; BattleView.prototype.getCannedText = function(cannedTextName, args) { var cannedText, genIndex, generation, i, language, _i, _ref, _ref1; cannedText = 'Please refresh to see this text!'; genIndex = ALL_GENERATIONS.indexOf(this.model.get('generation')); language = 'en'; for (i = _i = genIndex; _i >= 0; i = _i += -1) { generation = ALL_GENERATIONS[i]; if ((_ref = CannedMap[generation]) != null ? (_ref1 = _ref[language]) != null ? _ref1[cannedTextName] : void 0 : void 0) { cannedText = CannedMap[generation][language][cannedTextName]; break; } } return cannedText.replace(/\$([a-z]+|\d+)/g, (function(_this) { return function(match, p1, index) { var player, pokemon, slot, text, _ref2; switch (p1) { case 'p': _ref2 = args.splice(0, 2), player = _ref2[0], slot = _ref2[1]; pokemon = _this.model.getPokemon(player, slot); if (_this.isIllusioned(pokemon)) { pokemon = pokemon.getTeam().attributes.pokemon.at(pokemon.getTeam().attributes.pokemon.length - 1); } return pokemon.escape('name'); case 't': player = args.splice(0, 1)[0]; return _this.model.getTeam(player).escape('owner'); case 'ts': player = args.splice(0, 1)[0]; text = _this.isFront(player) ? "the opposing team" : "your team"; if (index === 0) { text = "" + (text[0].toUpperCase()) + text.slice(1); } return text; default: text = args.splice(0, 1)[0]; return text; } }; })(this)); }; BattleView.prototype.activateAbility = function(player, slot, abilityName, done) { var $ability, isFront, pokemon; if (this.skip != null) { return done(); } pokemon = this.model.getPokemon(player, slot); isFront = this.isFront(player); $ability = $('
').addClass('ability_activation'); $ability.html("" + (pokemon.escape('name')) + "'s " + abilityName + ""); $ability.addClass((isFront ? 'front' : 'back')); $ability.width(1); $ability.appendTo(this.$('.battle_pane')); $ability.transition({ opacity: 1, width: 150 }, 100 * this.speed, 'easeInQuad').delay(3000).transition({ opacity: 0 }, 300 * this.speed, 'easeInQuad', function() { return $ability.remove(); }); return setTimeout(done, 500 * this.speed); }; BattleView.prototype.changeSprite = function(player, slot, species, forme, done) { var $sprite, $spriteContainer; $spriteContainer = this.$spriteContainer(player, slot); $sprite = this.$sprite(player, slot); $spriteContainer.data('species', species); $spriteContainer.data('forme', forme); if (this.skip != null) { this.renderPokemon($spriteContainer, function() { $sprite.popover('destroy'); return $sprite.remove(); }); done(); return; } $sprite.fadeOut(200 * this.speed, (function(_this) { return function() { return _this.renderPokemon($spriteContainer, function($image) { $sprite.popover('destroy'); $sprite.remove(); return $image.hide().fadeIn(200 * this.speed); }); }; })(this)); if (this.model.getPokemon(player, slot).isFainted()) { return done(); } else { return setTimeout(done, 400 * this.speed); } }; BattleView.prototype.changeName = function(player, slot, newName, done) { var nameBox; nameBox = this.$pokemon(player, slot).find('.pokemon-name'); nameBox.html(newName); return done(); }; BattleView.prototype.changeWeather = function(newWeather, done) { var $drop, $hailstone, $overlays, $ray, $sand, $weather, dropLeft, dropTop, hailstoneLeft, hailstoneTop, height, i, left, millisecs, overlayHeight, overlayWidth, percentX, percentY, sandHeight, sandWidth, size, streams, top, width, x, y, _ref; $overlays = this.$('.battle_overlays'); $overlays.find('.weather').transition({ opacity: 0 }, 500 * this.speed, function() { return $(this).remove(); }); _ref = [600, 300], overlayWidth = _ref[0], overlayHeight = _ref[1]; $weather = (function() { var _i, _j, _k, _l, _len, _m, _n, _ref1, _ref2, _ref3, _ref4, _ref5; switch (newWeather) { case Weather.RAIN: $weather = $("
").addClass("battle_overlay weather rain"); for (i = _i = 0; _i < 100; i = ++_i) { dropLeft = _.random(-300, overlayWidth); dropTop = _.random(-2 * overlayHeight - 100, overlayHeight); $drop = $('
'); $drop.css({ left: dropLeft, top: dropTop }); $weather.append($drop); } $overlays.append($weather); return $weather; case Weather.SUN: $weather = $("
").addClass("battle_overlay weather sun"); for (i = _j = 0; _j < 10; i = ++_j) { millisecs = Math.floor(Math.random() * 3000) + 'ms'; $ray = $('
'); $ray.css({ left: Math.floor(Math.random() * overlayWidth) }); $ray.css({ '-webkit-animation-delay': millisecs, '-moz-animation-delay': millisecs, '-ms-animation-delay': millisecs, '-o-animation-delay': millisecs, 'animation-delay': millisecs }); $weather.append($ray); } $overlays.append($weather); return $weather; case Weather.SAND: $weather = $("
").addClass("battle_overlay weather sand"); _ref1 = [overlayWidth, overlayHeight], width = _ref1[0], height = _ref1[1]; _ref2 = [600, 600], sandWidth = _ref2[0], sandHeight = _ref2[1]; streams = []; for (x = _k = _ref3 = -(2 * width); sandWidth > 0 ? _k <= width : _k >= width; x = _k += sandWidth) { for (y = _l = _ref4 = -(2 * height); sandHeight > 0 ? _l < height : _l > height; y = _l += sandHeight) { percentX = Math.floor(100 * x / width) + "%"; percentY = Math.floor(100 * y / height) + "%"; streams.push([percentX, percentY]); } } for (_m = 0, _len = streams.length; _m < _len; _m++) { _ref5 = streams[_m], left = _ref5[0], top = _ref5[1]; $sand = $('
'); $sand.css({ left: left, top: top }); $weather.append($sand); } $overlays.append($weather); return $weather; case Weather.HAIL: $weather = $("
").addClass("battle_overlay weather hail"); for (i = _n = 0; _n < 100; i = ++_n) { hailstoneLeft = _.random(-300, overlayWidth); hailstoneTop = _.random(-2 * overlayHeight, overlayHeight); $hailstone = $('
'); size = Math.floor(Math.random() * 5) + 5; $hailstone.width(size); $hailstone.height(size); $hailstone.css({ left: hailstoneLeft, top: hailstoneTop }); $weather.append($hailstone); } $overlays.append($weather); return $weather; default: return $(); } })(); $weather.transition({ opacity: 1 }, 500 * this.speed); return done(); }; BattleView.prototype.attachPokemon = function(player, slot, attachment, done) { var $pokemon, $spriteContainer, pokemon, substituteUrl; pokemon = this.model.getPokemon(player, slot); $pokemon = this.$pokemon(player, slot); switch (attachment) { case 'SubstituteAttachment': $spriteContainer = this.$spriteContainer(player, slot); $spriteContainer.addClass('fade'); substituteUrl = (this.isFront(player) ? "substitute" : "subback"); substituteUrl = "../Sprites/battle/" + substituteUrl + ".gif"; return this.addPokemonImage($pokemon, substituteUrl, { callback: (function(_this) { return function($image) { var height, width, x, y, yOffset, _ref; _ref = _this.getPokemonPosition(player, slot), x = _ref[0], y = _ref[1]; $image.addClass('substitute'); width = $image.width(); height = $image.height(); x -= width >> 1; y -= height >> 1; yOffset = 200; $image.css({ position: 'absolute', left: x, top: y }); $image.show(); if (_this.skip != null) { return done(); } setTimeout(function() { return $image.transition({ y: -yOffset }, 0).transition({ y: 0 }, 200 * this.speed, 'easeInQuad').transition({ y: -yOffset >> 3 }, 100 * this.speed, 'easeOutQuad').transition({ y: 0 }, 100 * this.speed, 'easeInQuad'); }, 0); return setTimeout(done, 500 * _this.speed); }; })(this) }); case 'ConfusionAttachment': this.addPokemonEffect($pokemon, "confusion", "Confusion"); this.addLog("" + (pokemon.escape('name')) + " became confused!"); return done(); case 'ProtectAttachment': case 'KingsShieldAttachment': case 'SpikyShieldAttachment': this.cannedText('PROTECT_CONTINUE', player, slot); return this.attachScreen(player, slot, 'pink', 0, done); case 'Air Balloon': this.addPokemonEffect($pokemon, "balloon", "Balloon"); this.addLog("" + (pokemon.escape('name')) + " floats in the air with its Air Balloon!"); return done(); case 'Paralyze': pokemon.set('status', 'paralyze'); return done(); case 'Burn': pokemon.set('status', 'burn'); return done(); case 'Poison': pokemon.set('status', 'poison'); return done(); case 'Toxic': pokemon.set('status', 'toxic'); return done(); case 'Freeze': pokemon.set('status', 'freeze'); return done(); case 'Sleep': pokemon.set('status', 'sleep'); return done(); default: return done(); } }; BattleView.prototype.attachTeam = function(player, attachment, done) { var $battlePane, $div, isFront, newX, newY, oldX, oldY, previousLayers, _ref, _ref1, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7; $battlePane = this.$('.battle_pane'); isFront = this.isFront(player); switch (attachment) { case "StealthRockAttachment": $div = $("
").addClass("field-" + player + " team-stealth-rock"); if (isFront) { _ref = ["20%", "80%"], oldX = _ref[0], oldY = _ref[1]; _ref1 = ["67%", "45%"], newX = _ref1[0], newY = _ref1[1]; } else { _ref2 = ["80%", "20%"], oldX = _ref2[0], oldY = _ref2[1]; _ref3 = ["34%", "81%"], newX = _ref3[0], newY = _ref3[1]; } if (this.skip != null) { $div.css({ top: newY, left: newX, opacity: .5 }); $battlePane.prepend($div); return done(); } else { $div.css({ top: oldY, left: oldX, opacity: 0 }); $div.transition({ top: newY, left: newX, opacity: 1 }, 500 * this.speed).delay(1000 * this.speed).transition({ opacity: .5 }); $battlePane.prepend($div); return setTimeout(done, 500 * this.speed); } break; case "ToxicSpikesAttachment": $div = $("
").addClass("field-" + player + " team-toxic-spikes"); previousLayers = this.$(".field-" + player + ".team-toxic-spikes").length; if (isFront) { oldY = "80%"; oldX = "20%"; newY = (function() { switch (previousLayers) { case 0: return "51%"; case 1: return "50%"; } })(); newX = (function() { switch (previousLayers) { case 0: return "77%"; case 1: return "73%"; } })(); } else { oldY = "30%"; oldX = "80%"; newY = (function() { switch (previousLayers) { case 0: return "87%"; case 1: return "86%"; } })(); newX = (function() { switch (previousLayers) { case 0: return "23%"; case 1: return "27%"; } })(); } if (this.skip != null) { $div.css({ top: newY, left: newX, opacity: .5 }); $battlePane.prepend($div); return done(); } else { $div.css({ top: oldY, left: oldX, opacity: 0 }); $div.transition({ top: newY, left: newX, opacity: 1 }, 500 * this.speed).delay(1000 * this.speed).transition({ opacity: .5 }); $battlePane.prepend($div); return setTimeout(done, 500 * this.speed); } break; case "SpikesAttachment": $div = $("
").addClass("field-" + player + " team-spikes"); previousLayers = this.$(".field-" + player + ".team-spikes").length; if (isFront) { oldY = "80%"; oldX = "20%"; newY = (function() { switch (previousLayers) { case 0: return "49%"; case 1: return "52%"; case 2: return "50%"; } })(); newX = (function() { switch (previousLayers) { case 0: return "87%"; case 1: return "84%"; case 2: return "82%"; } })(); } else { oldY = "30%"; oldX = "80%"; newY = (function() { switch (previousLayers) { case 0: return "85%"; case 1: return "88%"; case 2: return "86%"; } })(); newX = (function() { switch (previousLayers) { case 0: return "13%"; case 1: return "16%"; case 2: return "18%"; } })(); } if (this.skip != null) { $div.css({ top: newY, left: newX, opacity: .5 }); $battlePane.prepend($div); return done(); } else { $div.css({ top: oldY, left: oldX, opacity: 0 }); $div.transition({ top: newY, left: newX, opacity: 1 }, 500 * this.speed).delay(1000 * this.speed).transition({ opacity: .5 }); $battlePane.prepend($div); return setTimeout(done, 500 * this.speed); } break; case "StickyWebAttachment": $div = $("
").addClass("field-" + player + " team-sticky-web"); if (isFront) { _ref4 = ["0%", "50%"], oldX = _ref4[0], oldY = _ref4[1]; _ref5 = ["65%", "10%"], newX = _ref5[0], newY = _ref5[1]; } else { _ref6 = ["65%", "10%"], oldX = _ref6[0], oldY = _ref6[1]; _ref7 = ["0%", "50%"], newX = _ref7[0], newY = _ref7[1]; } if (this.skip != null) { $div.css({ top: newY, left: newX, opacity: .5 }); $battlePane.prepend($div); return done(); } else { $div.css({ top: oldY, left: oldX, opacity: 0 }); $div.animate({ top: newY, left: newX, opacity: 1 }, 1000 * this.speed, 'easeOutElastic').delay(1000 * this.speed).animate({ opacity: .2 }); $battlePane.prepend($div); return setTimeout(done, 500 * this.speed); } break; case "ReflectAttachment": this.cannedText('REFLECT_START', player); return this.attachScreen(player, 'blue', 10, done); case "LightScreenAttachment": this.cannedText('LIGHT_SCREEN_START', player); return this.attachScreen(player, 'yellow', 5, done); default: return done(); } }; BattleView.prototype.attachBattle = function(attachment, done) { return done(); }; BattleView.prototype.attachScreen = function(player, slot, klass, offset, done) { var $screen, finalSize, halfSize, x, y, _ref, _ref1; if (done == null) { done = function() {}; } if (arguments.length === 4) { _ref = [null, slot, klass, offset], slot = _ref[0], klass = _ref[1], offset = _ref[2], done = _ref[3]; } finalSize = 100; halfSize = finalSize >> 1; $screen = $("
").addClass("team-screen " + klass + " field-" + player); if (slot) { $screen.addClass("slot-" + slot); } _ref1 = this.getPokemonPosition(player, 0), x = _ref1[0], y = _ref1[1]; x += offset; y += offset; $screen.css({ left: x, top: y }).appendTo(this.$('.battle_pane')); if (this.skip != null) { $screen.css({ width: finalSize, height: finalSize }); $screen.css({ x: -halfSize, y: -halfSize }); return done(); } else { $screen.transition({ width: finalSize, x: -halfSize }, 250 * this.speed, 'easeInOutCubic').transition({ height: finalSize, y: -halfSize }, 250 * this.speed, 'easeInOutCubic'); return setTimeout(done, 500 * this.speed); } }; BattleView.prototype.unattachScreen = function(player, slot, klass, done) { var $selector, selector, _ref; if (done == null) { done = function() {}; } if (arguments.length === 3) { _ref = [null, slot, klass], slot = _ref[0], klass = _ref[1], done = _ref[2]; } selector = ".team-screen." + klass + ".field-" + player; if (slot) { selector += ".slot-" + slot; } $selector = this.$(selector); $selector.fadeOut(500 * this.speed, function() { return $selector.remove(); }); return done(); }; BattleView.prototype.boost = function(player, slot, deltaBoosts, options) { var $effect, $effects, $pokemon, abbreviatedStat, amount, delta, finalStat, message, negFloatText, pokemon, pokemonName, posFloatText, previous, stages, stat; if (options == null) { options = {}; } pokemon = this.model.getPokemon(player, slot); if (this.isIllusioned(pokemon)) { pokemonName = pokemon.getTeam().attributes.pokemon.at(pokemon.getTeam().attributes.pokemon.length - 1).attributes.name; } else { pokemonName = pokemon.escape('name'); } stages = pokemon.get('stages'); $pokemon = this.$pokemon(player, slot); $effects = $pokemon.find('.pokemon-effects'); posFloatText = []; negFloatText = []; for (stat in deltaBoosts) { delta = deltaBoosts[stat]; previous = stages[stat]; stages[stat] += delta; if (!options.silent) { message = this.makeBoostMessage(pokemonName, stat, delta, stages[stat]); if (message) { this.addLog(message); } } abbreviatedStat = (function() { switch (stat) { case "attack": return "Att"; case "defense": return "Def"; case "speed": return "Spe"; case "specialAttack": return "Sp.A"; case "specialDefense": return "Sp.D"; case "accuracy": return "Acc."; case "evasion": return "Eva."; default: return stat; } })(); amount = stages[stat]; if (amount > 0) { amount = "+" + amount; } finalStat = "" + amount + " " + abbreviatedStat; $effect = this.addPokemonEffect($pokemon, "boost " + stat, finalStat); if (amount < 0) { $effect.addClass('negative'); negFloatText.push("" + delta + " " + abbreviatedStat); } else if (amount > 0) { $effect.removeClass('negative'); posFloatText.push("+" + delta + " " + abbreviatedStat); } else { $effect.remove(); } } if (options.floatText) { if (negFloatText.length > 0) { this.floatText(player, slot, negFloatText.join('/'), 'red'); } if (posFloatText.length > 0) { this.floatText(player, slot, posFloatText.join('/')); } } return true; }; BattleView.prototype.makeBoostMessage = function(pokemonName, stat, amount, currentBoost) { var adverb; stat = (function() { switch (stat) { case "attack": return "Attack"; case "defense": return "Defense"; case "speed": return "Speed"; case "specialAttack": return "Special Attack"; case "specialDefense": return "Special Defense"; case "accuracy": return "Accuracy"; case "evasion": return "Evasion"; default: return stat; } })(); if (amount > 0) { if (amount === 12) { return "" + pokemonName + " cut its own HP and maximized its " + stat + "!"; } else { if (amount === 1) { adverb = ""; } if (amount === 2) { adverb = " sharply"; } if (amount >= 3) { adverb = " drastically"; } return "" + pokemonName + "'s " + stat + " rose" + adverb + "!"; } } else if (amount < 0) { if (amount === -1) { adverb = ""; } if (amount === -2) { adverb = " harshly"; } if (amount <= -3) { adverb = " severely"; } return "" + pokemonName + "'s " + stat + adverb + " fell!"; } else if (currentBoost === 6) { return "" + pokemonName + "'s " + stat + " won't go any higher!"; } else if (currentBoost === -6) { return "" + pokemonName + "'s " + stat + " won't go any lower!"; } }; BattleView.prototype.unattachPokemon = function(player, slot, effect, done) { var $pokemon, $spriteContainer, $substitute, pokemon; pokemon = this.model.getPokemon(player, slot); $pokemon = this.$pokemon(player, slot); switch (effect) { case 'SubstituteAttachment': $spriteContainer = this.$spriteContainer(player, slot); $spriteContainer.removeClass('fade'); $substitute = $pokemon.find('.substitute').first(); if (this.skip != null) { $substitute.remove(); return done(); } else { $substitute.transition({ y: 300, opacity: 0 }, 300 * this.speed, function() { return $substitute.remove(); }); return setTimeout(done, 300 * this.speed); } break; case 'ProtectAttachment': case 'KingsShieldAttachment': case 'SpikyShieldAttachment': return this.unattachScreen(player, slot, 'pink', done); case 'Air Balloon': $pokemon.find(".pokemon-effect.balloon").remove(); this.addLog("" + (pokemon.escape('name')) + "'s Air Balloon popped!"); return done(); case 'ConfusionAttachment': $pokemon.find(".pokemon-effect.confusion").remove(); return done(); case 'Paralyze': pokemon.set('status', null); return done(); case 'Burn': pokemon.set('status', null); return done(); case 'Poison': pokemon.set('status', null); return done(); case 'Toxic': pokemon.set('status', null); return done(); case 'Freeze': pokemon.set('status', null); return done(); case 'Sleep': pokemon.set('status', null); return done(); default: return done(); } }; BattleView.prototype.setBoosts = function(player, slot, boosts) { var pokemon, stages, stat; pokemon = this.model.getPokemon(player, slot); stages = pokemon.get('stages'); for (stat in boosts) { boosts[stat] -= stages[stat]; } return this.boost(player, slot, boosts, { silent: true }); }; BattleView.prototype.resetBoosts = function(player, slot) { var $pokemon, pokemon; pokemon = this.model.getPokemon(player, slot); pokemon.resetBoosts(); $pokemon = this.$pokemon(player, slot); return $pokemon.find('.boost').remove(); }; BattleView.prototype.handlePercent = function(pokemon) { var $allHP, $hpText, $info, $pokemon, deltaPercent, percent, player, slot, _ref; $pokemon = this.$pokemon(pokemon); $info = $pokemon.find(".pokemon-info"); $allHP = $info.find('.hp'); $hpText = $info.find('.hp-text'); percent = pokemon.getPercentHP(); if (percent <= 20) { $allHP.css({ backgroundColor: "#f00" }); } else if (percent <= 50) { $allHP.css({ backgroundColor: "#ff0" }); } else { $allHP.css({ backgroundColor: "#0f0" }); } $allHP.width("" + percent + "%"); $hpText.text("" + percent + "%"); deltaPercent = percent - pokemon.previous('percent'); _ref = [$pokemon.data('team'), $pokemon.data('slot')], player = _ref[0], slot = _ref[1]; return this.floatPercent(player, slot, deltaPercent); }; BattleView.prototype.handleStatus = function(pokemon, status) { var $effects, $pokemon, display; $pokemon = this.$pokemon(pokemon); if (status != null) { $effects = $pokemon.find('.pokemon-effects'); display = this.mapStatusForDisplay(status); return this.addPokemonEffect($pokemon, status, display); } else { return $pokemon.find(".pokemon-effect." + (pokemon.previous('status'))).remove(); } }; BattleView.prototype.showSpinner = function() { return this.$('.battle_actions .show_spinner').removeClass('hidden'); }; BattleView.prototype.mapStatusForDisplay = function(status) { switch (status) { case "burn": return "BRN"; case "paralyze": return "PAR"; case "poison": return "PSN"; case "toxic": return "TOX"; case "freeze": return "FRZ"; case "sleep": return "SLP"; } }; BattleView.prototype.addPokemonEffect = function($pokemon, klass, text) { var $effect, $effects; $effects = $pokemon.find(".pokemon-effects"); $effect = $effects.find(".pokemon-effect." + (klass.replace(/\s+/g, '.'))); if (!text) { return $effect; } if ($effect.length === 0) { $effect = $("
" + text + "
"); $effect.appendTo($effects); } else { $effect.text(text); } return $effect; }; BattleView.prototype.unattachTeam = function(player, attachment, done) { var $battlePane; $battlePane = this.$('.battle_pane'); switch (attachment) { case "StealthRockAttachment": $battlePane.find(".field-" + player + ".team-stealth-rock").remove(); return done(); case "ToxicSpikesAttachment": $battlePane.find(".field-" + player + ".team-toxic-spikes").remove(); return done(); case "SpikesAttachment": $battlePane.find(".field-" + player + ".team-spikes").remove(); return done(); case "StickyWebAttachment": $battlePane.find(".field-" + player + ".team-sticky-web").remove(); return done(); case 'ReflectAttachment': this.cannedText('REFLECT_END', player); return this.unattachScreen(player, 'blue', done); case 'LightScreenAttachment': this.cannedText('LIGHT_SCREEN_END', player); return this.unattachScreen(player, 'yellow', done); default: return done(); } }; BattleView.prototype.unattachBattle = function(effect, done) { return done(); }; BattleView.prototype.updateTimers = function(timers) { var index, now, timer, _i, _len, _results; now = $.now(); _results = []; for (index = _i = 0, _len = timers.length; _i < _len; index = ++_i) { timer = timers[index]; this.timers[index] = timer; _results.push(this.timerUpdatedAt[index] = now); } return _results; }; BattleView.prototype.renderTimers = function() { var i, _i, _results; _results = []; for (i = _i = 0; _i <= 1; i = ++_i) { _results.push(this.renderTimer(i)); } return _results; }; BattleView.prototype.countdownTimers = function() { var diff; this.renderTimers(); diff = $.now() - this.battleStartTime - this.timerIterations * 1000; this.timerIterations++; return this.countdownTimersId = setTimeout(this.countdownTimers, 1000 - diff); }; BattleView.prototype.renderTimer = function(index) { var $frozenTimer, $info, $remainingTimer, timeRemaining; $info = this.$playerInfo(index); $remainingTimer = $info.find('.remaining-timer'); $frozenTimer = $info.find('.frozen-timer'); timeRemaining = this.timers[index] - $.now() + this.timerUpdatedAt[index]; if (!timeRemaining && timeRemaining !== 0) { $remainingTimer.addClass('hidden'); } else { $remainingTimer.removeClass('hidden'); $remainingTimer.text(PokeBattle.humanizeTime(timeRemaining)); } if (timeRemaining <= 1 * 60 * 1000) { $frozenTimer.addClass("battle-timer-low"); $remainingTimer.addClass("battle-timer-low"); } else { $frozenTimer.removeClass("battle-timer-low"); $remainingTimer.removeClass("battle-timer-low"); } if (this.timerFrozenAt[index]) { $frozenTimer.text(PokeBattle.humanizeTime(this.timerFrozenAt[index])); $frozenTimer.removeClass('hidden'); $remainingTimer.addClass('battle-timer-small'); if (this.showSecondaryTimer) { return $remainingTimer.removeClass('hidden'); } else { return $remainingTimer.addClass('hidden'); } } else { $frozenTimer.addClass('hidden'); return $remainingTimer.removeClass('battle-timer-small hidden'); } }; BattleView.prototype.pauseTimer = function(index, timeSinceLastAction) { var now; now = $.now(); this.timerFrozenAt[index] = this.timers[index] - (now - this.timerUpdatedAt[index]); if (timeSinceLastAction) { this.timerUpdatedAt[index] -= timeSinceLastAction; } this.showSecondaryTimer = timeSinceLastAction != null; return this.renderTimer(index); }; BattleView.prototype.resumeTimer = function(index) { delete this.timerFrozenAt[index]; return this.renderTimer(index); }; BattleView.prototype.$playerInfo = function(index) { var $userInfo; $userInfo = this.$('.battle_user_info'); if (index === this.model.get('index')) { return $userInfo.find('.left'); } else { return $userInfo.find('.right'); } }; BattleView.prototype.announceWinner = function(player, done) { var message, owner; owner = this.model.getTeam(player).escape('owner'); message = "" + owner + " won!"; return this.announceWin(message, done); }; BattleView.prototype.announceForfeit = function(player, done) { var message, owner; owner = this.model.getTeam(player).escape('owner'); message = "" + owner + " has forfeited!"; return this.announceWin(message, done); }; BattleView.prototype.announceTimer = function(player, done) { var message, owner; owner = this.model.getTeam(player).escape('owner'); message = "" + owner + " was given the timer win!"; return this.announceWin(message, done); }; BattleView.prototype.announceExpiration = function(done) { var message; message = "The battle expired!"; return this.announceWin(message, done); }; BattleView.prototype.announceWin = function(message, done) { this.chatView.print("

" + message + "

"); this.addSummary(message, { newline: true }); this.model.set('finished', true); return done(); }; BattleView.prototype.handleEnd = function(battle, end) { if (this.shouldRenderEnd()) { this.disableButtons(); this.$('.battle_actions').html(this.battle_end_template({ window: window })); } return clearTimeout(this.countdownTimersId); }; BattleView.prototype.handleRemoval = function(battle) { if (battle === this.model) { return this.remove(); } }; BattleView.prototype.shouldRenderEnd = function() { return PokeBattle.primus != null; }; BattleView.prototype.saveReplay = function(e) { var $replayButton; $replayButton = $(e.currentTarget); if ($replayButton.is('.disabled')) { return; } $replayButton.addClass('disabled'); $replayButton.find('.show_spinner').removeClass('hidden'); return PokeBattle.primus.send('saveReplay', this.model.id, (function(_this) { return function(error, replayId) { var absoluteUrl, relativeUrl; $replayButton.find('.show_spinner').addClass('hidden'); if (error) { return _this.chatView.announce("error", error); } else { relativeUrl = "/replays/" + replayId; absoluteUrl = "" + window.location.protocol + "//" + window.location.host; absoluteUrl += relativeUrl; return _this.chatView.announce("success", "Your replay was saved! Share the link: " + absoluteUrl + "."); } }; })(this)); }; BattleView.prototype.saveLog = function() { var $children, blob, fileName, log; log = []; $children = this.$('.messages').children(); $children.each(function() { var $this, isHeader; $this = $(this); isHeader = /H\d/i.test(this.tagName); if (isHeader) { log.push(""); } log.push($this.text()); if (isHeader) { return log.push(""); } }); log = [log.join('\n')]; fileName = (this.model.get('teams').map(function(team) { return team.escape('owner'); })).join(" vs "); fileName += ".txt"; blob = new Blob(log, { type: "text/plain;charset=utf-8", endings: "native" }); return saveAs(blob, fileName); }; BattleView.prototype.returnToLobby = function() { return PokeBattle.navigation.focusLobby(); }; BattleView.prototype.changeBattleSpeed = function(e) { this.speed = Number($(e.currentTarget).val()) || 1; try { return window.localStorage.setItem('battle_speed', this.speed); } catch (_error) { } }; BattleView.prototype.$pokemon = function(player, slot) { var pokemon; if (arguments.length === 1) { pokemon = player; this.model.get('teams').forEach(function(team, playerIndex) { var index; index = team.indexOf(pokemon); if (index !== -1) { player = playerIndex; slot = index; } }); } return this.$(".pokemon[data-team='" + player + "'][data-slot='" + slot + "']"); }; BattleView.prototype.$spriteContainer = function(player, slot) { return this.$pokemon(player, slot).find('.sprite'); }; BattleView.prototype.$sprite = function(player, slot) { return this.$spriteContainer(player, slot).find('img'); }; BattleView.prototype.$projectile = function(player, slot, moveData) { var $projectile, x, y, _ref; $projectile = $('
').addClass('projectile'); $projectile.addClass(moveData['type'].toLowerCase()); $projectile.appendTo(this.$(".battle_pane")); _ref = this.getPokemonPosition(player, slot), x = _ref[0], y = _ref[1]; $projectile.css({ left: x, top: y }); return $projectile; }; BattleView.prototype.isFront = function(player) { return this.model.get('index') !== player; }; BattleView.prototype.faint = function(player, slot, done) { var $pokemon, $sprite; $pokemon = this.$pokemon(player, slot); $sprite = this.$sprite(player, slot); if (this.skip != null) { $sprite.popover('destroy'); $sprite.remove(); done(); return; } $sprite.transition({ y: 100, opacity: 0 }, 250 * this.speed, 'ease-in', function() { $sprite.popover('destroy'); return $sprite.remove(); }); setTimeout(done, 250 * this.speed); return this.renderUserInfo(); }; BattleView.prototype.resetPopovers = function() { var $pokemon, $sprite, player, pokemon, slot, _i, _results; if (!this.model.teams) { return; } _results = []; for (player = _i = 0; _i < 2; player = ++_i) { _results.push((function() { var _j, _ref, _results1; _results1 = []; for (slot = _j = 0, _ref = this.model.numActive; 0 <= _ref ? _j < _ref : _j > _ref; slot = 0 <= _ref ? ++_j : --_j) { $pokemon = this.$pokemon(player, slot); pokemon = this.model.getPokemon(player, slot); $sprite = this.$sprite(player, slot); $sprite.popover('destroy'); _results1.push(this.pokemonPopover($sprite, pokemon)); } return _results1; }).call(this)); } return _results; }; BattleView.prototype.enableButtons = function(validActions) { if (validActions) { this.renderActions(validActions); return this.resumeTimer(this.model.get('index')); } else { return this.disableButtons(); } }; BattleView.prototype.disableButtons = function() { this.$('.battle_actions .switch.button').popover('destroy'); return this.renderWaiting(); }; BattleView.prototype.addMoveMessage = function(owner, pokemon, moveName) { var lastpokemon; if (this.isIllusioned(pokemon)) { lastpokemon = pokemon.getTeam().attributes.pokemon.at(pokemon.getTeam().attributes.pokemon.length - 1); pokemon = lastpokemon; } this.chatView.print("

" + owner + "'s " + (this.pokemonHtml(pokemon)) + " used " + moveName + "!

"); return this.addSummary("" + owner + "'s " + (pokemon.escape('name')) + " used " + moveName + "!", { newline: true, big: true }); }; BattleView.prototype.isIllusioned = function(pokemon) { var illusionmons, _ref; illusionmons = ['Zoroark', 'Zorua']; if ((_ref = pokemon.attributes.species, __indexOf.call(illusionmons, _ref) >= 0) && pokemon.attributes.percent === 100 && this.model.attributes.turn <= 1) { return true; } if (pokemon.getIllu()) { return true; } return false; }; BattleView.prototype.addLog = function(message) { return this.chatView.print("

" + message + "

"); }; BattleView.prototype.addSummary = function(message, options) { var $p, $summary, html, removeP; if (options == null) { options = {}; } if (this.skip != null) { return; } $summary = this.$('.battle_summary'); $summary.show(); $p = $summary.children().last(); if ($p.length === 0 || $p.is('.newline') || options.newline) { $p = $("

").html(message).hide(); if (options.newline) { $p.addClass('newline'); } if (options.big) { $p.addClass('big'); } $p.appendTo($summary); } else { html = $p.html(); $p.html("" + html + " " + message); } $p.slideDown(200); if (!this.chatView.$el.is(':visible')) { return; } removeP = function() { return $p.slideUp(200, function() { $p.remove(); if ($summary.is(':empty')) { return $summary.hide(); } }); }; return setTimeout(removeP, 4000); }; BattleView.prototype.beginTurn = function(turn, done) { this.chatView.print("

Turn " + turn + "

"); this.model.set('turn', turn); return done(); }; BattleView.prototype.continueTurn = function(done) { var offset; this.$('.battle_summary').empty().hide(); offset = this.$('.battle_pane').offset().top + this.$el.scrollTop(); offset -= this.$el.offset().top; this.$el.scrollTop(offset); return done(); }; BattleView.prototype.makeMove = function(e) { var $target, forSlot, moveName, pokemon; forSlot = 0; $target = $(e.currentTarget); moveName = $target.data('move-id'); if ($target.hasClass('disabled')) { console.log("Cannot use " + moveName + "."); return; } console.log("Making move " + moveName); pokemon = this.model.getPokemon(this.model.get('index'), 0); this.showSpinner(); return this.model.makeMove(moveName, forSlot, this.afterSelection.bind(this, pokemon)); }; BattleView.prototype.switchPokemon = function(e) { var $target, forSlot, pokemon, toSlot; forSlot = 0; $target = $(e.currentTarget); toSlot = $target.data('slot'); if ($target.hasClass('disabled')) { console.log("Cannot switch to " + toSlot + "."); return; } console.log("Switching to " + toSlot); toSlot = parseInt(toSlot, 10); pokemon = this.model.getPokemon(this.model.get('index'), 0); this.showSpinner(); return this.model.makeSwitch(toSlot, forSlot, this.afterSelection.bind(this, pokemon)); }; BattleView.prototype.cancelAction = function(e) { var pokemon; this.$('.battle_actions').html("
Canceling...
"); pokemon = this.model.getPokemon(this.model.get('index'), 0); this.model.makeCancel(); return this.afterAction(pokemon); }; BattleView.prototype.megaEvolve = function(e) { var $target, pokemon; $target = $(e.currentTarget); $target.toggleClass('pressed'); pokemon = this.model.getPokemon(this.model.get('index'), 0); return pokemon.set('megaEvolve', $target.hasClass("pressed")); }; BattleView.prototype.afterSelection = function(pokemon) { this.disableButtons(); this.pauseTimer(this.model.get('index'), 0); return this.afterAction(pokemon); }; BattleView.prototype.afterAction = function(pokemon) { return pokemon.set('megaEvolve', false); }; BattleView.prototype.preloadImages = function() { var gen, image, pokemonUrl, pokemonUrls, teams, _i, _len, _results; gen = window.Generations[this.model.get('generation').toUpperCase()]; teams = this.model.get('teams').map((function(_this) { return function(team, playerIndex) { var front; front = _this.isFront(playerIndex); return team.get('pokemon').map(function(pokemon) { var forme, formeName, formeNames, formes, id, shiny, species, _i, _len, _results; species = pokemon.get('species'); forme = pokemon.get('forme'); shiny = pokemon.get('shiny'); id = gen.SpeciesData[species].id; formes = gen.FormeData[species]; formeNames = _.keys(formes); formeNames = _.filter(formeNames, function(formeName) { return forme === formeName || formes[formeName].isBattleOnly; }); _results = []; for (_i = 0, _len = formeNames.length; _i < _len; _i++) { formeName = formeNames[_i]; _results.push(PokemonSprite(id, formeName, { front: front, shiny: shiny })); } return _results; }); }; })(this)); pokemonUrls = _.flatten(_.zip.apply(_, teams)); _results = []; for (_i = 0, _len = pokemonUrls.length; _i < _len; _i++) { pokemonUrl = pokemonUrls[_i]; image = new Image(); _results.push(image.src = pokemonUrl); } return _results; }; BattleView.prototype.addPokemonImage = function($div, url, options) { var $image, image, scale; if (options == null) { options = {}; } scale = options.scale || 1; image = new Image(); $image = $(image); $image.load((function(_this) { return function() { var height, width; width = image.width, height = image.height; if (scale !== 1) { width *= scale; height *= scale; $image.width(width); $image.height(height); } return typeof options.callback === "function" ? options.callback($image) : void 0; }; })(this)); image.src = url; return $image.hide().appendTo($div); }; BattleView.prototype.getPokemonPosition = function(player, slot) { if (player === this.model.get('index')) { return [96, 208]; } else { return [332, 108]; } }; BattleView.prototype.remove = function() { clearTimeout(this.countdownTimersId); return BattleView.__super__.remove.call(this); }; BattleView.prototype.pokemonHtml = function(pokemon) { return "" + (pokemon.escape('name')) + ""; }; BattleView.prototype.setVisibleTeam = function() { var battle; battle = this.model; return battle.set('visibleteam', true); }; return BattleView; })(Backbone.View); }).call(this); (function() { var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; this.ChatView = (function(_super) { var MAX_MESSAGES_LENGTH, MAX_USERNAME_HISTORY; __extends(ChatView, _super); function ChatView() { this.scrollToBottom = __bind(this.scrollToBottom, this); this.isAtBottom = __bind(this.isAtBottom, this); this.linkify = __bind(this.linkify, this); this.sanitize = __bind(this.sanitize, this); this.timestamp = __bind(this.timestamp, this); this.clear = __bind(this.clear, this); this.print = __bind(this.print, this); this.announce = __bind(this.announce, this); this.cleanChat = __bind(this.cleanChat, this); this.rawMessage = __bind(this.rawMessage, this); this.userLeave = __bind(this.userLeave, this); this.userJoin = __bind(this.userJoin, this); this.handleMessage = __bind(this.handleMessage, this); this.userColor = __bind(this.userColor, this); this.userMessage = __bind(this.userMessage, this); this.handleKeys = __bind(this.handleKeys, this); this.tabComplete = __bind(this.tabComplete, this); this.sendChat = __bind(this.sendChat, this); this.focusChat = __bind(this.focusChat, this); this.getSelectedText = __bind(this.getSelectedText, this); this.renderUserList = __bind(this.renderUserList, this); this.render = __bind(this.render, this); this.setTopic = __bind(this.setTopic, this); this.initialize = __bind(this.initialize, this); return ChatView.__super__.constructor.apply(this, arguments); } ChatView.prototype.template = JST['chat']; ChatView.prototype.userListTemplate = JST['user_list']; ChatView.prototype.events = { 'click': 'focusChat', 'keydown .chat_input': 'handleKeys', 'click .chat_input_send': 'sendChat', 'scroll_to_bottom': 'scrollToBottom' }; MAX_USERNAME_HISTORY = 10; MAX_MESSAGES_LENGTH = 500; ChatView.prototype.initialize = function(options) { var callback, eventName, _i, _len, _ref; this.noisy = options.noisy; if (this.model) { this.listenTo(this.model.get('users'), 'add remove reset', this.renderUserList); if (this.noisy) { this.listenTo(this.model.get('users'), 'add', this.userJoin); this.listenTo(this.model.get('users'), 'remove', this.userLeave); } _ref = Room.prototype.EVENTS; for (_i = 0, _len = _ref.length; _i < _len; _i++) { eventName = _ref[_i]; callback = this[eventName] || (function() { throw new Error("ChatView must implement " + eventName + "."); })(); this.listenTo(this.model, eventName, callback); } } this.chatHistory = []; this.mostRecentNames = []; this.tabCompleteIndex = -1; return this.tabCompleteNames = []; }; ChatView.prototype.setTopic = function(topic) { topic = this.sanitize(topic); return this.rawMessage("
Topic: " + topic + "
"); }; ChatView.prototype.render = function() { this.$el.html(this.template()); if (this.model) { this.$el.removeClass('without_spectators'); this.$el.removeClass('without_chat_input'); this.renderUserList(); } return this; }; ChatView.prototype.renderUserList = function() { this.$('.user_count').text("Users (" + (this.model.get('users').length) + ")"); this.$('.users').html(this.userListTemplate({ userList: this.model.get('users').models })); return this; }; ChatView.prototype.getSelectedText = function() { var text; text = ""; if (window.getSelection) { text = window.getSelection().toString(); } else if (document.selection && document.selection.type !== "Control") { text = document.selection.createRange().text; } return text; }; ChatView.prototype.focusChat = function() { var selectedText; selectedText = this.getSelectedText(); if (selectedText.length === 0) { return this.$('.chat_input').focus(); } }; ChatView.prototype.sendChat = function() { var $this, message; $this = this.$('.chat_input'); message = $this.val(); if (this.model.sendChat(message)) { this.chatHistory.push(message); delete this.chatHistoryIndex; return $this.val(''); } }; ChatView.prototype.tabComplete = function($input, options) { var candidates, cursorIndex, length, newPrefix, newPrefixLength, pieces, possibleName, rest, tabbedName, text; if (options == null) { options = {}; } cursorIndex = $input.prop('selectionStart'); text = $input.val(); if (this.tabCompleteNames.length > 0 && this.tabCompleteCursorIndex === cursorIndex) { if (options.reverse) { this.tabCompleteIndex -= 1; if (this.tabCompleteIndex < 0) { this.tabCompleteIndex = this.tabCompleteNames.length - 1; } } else { this.tabCompleteIndex = (this.tabCompleteIndex + 1) % this.tabCompleteNames.length; } } else { delete this.tabCompleteCursorIndex; pieces = text.slice(0, cursorIndex).split(' '); possibleName = pieces.pop(); rest = pieces.join(' '); if (pieces.length > 0) { rest += ' '; } length = possibleName.length; if (length === 0) { return; } candidates = _.union(this.mostRecentNames, this.model.get('users').pluck('id')); candidates = candidates.filter(function(name) { return name.slice(0, length).toLowerCase() === possibleName.toLowerCase(); }); if (candidates.length === 0) { return; } if (options.reverse) { this.tabCompleteIndex = candidates.length - 1; } else { this.tabCompleteIndex = 0; } this.tabCompleteNames = candidates; this.tabCompletePrefix = rest; this.tabCompleteCursorIndex = cursorIndex; } tabbedName = this.tabCompleteNames[this.tabCompleteIndex]; newPrefix = this.tabCompletePrefix + tabbedName; newPrefixLength = newPrefix.length; $input.val(newPrefix + text.slice(cursorIndex)); $input[0].setSelectionRange(newPrefixLength, newPrefixLength); return this.tabCompleteCursorIndex = newPrefixLength; }; ChatView.prototype.handleKeys = function(e) { var $input; $input = $(e.currentTarget); switch (e.which) { case 13: e.preventDefault(); return this.sendChat(); case 9: e.preventDefault(); return this.tabComplete($input, { reverse: e.shiftKey }); case 38: e.preventDefault(); if (this.chatHistory.length === 0) { return; } if (this.chatHistoryIndex == null) { this.chatHistoryIndex = this.chatHistory.length; this.chatHistoryText = $input.val(); } if (this.chatHistoryIndex > 0) { this.chatHistoryIndex -= 1; return $input.val(this.chatHistory[this.chatHistoryIndex]); } break; case 40: e.preventDefault(); if (this.chatHistoryIndex == null) { return; } this.chatHistoryIndex += 1; if (this.chatHistoryIndex === this.chatHistory.length) { $input.val(this.chatHistoryText); return delete this.chatHistoryIndex; } else { return $input.val(this.chatHistory[this.chatHistoryIndex]); } } }; ChatView.prototype.userMessage = function(username, message) { var displayName, highlight, index, u, user, yourName; user = this.model.get('users').get(username); displayName = (user != null ? user.getDisplayName() : void 0) || username; yourName = PokeBattle.username; highlight = new RegExp("\\b" + yourName + "\\b", 'i').test(message); u = "" + displayName + ":"; this.rawMessage("" + (this.timestamp()) + " " + u + " " + (this.sanitize(message)), { highlight: highlight }); this.handleMessage(user, message); index = this.mostRecentNames.indexOf(username); if (index !== -1) { this.mostRecentNames.splice(index, 1); } this.mostRecentNames.push(username); if (this.mostRecentNames.length > MAX_USERNAME_HISTORY) { return this.mostRecentNames.shift(); } }; ChatView.prototype.userColor = function(username) { var c, chr, h, hash, i, l, s, _i, _len; hash = 0; for (i = _i = 0, _len = username.length; _i < _len; i = ++_i) { c = username[i]; chr = username.charCodeAt(i); hash = ((hash << 5) - hash) + chr; hash |= 0; } h = hash % 360; hash /= 360; s = (hash % 25) + 75; l = 50; return "hsl(" + h + ", " + s + "%, " + l + "%)"; }; ChatView.prototype.handleMessage = function(user, message) { var authority, printableCommands, _ref; authority = user != null ? user.get('authority') : void 0; printableCommands = ['/pbv', '/data']; if (authority > 1 && (_ref = message.split(/\s/, 1)[0], __indexOf.call(printableCommands, _ref) >= 0)) { return PokeBattle.commands.execute(this.model, message); } }; ChatView.prototype.userJoin = function(user) { return this.rawMessage("" + (this.timestamp()) + " " + user.id + " joined!"); }; ChatView.prototype.userLeave = function(user) { return this.rawMessage("" + (this.timestamp()) + " " + user.id + " left!"); }; ChatView.prototype.rawMessage = function(message, options) { var klass, wasAtBottom; if (options == null) { options = {}; } wasAtBottom = this.isAtBottom(); klass = []; if (options.highlight) { klass.push('bg-blue'); } if (options["class"]) { klass.push(options["class"]); } this.print("

" + message + "

"); this.cleanChat(); if (wasAtBottom) { return this.scrollToBottom(); } }; ChatView.prototype.cleanChat = function() { var $messages, numToRemove; $messages = this.$('.chat_message'); numToRemove = $messages.length - MAX_MESSAGES_LENGTH; if (numToRemove > 0) { return $messages.slice(0, numToRemove).remove(); } }; ChatView.prototype.announce = function(klass, message) { var wasAtBottom; wasAtBottom = this.isAtBottom(); message = this.linkify(message); this.print("
" + message + "
"); if (wasAtBottom) { return this.scrollToBottom(); } }; ChatView.prototype.print = function(message) { return this.$('.messages').append(message); }; ChatView.prototype.clear = function() { return this.$('.messages').empty(); }; ChatView.prototype.timestamp = function() { var date, hours, minutes, seconds; date = new Date(); hours = date.getHours(); minutes = date.getMinutes(); seconds = date.getSeconds(); minutes = ("00" + minutes).substr(-2); seconds = ("00" + seconds).substr(-2); return "[" + hours + ":" + minutes + ":" + seconds + "]"; }; ChatView.prototype.sanitize = function(message) { var sanitizedMessage; sanitizedMessage = $('
').text(message).html(); return this.linkify(sanitizedMessage); }; ChatView.prototype.linkify = function(message) { message = URI.withinString(message, function(url) { var $a, battleId, battleRegex, host, path, uri, _ref; uri = URI(url); _ref = [uri.host(), uri.path()], host = _ref[0], path = _ref[1]; battleRegex = /^\/battles\/([a-fA-F0-9]+)$/i; $a = $("").prop('href', url).prop('target', '_blank').text(url); if (host === URI(window.location.href).host() && battleRegex.test(path)) { battleId = path.match(battleRegex)[1]; $a.addClass('spectate').attr('data-battle-id', battleId); } return $a.wrap("
").parent().html(); }); return message; }; ChatView.prototype.isAtBottom = function() { var $el; $el = this.$('.messages'); return $el[0].scrollHeight - $el.scrollTop() <= $el.outerHeight(); }; ChatView.prototype.scrollToBottom = function() { var messages; messages = this.$('.messages')[0]; messages.scrollTop = messages.scrollHeight; return false; }; return ChatView; })(Backbone.View); }).call(this); (function() { var attachSelectize, isMobileOrAndroid, setSelectizeDisabled, setSelectizeValue, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; isMobileOrAndroid = function() { if (/Mobile/i.test(window.navigator.userAgent)) { return true; } if (/Android/i.test(window.navigator.userAgent)) { return true; } return false; }; attachSelectize = function($element, options) { if (isMobileOrAndroid()) { return; } return $element.selectize(options); }; setSelectizeValue = function($element, value) { if (isMobileOrAndroid()) { return $element.val(value); } else { return $element.each(function() { var _ref; return (_ref = this.selectize) != null ? _ref.setValue(value) : void 0; }); } }; setSelectizeDisabled = function($element, disabled) { return $element.filter(".selectized").each(function() { if (!this.selectize) { return; } if (disabled) { return this.selectize.disable(); } else { return this.selectize.enable(); } }); }; this.PokemonEditView = (function(_super) { __extends(PokemonEditView, _super); function PokemonEditView() { this.renderMoves = __bind(this.renderMoves, this); this.renderStats = __bind(this.renderStats, this); this.renderNonStats = __bind(this.renderNonStats, this); this.getTeam = __bind(this.getTeam, this); this.renderSpecies = __bind(this.renderSpecies, this); this.renderFormat = __bind(this.renderFormat, this); this.renderTier = __bind(this.renderTier, this); this.renderPBV = __bind(this.renderPBV, this); this.renderPokemon = __bind(this.renderPokemon, this); this.render = __bind(this.render, this); this.disableEventsAndExecute = __bind(this.disableEventsAndExecute, this); this.filterMovesBy = __bind(this.filterMovesBy, this); this.keydownMoves = __bind(this.keydownMoves, this); this.buttonify = __bind(this.buttonify, this); this.removeSelectedMove = __bind(this.removeSelectedMove, this); this.clickSelectedMove = __bind(this.clickSelectedMove, this); this.$selectedMove = __bind(this.$selectedMove, this); this.recordMoves = __bind(this.recordMoves, this); this.insertMove = __bind(this.insertMove, this); this.clickMoveName = __bind(this.clickMoveName, this); this.blurMoves = __bind(this.blurMoves, this); this.preventBlurMoves = __bind(this.preventBlurMoves, this); this.changeHiddenPower = __bind(this.changeHiddenPower, this); this.changeEv = __bind(this.changeEv, this); this.focusEv = __bind(this.focusEv, this); this.changeIv = __bind(this.changeIv, this); this.changeLevel = __bind(this.changeLevel, this); this.changeGender = __bind(this.changeGender, this); this.changeItem = __bind(this.changeItem, this); this.changeAbility = __bind(this.changeAbility, this); this.changeNature = __bind(this.changeNature, this); this.changeForme = __bind(this.changeForme, this); this.changeHappiness = __bind(this.changeHappiness, this); this.changeShiny = __bind(this.changeShiny, this); this.changeNickname = __bind(this.changeNickname, this); this.changeSpecies = __bind(this.changeSpecies, this); this.setTeamTier = __bind(this.setTeamTier, this); this.setTeamPBV = __bind(this.setTeamPBV, this); this.setPokemon = __bind(this.setPokemon, this); this.setGeneration = __bind(this.setGeneration, this); this.sortSpecieslist = __bind(this.sortSpecieslist, this); this.changeSort = __bind(this.changeSort, this); this.setFormat = __bind(this.setFormat, this); this.initialize = __bind(this.initialize, this); return PokemonEditView.__super__.constructor.apply(this, arguments); } PokemonEditView.prototype.editTemplate = JST['teambuilder/pokemon']; PokemonEditView.prototype.speciesTemplate = JST['teambuilder/species']; PokemonEditView.prototype.nonStatsTemplate = JST['teambuilder/non_stats']; PokemonEditView.prototype.movesTemplate = JST['teambuilder/moves']; PokemonEditView.prototype.events = { 'change .sortSpecies': 'changeSort', 'change .species_list': 'changeSpecies', 'change .selected_nickname': 'changeNickname', 'click .selected_shininess': 'changeShiny', 'click .selected_happiness': 'changeHappiness', 'change .selected-forme': 'changeForme', 'change .selected_nature': 'changeNature', 'change .selected_ability': 'changeAbility', 'change .selected_item': 'changeItem', 'change .selected_gender': 'changeGender', 'change .selected_level': 'changeLevel', 'change .iv-entry': 'changeIv', 'focus .ev-entry': 'focusEv', 'blur .ev-entry': 'changeEv', 'change .ev-entry': 'changeEv', 'input .ev-entry[type=range]': 'changeEv', 'change .select-hidden-power': 'changeHiddenPower', 'keydown .selected_moves input': 'keydownMoves', 'blur .selected_moves input': 'blurMoves', 'click .table-moves tbody tr': 'clickMoveName', 'mousedown .table-moves': 'preventBlurMoves', 'click .move-button': 'clickSelectedMove', 'click .move-button .close': 'removeSelectedMove' }; PokemonEditView.prototype.initialize = function(attributes) { if (attributes == null) { attributes = {}; } return this.onPokemonChange = attributes.onPokemonChange; }; PokemonEditView.prototype.setFormat = function(format) { var allformats; allformats = window.PokeBattle.conditions.Formats(); format = allformats[format] || allformats[DEFAULT_FORMAT]; return this.setGeneration(format.generation); }; PokemonEditView.prototype.changeSort = function(e) { var sort; sort = $(e.currentTarget).val(); if (sort === "Default Sort") { return this.sortSpecieslist("Default"); } else if (sort === "Sort by Dexnumber") { return this.sortSpecieslist("id", false); } else if (sort === "Invert by Dexnumber") { return this.sortSpecieslist("id", true); } else if (sort === "Sort Alphabetically") { return this.sortSpecieslist("pokename", false); } else if (sort === "Invert Alphabetically") { return this.sortSpecieslist("pokename", true); } }; PokemonEditView.prototype.sortSpecieslist = function(option, reverse) { var ItemData, MoveData, SpeciesData, data, sortedlist, species, _ref; _ref = this.generation, MoveData = _ref.MoveData, SpeciesData = _ref.SpeciesData, ItemData = _ref.ItemData; if (option === "Default") { sortedlist = this.getSpecies(); } else { sortedlist = this.sortObject(SpeciesData, option, reverse); } this.speciesList = (function() { var _results; _results = []; for (species in sortedlist) { data = sortedlist[species]; _results.push(species); } return _results; })(); return this.render(); }; PokemonEditView.prototype.sortObject = function(data, option, reverse) { var arr, finished, key, newobj, thing, val, _i, _len; arr = []; for (key in data) { val = data[key]; val.pokename = key; arr.push(val); } arr = _.sortBy(arr, option); if (reverse === true) { arr.reverse(); } newobj = {}; for (_i = 0, _len = arr.length; _i < _len; _i++) { thing = arr[_i]; newobj[thing.pokename] = thing; } return finished = newobj; }; PokemonEditView.prototype.setGeneration = function(generation) { var ItemData, MoveData, SpeciesData, data, itemName, species, _ref; this.generation = window.Generations[generation.toUpperCase()]; _ref = this.generation, MoveData = _ref.MoveData, SpeciesData = _ref.SpeciesData, ItemData = _ref.ItemData; this.moveData = MoveData; this.speciesList = (function() { var _results; _results = []; for (species in SpeciesData) { data = SpeciesData[species]; _results.push(species); } return _results; })(); this.itemList = _((function() { var _results; _results = []; for (itemName in ItemData) { data = ItemData[itemName]; _results.push(itemName); } return _results; })()).sort(); return this.render(); }; PokemonEditView.prototype.setPokemon = function(pokemon) { if (this.pokemon) { this.stopListening(this.pokemon); } this.pokemon = pokemon; this.listenTo(pokemon, 'change:level', this.renderStats); this.listenTo(pokemon, 'change:ivs', this.renderStats); this.listenTo(pokemon, 'change:evs', this.renderStats); this.listenTo(pokemon, 'change:nature', this.renderStats); this.listenTo(pokemon, 'change:hiddenPowerType', this.renderStats); this.listenTo(pokemon, 'change:shiny', this.renderSpecies); return this.renderPokemon(); }; PokemonEditView.prototype.setTeamPBV = function(pbv) { return this.teamPBV = pbv; }; PokemonEditView.prototype.setTeamTier = function(tier) { return this.teamTier = tier; }; PokemonEditView.prototype.changeSpecies = function(e) { var species; if (!this.onPokemonChange) { return; } species = $(e.currentTarget).val(); this.pokemon = species ? new Pokemon({ teambuilder: true, species: species }) : new NullPokemon(); return this.onPokemonChange(this.pokemon); }; PokemonEditView.prototype.changeNickname = function(e) { var $input; $input = $(e.currentTarget); return this.pokemon.set("name", $input.val()); }; PokemonEditView.prototype.changeShiny = function(e) { var $switch; $switch = $(e.currentTarget).toggleClass("selected"); return this.pokemon.set("shiny", $switch.is(".selected")); }; PokemonEditView.prototype.changeHappiness = function(e) { var $switch, happiness; $switch = $(e.currentTarget).toggleClass("selected"); happiness = $switch.is(".selected") ? 0 : 100; return this.pokemon.set("happiness", happiness); }; PokemonEditView.prototype.changeForme = function(e) { var $forme; $forme = $(e.currentTarget); this.pokemon.set('forme', $forme.val()); return this.pokemon.set('ability', this.pokemon.getAbilities()[0]); }; PokemonEditView.prototype.changeNature = function(e) { var $list; $list = $(e.currentTarget); return this.pokemon.set("nature", $list.val()); }; PokemonEditView.prototype.changeAbility = function(e) { var $list; $list = $(e.currentTarget); return this.pokemon.set("ability", $list.val()); }; PokemonEditView.prototype.changeItem = function(e) { var $list; $list = $(e.currentTarget); return this.pokemon.set("item", $list.val()); }; PokemonEditView.prototype.changeGender = function(e) { var $list; $list = $(e.currentTarget); return this.pokemon.set("gender", $list.val()); }; PokemonEditView.prototype.changeLevel = function(e) { var $input, value; $input = $(e.currentTarget); value = parseInt($input.val(), 10); if (isNaN(value) || value > 120) { value = 1120; } if (value < 1) { value = 1; } $input.val(value); return this.pokemon.set("level", value); }; PokemonEditView.prototype.changeIv = function(e) { var $input, stat, value; $input = $(e.currentTarget); stat = $input.data("stat"); value = parseInt($input.val(), 10); if (isNaN(value) || value > 31 || value < 0) { value = 31; } return this.pokemon.setIv(stat, value); }; PokemonEditView.prototype.focusEv = function(e) { var $input, value; $input = $(e.currentTarget); if ($input.is("[type=range]")) { return; } value = parseInt($input.val(), 10); if (value === 0) { return $input.val(""); } }; PokemonEditView.prototype.changeEv = function(e) { var $input, stat, value; $input = $(e.currentTarget); stat = $input.data("stat"); value = parseInt($input.val(), 10); if (value > 252) { value = 252; } if (isNaN(value) || value < 0) { value = 0; } value = this.pokemon.setEv(stat, value); if (!$input.is("[type=range]")) { return $input.val(value); } }; PokemonEditView.prototype.changeHiddenPower = function(e) { var $input, type; $input = $(e.currentTarget); type = $input.val(); return this.pokemon.set('hiddenPowerType', type.toLowerCase()); }; PokemonEditView.prototype.preventBlurMoves = function(e) { this._preventBlur = true; return _.defer((function(_this) { return function() { return _this._preventBlur = false; }; })(this)); }; PokemonEditView.prototype.blurMoves = function(e) { var $input, $selectedMove, moveName, previousScrollPosition; $input = $(e.currentTarget); if (this._preventBlur) { previousScrollPosition = this.$el.scrollTop(); $input.focus(); e.preventDefault(); this.$el.scrollTop(previousScrollPosition); return; } $selectedMove = this.$selectedMove(); moveName = $selectedMove.data('move-id'); this.filterMovesBy(""); $(".table-moves .active").removeClass("active"); if ($input.val().length === 0) { return this.recordMoves(); } else { return this.insertMove($input, moveName); } }; PokemonEditView.prototype.clickMoveName = function(e) { var $input, $moves, $this, moveName; $this = $(e.currentTarget); moveName = $this.data('move-id'); $moves = this.$el.find('.selected_moves'); $input = $moves.find('input:focus').first(); if ($input.length === 0) { $input = $moves.find('input').first(); } if ($input.length === 0) { return; } return this.insertMove($input, moveName); }; PokemonEditView.prototype.insertMove = function($input, moveName) { var $firstInput, $moves, currentScrollPosition; currentScrollPosition = this.$el.scrollTop(); this.preventBlurMoves(); if (!this.buttonify($input, moveName)) { return; } $moves = this.$el.find('.selected_moves'); $firstInput = $moves.find('input').first(); if ($firstInput.length > 0) { $firstInput.focus(); this.$el.scrollTop(currentScrollPosition); } else { this.$el.scrollTop(0); } return this.recordMoves(); }; PokemonEditView.prototype.recordMoves = function() { var $moves, movesArray; movesArray = []; $moves = this.$el.find('.selected_moves'); $moves.find('.move-button').each(function() { var moveName; moveName = $(this).find("span").text().trim(); if (moveName !== "") { return movesArray.push(moveName); } }); return this.pokemon.set("moves", movesArray); }; PokemonEditView.prototype.$selectedMove = function() { var $allMoves, $table; $table = this.$el.find('.table-moves'); $allMoves = $table.find('tbody tr'); return $allMoves.filter('.active').first(); }; PokemonEditView.prototype.clickSelectedMove = function(e) { var $input, $this, moveName; $this = $(e.currentTarget); moveName = $this.find('span').text(); $input = $(""); $this.replaceWith($input); $input.focus().select(); return $(".table-moves tr[data-move-id='" + moveName + "']").addClass("active"); }; PokemonEditView.prototype.removeSelectedMove = function(e) { var $input, $this; $this = $(e.currentTarget).parent(); $input = $(""); $this.replaceWith($input); $input.focus(); return e.stopPropagation(); }; PokemonEditView.prototype.buttonify = function($input, moveName) { var type; if (!(moveName in this.moveData)) { return false; } if ($input.is(":focus")) { this.filterMovesBy(""); $(".table-moves .active").removeClass("active"); } type = this.moveData[moveName].type.toLowerCase(); $input.replaceWith("
" + moveName + "
×
"); return true; }; PokemonEditView.prototype.keydownMoves = function(e) { var $activeMove, $allMoves, $input, $nextMove, $prevMove, $table; $input = $(e.currentTarget); $table = this.$el.find('.table-moves'); $allMoves = $table.find('tbody tr'); switch (e.which) { case 13: $activeMove = this.$selectedMove(); return $activeMove.click(); case 38: $activeMove = $allMoves.filter('.active').first(); $prevMove = $activeMove.prevAll(":visible").first(); if ($prevMove.length > 0) { $activeMove.removeClass('active'); return $prevMove.addClass('active'); } break; case 40: $activeMove = $allMoves.filter('.active').first(); $nextMove = $activeMove.nextAll(":visible").first(); if ($nextMove.length > 0) { $activeMove.removeClass('active'); return $nextMove.addClass('active'); } break; default: return _.defer((function(_this) { return function() { var moveName; if (!$input.is(":focus")) { return; } moveName = $input.val(); return _this.filterMovesBy(moveName); }; })(this)); } }; PokemonEditView.prototype.filterMovesBy = function(moveName) { var $allMoves, $moves, $table, moveRegex; moveName = moveName.replace(/\s+|-/g, ""); $table = this.$el.find('.table-moves'); $allMoves = $table.find('tbody tr'); moveRegex = new RegExp(moveName, "i"); $moves = $allMoves.filter(function() { var $move; $move = $(this); moveName = $move.data('move-search-id'); return moveRegex.test(moveName); }); $table.addClass('hidden'); $moves.removeClass('hidden'); $allMoves.not($moves).addClass('hidden'); $allMoves.removeClass('active'); $moves.first().addClass('active'); return $table.removeClass('hidden'); }; PokemonEditView.prototype.disableEventsAndExecute = function(callback) { var isOutermost; isOutermost = !this._eventsDisabled; this._eventsDisabled = true; if (isOutermost) { this.undelegateEvents(); } callback(); if (isOutermost) { this.delegateEvents(); } if (isOutermost) { return this._eventsDisabled = false; } }; PokemonEditView.prototype.render = function() { this.$el.html(this.editTemplate({ window: window, speciesList: this.speciesList, itemList: this.itemList })); attachSelectize(this.$el.find(".species_list"), { render: { option: (function(_this) { return function(item, escape) { var pbv, team, tier; team = _this.pokemon.getTeam(); if (team.hasPBV()) { pbv = PokeBattle.PBV.determinePBV(_this.generation, { species: item.value }); return "
" + item.text + "
" + pbv + "
"; } else if (team.hasTier()) { tier = PokeBattle.Tier.determineTier(_this.generation, { species: item.value }); return "
" + item.text + "
" + tier.humanName + "
"; } }; })(this) } }); attachSelectize(this.$el.find(".selected_item")); return this; }; PokemonEditView.prototype.renderPokemon = function() { var $elements; this.renderSpecies(); this.renderNonStats(); this.renderStats(); this.renderMoves(); this.renderFormat(); $elements = this.$el.find("input, select").not(".species input, .species select"); $elements.prop("disabled", this.pokemon.isNull); setSelectizeDisabled($elements, this.pokemon.isNull); return this; }; PokemonEditView.prototype.renderPBV = function() { var individualPBV, maxPBV, pbv, team; individualPBV = this.pokemon.getPBV(); this.$(".individual-format").text(individualPBV); team = this.pokemon.getTeam(); pbv = team.getPBV(); maxPBV = team.getMaxPBV(); this.$(".total-format").text(pbv).toggleClass("red", pbv > maxPBV); return this.$(".max-format").text(maxPBV); }; PokemonEditView.prototype.renderTier = function() { var individualTier, maxTier, team, teamtier, tier; individualTier = this.pokemon.getTier(); this.$('.individual-format').text(individualTier.humanName); team = this.pokemon.getTeam(); if (team) { teamtier = team.getTier(); tier = team.getTier(); maxTier = team.getMaxTier(); this.$(".total-format").text(teamtier.humanName).toggleClass("red", teamtier.tierRank > maxTier.tierRank); return this.$(".max-format").text(maxTier.humanName); } }; PokemonEditView.prototype.renderFormat = function() { var team; team = this.pokemon.getTeam(); if (team && team.hasPBV()) { return this.renderPBV(); } else if (team && team.hasTier()) { return this.renderTier(); } }; PokemonEditView.prototype.renderSpecies = function() { return this.disableEventsAndExecute((function(_this) { return function() { var html; setSelectizeValue(_this.$(".species_list"), _this.pokemon.get("species")); html = _this.pokemon.isNull ? "" : _this.speciesTemplate({ window: window, pokemon: _this.pokemon }); _this.$(".species-info").html(html); _this.$(".selected_shininess").toggleClass("selected", _this.pokemon.get('shiny') === true); return _this.$(".selected_happiness").toggleClass("selected", _this.pokemon.get("happiness") === 0); }; })(this)); }; PokemonEditView.prototype.getTeam = function() { return this.pokemon.getTeam(); }; PokemonEditView.prototype.renderNonStats = function() { var $nonStats, displayedGenders, populateSelect; $nonStats = this.$el.find(".non-stats"); populateSelect = function(searchStr, valueTextPairs, selectedValue) { var $select, pair, text, value, _i, _len; $select = $nonStats.find(searchStr).empty(); for (_i = 0, _len = valueTextPairs.length; _i < _len; _i++) { pair = valueTextPairs[_i]; value = text = pair; if (pair instanceof Array) { value = pair[0]; text = pair[1]; } $select.append($("
"); return; } return room.announce('success', message); }); dataPokemon = function(pokemon) { var abilities, forme, formeName, formeSlug, hiddenAbility, message, pokeBattleValue, speciesName, speciesSlug, statNames, stats, statsText, types, _ref; speciesName = pokemon[0], formeName = pokemon[1]; _ref = [slugify(speciesName), slugify(formeName)], speciesSlug = _ref[0], formeSlug = _ref[1]; forme = window.Generations.XY.FormeData[speciesName][formeName]; types = forme.types, abilities = forme.abilities, hiddenAbility = forme.hiddenAbility, stats = forme.stats, pokeBattleValue = forme.pokeBattleValue; abilities = _.clone(abilities); if (hiddenAbility != null) { abilities.push(hiddenAbility); } abilities = _(abilities).map(function(a) { return linkToDex("abilities/" + (slugify(a)), a); }); abilities = abilities.join('/'); if (hiddenAbility != null) { abilities += " (H)"; } types = _(types).map(function(t) { return linkToDex("types/" + (slugify(t)), "" + t + ""); }); statNames = ['HP', 'Attack', 'Defense', 'Sp.Attack', 'Sp.Defense', 'Speed']; stats = [stats.hp, stats.attack, stats.defense, stats.specialAttack, stats.specialDefense, stats.speed]; statsText = _.map(_.zip(statNames, stats), function(a) { return a.join(': '); }).join(' / '); message = "" + (pokemonIcon(speciesName, formeName, "left")) + "\n

\n" + (formatName(speciesName, formeName)) + ": " + (types.join('')) + " |\n" + abilities + "
" + statsText + " |\n" + (_(stats).reduce(function(a, b) { return a + b; })) + " BST\n| PBV: " + pokeBattleValue + "\n" + (linkToDex("pokemon/" + speciesSlug + "/" + formeSlug, "See dex entry »")) + "\n

"; return message; }; dataItem = function(itemName) { var item, message; item = window.Generations.XY.ItemData[itemName]; message = "" + itemName + ": " + item.description; if (item.naturalGift) { message += " Natural Gift is " + item.naturalGift.type + " type and has " + item.naturalGift.power + " base power."; } if (item.flingPower) { message += " Fling has " + item.flingPower + " base power."; } if (item.unreleased) { message += " Currently unreleased in Gen 6."; } return message; }; dataMove = function(moveName) { var acc, category, maxpp, message, move, power, priority, target, type; move = window.Generations.XY.MoveData[moveName]; type = linkToDex("types/" + (slugify(move.type)), "" + move.type + ""); category = ""; target = ""; power = move.power || "—"; acc = move.accuracy || "—"; maxpp = Math.floor(move.pp * 8 / 5); if (move.priority > 0) { priority = "+" + move.priority; } else if (move.priority < 0) { priority = move.priority; } message = "" + moveName + ": " + type + " " + category + " " + target + " "; message += "Power: " + power + " Acc: " + acc + " PP: " + move.pp + " (max " + maxpp + ")"; message += "
"; if (priority) { message += "Priority " + priority + ". "; } message += move.description; message += " "; message += linkToDex("moves/" + (slugify(moveName)), "See who learns this move »"); return message; }; dataAbility = function(abilityName) { var ability, message; ability = window.Generations.XY.AbilityData[abilityName]; message = "" + abilityName + ": " + ability.description + "\n" + (linkToDex("abilities/" + (slugify(abilityName)), "See who obtains this ability »")); return message; }; findPokemon = function(pokemonName) { var formeName, name, speciesData, speciesName, _ref; pokemonName = normalize(pokemonName); _ref = window.Generations.XY.FormeData; for (speciesName in _ref) { speciesData = _ref[speciesName]; for (formeName in speciesData) { name = speciesName; if (formeName !== 'default') { name += formeName; } name = normalize(name); name += name; if (name.indexOf(pokemonName) !== -1) { return [speciesName, formeName]; } } } return null; }; findItem = function(itemName) { var name, normalized; normalized = normalize(itemName); for (name in window.Generations.XY.ItemData) { if (normalized === normalize(name)) { return name; } } return null; }; findMove = function(moveName) { var name, normalized; normalized = normalize(moveName); for (name in window.Generations.XY.MoveData) { if (normalized === normalize(name)) { return name; } } return null; }; findAbility = function(abilityName) { var name, normalized; normalized = normalize(abilityName); for (name in window.Generations.XY.AbilityData) { if (normalized === normalize(name)) { return name; } } return null; }; slugify = function(str) { return str.toLowerCase().replace(/[^a-z0-9]/g, '-').replace(/\-{2,}/g, '-'); }; normalize = function(str) { return str.trim().toLowerCase().replace(/[^a-zA-Z0-9]+/g, ''); }; formatName = function(speciesName, formeName) { var pokemonName; if (formeName === 'default') { pokemonName = speciesName; } else { pokemonName = speciesName; pokemonName += ' '; pokemonName += formeName.split('-').map(function(n) { return n[0].toUpperCase() + n.slice(1); }).join('-'); } return pokemonName; }; linkToDex = function(slug, text) { return "
" + text + ""; }; pokemonIcon = function(speciesName, formeName, classes) { var style; if (classes == null) { classes = ""; } style = window.PokemonIconBackground(speciesName, formeName); return ""; }; }).call(this); (function() { var $body, $popup, reconnectTimer; $body = $("body"); $popup = $('#popup'); PokeBattle.primus.on('open', function() { $popup.hide(); return PokeBattle.rooms.rawMessage("Connected to the server!", { "class": "yellow italic" }); }); PokeBattle.primus.on('reconnecting', function() { return PokeBattle.rooms.rawMessage("Lost connection to the server...", { "class": "red italic" }); }); PokeBattle.primus.on('end', function() { return PokeBattle.rooms.rawMessage("Connection terminated!", { "class": "red italic" }); }); PokeBattle.primus.on('reconnecting', function(opts) { var $div, seconds; seconds = Math.floor(opts.timeout / 1000); if ($popup.length === 0) { $popup = $('