(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!", WEATHER_FAIL_RAIN: "There is no relief from this heavy rain!", WEATHER_FAIL_SUN: "The extremely harsh sunlight was not lessened at all!", HARSHSUN_MOVEFAIL: "The Water-type attack evaporated in the harsh sunlight!", HEAVYRAIN_MOVEFAIL: "The Fire-type attack fizzled out in the heavy rain!", HARSHSUN_START: "The sunlight turned extremely harsh!", HEAVYRAIN_START: "A heavy rain began to fall!", HARSHSUN_END: "The sunlight turned extremely harsh!", HEAVYRAIN_END: "A heavy rain began to fall!", DELTASTREAM_START: "A mysterious air current is protecting Flying-type Pok�mon!", WEATHER_FAIL_AIR: "The mysterious air current blows on regardless!", DELTASTREAM_END: "The mysterious air current has dissipated!", DELTASTREAM_MOVEFAIL: "The mysterious air current weakened the attack!" } } }; 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, PRIMAL_LIMIT: 13, TIER_LC: 14, TIER_PU: 15, TIER_NU: 16, TIER_RU: 17, TIER_UU: 18, TIER_OU: 19, TIER_Uber: 20 }; 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", PRIMAL_LIMIT: "Primal Limit" } }; self.PresetFormats = { insur1000: { name: 'insur1000', humanName: 'Insurgence 1000', generation: 'in', conditions: [this.Conditions.PBV_1000, this.Conditions.TEAM_PREVIEW, this.Conditions.PRIMAL_LIMIT], 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, this.Conditions.PRIMAL_LIMIT], playable: true, priority: 10, tierBased: false }, xy500: { name: 'xy500', humanName: '500 PBV XY', generation: 'xy', conditions: [this.Conditions.PBV_500, this.Conditions.TEAM_PREVIEW, this.Conditions.PRIMAL_LIMIT], 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, Conditions.PRIMAL_LIMIT]; priority = tierData.priority; humanname = "" + GenerationCondition[gen].humanName + " " + tierData.humanName; } else { formatname = this.GenerationCondition[gen].conditionname + tier; _conditions = [this.Conditions[key], this.Conditions.TEAM_PREVIEW, this.Conditions.PRIMAL_LIMIT]; 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, eeveelutions, getGenerationFromInt, getMinimumGeneration, levelLimit, 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; }); levelLimit = false; 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, origspecies, species, theFormes, thePokemon, _i, _j, _k, _len, _len1, _ref1; minimumGeneration = getMinimumGeneration(forGeneration); species = pokemon.species, forme = pokemon.forme, ability = pokemon.ability; origspecies = species; 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; }; eeveelutions = ['Vaporeon', 'Jolteon', 'Flareon', 'Espeon', 'Umbreon', 'Leafeon', 'Glaceon', 'Sylveon']; self.learnableMoves = function(Generations, pokemon, forGeneration) { var ele, index, learnable, remindex, _i, _len, _ref1; 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; } }); if ((_ref1 = pokemon.species, __indexOf.call(eeveelutions, _ref1) >= 0) && forGeneration === 7) { remindex = -1; for (index = _i = 0, _len = learnable.length; _i < _len; index = ++_i) { ele = learnable[index]; if (__indexOf.call(ele, "Hydro Pump") >= 0 && __indexOf.call(ele, "Flare Blitz") >= 0 && __indexOf.call(ele, "Psychic") >= 0 && pokemon.species !== 'Eevee') { remindex = index; } } learnable.splice(remindex, 1); } 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 || generation.maxLevel; 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 |= 120; if (levelLimit = false) { return true; } 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, __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).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: true, priority: 3 }, 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; } } if (species === "Rayquaza" && (pokemon.moves != null) && __indexOf.call(pokemon.moves, "Dragon Ascent") >= 0) { forme = "mega"; } 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', HEAVYRAIN: 'HeavyRain' }; }).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', this.getGeneration.maxLevel); } 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(); if (typeof move === "undefined") { console.log(moveName); } 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') || this.getGeneration.maxLevel; 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; if (this.get('species') === "Rayquaza" && __indexOf.call(this.get('moves'), "Dragon Ascent") >= 0) { return true; } 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 "/pokemon/" + (this.get('species')); }; 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; 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); $button = $actions.find('.mega-evolve'); if (pokemon.canMegaEvolve()) { $button.removeClass("hidden"); } else { $button.addClass('disabled'); } $actions.find('.move.button').each((function(_this) { return function(i, el) { var $this, gen, moveData, moveName, _ref; $this = $(el); moveName = $this.data('move-id'); gen = _this.model.get('generation').toUpperCase(); moveData = (_ref = window.Generations[gen]) != null ? _ref.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'); return pokemon = _this.model.getPokemon(team, slot); }; })(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); pokemon.set('beeninbattle', true); 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']; console.log(pokemon.getIllu()); 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.changeLevel2 = __bind(this.changeLevel2, 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.arrToObject = __bind(this.arrToObject, this); this.objectToArr = __bind(this.objectToArr, this); this.filterTier = __bind(this.filterTier, 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.tierFilterBool = true; PokemonEditView.prototype.events = { 'change .sortSpecies': 'changeSort', 'change .filter-tier': 'filterTier', '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.filterTier = function(e) { var FormeData, SpeciesData, arr, data, obj, species, thistier, _i, _len, _ref; thistier = this.pokemon.getTeam().getTier().tierRank; _ref = this.generation, SpeciesData = _ref.SpeciesData, FormeData = _ref.FormeData; if (e.target.checked) { arr = this.objectToArr(SpeciesData); console.log(thistier); for (_i = 0, _len = arr.length; _i < _len; _i++) { obj = arr[_i]; obj.tier = window.PokeBattle.Tier.Tiers[FormeData[obj.pokename]["default"].tier[0]].tierRank; } console.log(arr); arr = _.filter(arr, function(thing) { return thing.tier === thistier; }); obj = this.arrToObject(arr); this.speciesList = (function() { var _results; _results = []; for (species in obj) { data = obj[species]; _results.push(species); } return _results; })(); return this.render(); } else { this.speciesList = (function() { var _results; _results = []; for (species in SpeciesData) { data = SpeciesData[species]; _results.push(species); } return _results; })(); return this.render(); } }; PokemonEditView.prototype.objectToArr = function(data) { var arr, key, val; arr = []; for (key in data) { val = data[key]; val.pokename = key; arr.push(val); } return arr; }; PokemonEditView.prototype.arrToObject = function(arr) { var obj, thing, _i, _len; obj = {}; for (_i = 0, _len = arr.length; _i < _len; _i++) { thing = arr[_i]; obj[thing.pokename] = thing; } return obj; }; PokemonEditView.prototype.changeSort = function(e) { var sort; sort = $(e.currentTarget).val(); if (sort === "Sort") { return this.sortSpecieslist("tier", false); } 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); } else if (sort === "Sort by Tier") { return this.sortSpecieslist("tier", false); } else if (sort === "Invert by Tier") { return this.sortSpecieslist("tier", 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 FormeData, arr, finished, obj, _i, _len; arr = this.objectToArr(data); if (option !== 'tier') { arr = _.sortBy(arr, option); } else { FormeData = this.generation.FormeData; for (_i = 0, _len = arr.length; _i < _len; _i++) { obj = arr[_i]; obj.tier = window.PokeBattle.Tier.Tiers[FormeData[obj.pokename]["default"].tier[0]].tierRank; arr = _.sortBy(arr, 'tier'); } } if (reverse === true) { arr.reverse(); } obj = this.arrToObject(arr); return finished = obj; }; 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, ItemData, item, itemdata; $list = $(e.currentTarget); item = $list.val(); ItemData = this.generation.ItemData; itemdata = ItemData[item]; this.pokemon.set("item", item); if (typeof itemdata.itemForme !== 'undefined' && itemdata.itemForme[0] === this.pokemon.get('species')) { return this.pokemon.set('forme', itemdata.itemForme[1]); } else if (typeof this.pokemon.getForme().isItemBased !== 'undefined' && this.pokemon.getForme().isItemBased) { return this.pokemon.set('forme', 'default'); } }; 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 > this.generation.maxLevel) { value = this.generation.maxLevel; } if (value < 1) { value = 1; } return this.changeLevel2(value); }; PokemonEditView.prototype.changeLevel2 = function(level) { var $levelBox; $levelBox = $(".selected_level"); $levelBox.val(level); return this.pokemon.set("level", level); }; 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() { var filtertierbox; 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")); filtertierbox = this.$el.find(".filter-tier-box")[0]; if (this.tierFilterBool === false) { filtertierbox.checked = true; this.tierFilterBool = true; } else if (this.tierFilterBool === true) { filtertierbox.checked = false; this.tierFilterBool = false; } return this; }; PokemonEditView.prototype.renderPokemon = function() { var $elements; this.renderSpecies(); this.renderNonStats(); this.renderStats(); this.renderMoves(); this.renderFormat(); if (typeof this.pokemon.get("level") === "undefined") { this.changeLevel2(this.generation.maxLevel); } $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 = $('