NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name PokeLegends UI // @namespace pokecrap // @version 1.4 // @description Pokemon Party UI // @author Ripster // @match https://www.pokemonlegends.com/explore* // @grant unsafeWindow // ==/UserScript== (function() { var prevInBattle = bInBattle; var lastLine; unsafeWindow.pokeTeam = {slot1: {}, slot2: {}, slot3: {}, slot4: {}, slot5: {}, slot6: {}}; function editSkills(e) { var slot = $(this).parents('.pokemon').attr('id'); var link = unsafeWindow.pokeTeam[slot].link; var name = unsafeWindow.pokeTeam[slot].name; e.preventDefault(); $.get(link, function (data) { data = $(data); var dropdown = data.find('.mws-datatable td select'); var skills = dropdown[0].innerHTML; var skillDiv = $('#pokeSkills'); skillDiv.children().remove(); skillDiv.append( '<div class="mws-panel-header">'+ '<span class="mws-i-24 i-table-1">'+name+"'s Moves</span>"+ '</div>'+ '<div class="mws-panel-body clearfix">'+ '<form id="pokeSkillForm">'+ '<select class="poke-select" id="pokeAtk1" name="atk1">'+skills +'</select>'+ '<select class="poke-select" id="pokeAtk2" name="atk2">'+skills +'</select>'+ '<select class="poke-select" id="pokeAtk3" name="atk3">'+skills +'</select>'+ '<select class="poke-select" id="pokeAtk4" name="atk4">'+skills +'</select>'+ '<input id="skillSubmit" type="text" name="updateSkills" class="mws-button green" value="Save Attack Order">'+ '<button type="button" id="skillCancel" class="mws-button red">Cancel</button>'+ '</form>'+ '</div>' ); skillDiv.find('#pokeAtk2 option[value='+dropdown[1].value+']').prop('selected', true).change(); skillDiv.find('#pokeAtk3 option[value='+dropdown[2].value+']').prop('selected', true).change(); skillDiv.find('#pokeAtk4 option[value='+dropdown[3].value+']').prop('selected', true).change(); $('#skillCancel').click(function (ev) { ev.preventDefault(); skillDiv.addClass('hidden'); skillDiv.children().remove(); }); var pokeSkillForm = $('#pokeSkillForm'); pokeSkillForm.submit(function (event) { event.preventDefault(); }); $('#skillSubmit').click(function () { $('#pokeSkills').addClass('hidden'); $.ajax({ type: 'POST', url: link+'&action=SkillUpdated', data: pokeSkillForm.serialize() }); }); skillDiv.removeClass('hidden'); $('.poke-select').chosen(); }); } function hideTooltips() { $('#party-info > div').addClass('hidden'); } function removePokemon(slot) { /* Slot must be in the format of slotX */ $('#' + slot).children().remove(); $('#'+slot).append('<div class="empty-slot" ondrop="pokeUI.dropPoke(event)" ondragover="pokeUI.allowPokeDrop(event)"></div>'); $('#'+slot+'info').children().remove(); unsafeWindow.pokeTeam[slot] = {}; } function addPokemon(slot, pokemon) { /* Slot must be in the format of slotX */ // Add pokemon to party $('#'+slot).children().remove(); $('#'+slot).append( '<div class="pokemon-name">' + pokemon.name + ' Lv.' + pokemon.level + '</div>'+ '<div>'+ '<div class="poke-edit hidden">'+ '<a href="#" class="mws-i-24 i-pencil-edit"></a>'+ '</div>'+ '<a href="' + pokemon.link + '" ondragstart="pokeUI.dragPoke(event)" draggable="true" target="_blank">'+ '<img src="'+ pokemon.img + '" ondrop="pokeUI.dropPoke(event)" ondragover="pokeUI.allowPokeDrop(event)">'+ '</a>'+ '</div>'+ '<div class=pokemon-hp>' + pokemon.hp + '/' + pokemon.max_hp + '</div>'+ '<div id="hp-bar" class="mws-progressbar-exp ui-progressbar ui-widget ui-wdiget-content ui-corner-all" role="progressbar">'+ '<div class="ui-progressbar-value ui-widget-header ui-corner-all" style="width: ' + pokemon.hp_pct + ';"></div>'+ '</div>'+ '<div id="exp-bar" class="mws-progressbar-exp ui-progressbar ui-widget ui-wdiget-content ui-corner-all" role="progressbar">'+ '<div class="ui-progressbar-value ui-widget-header ui-corner-all" style="width: ' + pokemon.exp_pcnt + ';"></div>'+ '</div>' ); // Fill info div $('#'+slot+'info').children().remove(); $('#'+slot+'info').append( '<table>'+ '<thead>'+ '<tr><th colspan="6">' + pokemon.name + "'s Effort Values</th></tr>"+ '<tr><th>HP</th><th>Atk</th><th>Def</th><th>Spd</th><th>Spcl Atk</th><th>Spcl Def</th></tr>'+ '<tbody><tr>'+ '<tr>'+ '<td>' + pokemon.ev.hp + '</td>'+ '<td>' + pokemon.ev.attack + '</td>'+ '<td>' + pokemon.ev.defence + '</td>'+ '<td>' + pokemon.ev.speed + '</td>'+ '<td>' + pokemon.ev.spcl_atk + '</td>'+ '<td>' + pokemon.ev.spcl_def + '</td>'+ '</tr>'+ '</tr></tbody>'+ '</thead>'+ '</table>' ); $('#'+slot+'info').append( '<table>'+ '<thead>'+ '<tr><th colspan="6">' + pokemon.name + "'s Individual Values</th></tr>"+ '<tr><th>HP</th><th>Atk</th><th>Def</th><th>Spd</th><th>Spcl Atk</th><th>Spcl Def</th></tr>'+ '<tbody><tr>'+ '<tr>'+ '<td>' + pokemon.iv.hp + '</td>'+ '<td>' + pokemon.iv.attack + '</td>'+ '<td>' + pokemon.iv.defence + '</td>'+ '<td>' + pokemon.iv.speed + '</td>'+ '<td>' + pokemon.iv.spcl_atk + '</td>'+ '<td>' + pokemon.iv.spcl_def + '</td>'+ '</tr>'+ '</tr></tbody>'+ '</thead>'+ '</table>' ); unsafeWindow.pokeTeam[slot] = pokemon; $('#'+slot+'info').addClass('hidden'); $('#'+slot+' .i-pencil-edit').click(pokeUI.editSkills); } function loadPokemon(link, img, slot) { var pokemon = {}; // Get pokemon page $.get(link.attr('href'), function (data) { var dataObj = $(data); // Get exp percent var re = /expbar"\)\.innerText\s=\s(.+)\s\+\s"\/"\s\+\s(.*);/; var expBar = re.exec(data); pokemon.exp_pcnt = Math.round(parseInt(expBar[1])/parseInt(expBar[2])*100) + '%'; // Get monster id and image source pokemon.mid = link.attr('href').split('?mid=')[1]; pokemon.img = img.attr('src'); pokemon.link = link.attr('href'); // Find details table var details = dataObj.find('.container > .mws-panel.grid_6 > .mws-panel-body > .mws-panel-content > table td'); // Iterate over columns $(details).each(function (idx, obj) { var txt = $(obj).text().trim() || $(obj).find('input').attr('value'); // Skip blank lines if (txt) { // Parse data, this is ugly but there isn't any specific classes or id's in the table if (txt.includes('Name: ')) { pokemon.name = txt.split('Name: ')[1]; } else if (txt.includes('Level: ')) { pokemon.level = txt.split('Level: ')[1]; } else if (txt.includes('Health: ')) { var hp = txt.split('Health: ')[1].split(' / '); pokemon.hp = parseInt(hp[0]); pokemon.max_hp = parseInt(hp[1]); pokemon.hp_pct = Math.round(pokemon.hp / pokemon.max_hp * 100) + '%'; } } // HP Attack Defence Speed Special Attack Special Defence var cells = dataObj.find('.mws-datatable td'); pokemon.iv = { hp: cells[4].innerHTML, attack: cells[5].innerHTML, defence: cells[6].innerHTML, speed: cells[7].innerHTML, spcl_atk: cells[8].innerHTML, spcl_def: cells[9].innerHTML }; pokemon.ev = { hp: cells[10].innerHTML, attack: cells[11].innerHTML, defence: cells[12].innerHTML, speed: cells[13].innerHTML, spcl_atk: cells[14].innerHTML, spcl_def: cells[15].innerHTML }; addPokemon(slot, pokemon); }); }); } function loadParty() { $.ajax( { url: '/team', cache: true, success: function (data) { // Empty slots var emptySlots = $(data).find('.full-box > .box-empty'); // Clear empty slots $.each(emptySlots, function (idx, obj) { var slot = 'slot' + parseInt($(obj).attr('data-spot')); removePokemon(slot); }); // Full slots var team = $(data).find('.full-box > .box'); // Get pokemon data $.each(team, function (idx, obj) { var slot = 'slot' + parseInt($(obj).attr('data-spot')); var img = $(obj).find('img'); var link = $(obj).find('a'); loadPokemon(link, img, slot); }); } }); } function moveToPC(slot, callback) { $.get( '/xml/team.xml.php', { userTeam: slot, userMonsters: 0, rand: (Math.random() * 1000000) }, callback ); } function moveFromPC(slot, mid, callback) { $.get( '/xml/team.xml.php', { userTeam: slot, userMonsters: mid, rand: (Math.random() * 1000000) }, callback ); } function hoverEnterSlot () { var slot = $(this); var infoSlot = $('#' + slot.attr('id') + 'info'); var edit = slot.find('.poke-edit'); var pos = slot.position(); var height = slot.outerHeight(); var viewport = (pos.left + infoSlot.width()) - $(window).width(); edit.removeClass('hidden'); infoSlot.removeClass('hidden'); infoSlot.css('top', pos.top + height + 'px'); if (viewport > 0) { infoSlot.css('left', (pos.left - viewport) + 'px'); } else { infoSlot.css('left', pos.left + 'px'); } } function hoverExitSlot () { var slot = $(this); var edit = slot.find('.poke-edit'); var infoSlot = $('#' + slot.attr('id') + 'info'); infoSlot.addClass('hidden'); edit.addClass('hidden'); } unsafeWindow.pokeUI = {}; unsafeWindow.pokeUI.allowPokeDrop = function (ev) { ev.preventDefault(); }; unsafeWindow.pokeUI.dragPoke = function (ev) { ev.dataTransfer.setData("text", $(ev.target).parents('.pokemon')[0].id); hideTooltips(); }; unsafeWindow.pokeUI.dropPoke = function (ev) { ev.preventDefault(); var data = ev.dataTransfer.getData('text'); var moveFromSlot = $(document.getElementById(data)).attr('id').split('slot')[1]; var moveToSlot = $(ev.target).parents('div.pokemon').attr('id').split('slot')[1]; var midFrom = unsafeWindow.pokeTeam['slot'+moveFromSlot].mid || false; var midTo = unsafeWindow.pokeTeam['slot'+moveToSlot].mid || false; // Ignore drop on same slot if (moveFromSlot !== moveToSlot) { // Put the pokemon you want to move into the PC box moveToPC(moveFromSlot, function() { // If the slot you're trying to move a pokemon into is not empty if (midTo) { // Put that pokemon into the PC box moveToPC(moveToSlot, function () { // Move your pokemon from the PC back into your party moveFromPC(moveToSlot, midFrom, function () { moveFromPC(moveFromSlot, midTo, loadParty); }); }); } else { // Move your pokemon from the PC into your target slot moveFromPC(moveToSlot, midFrom, loadParty); } }); } }; unsafeWindow.pokeUI.editSkills = editSkills; // Build div html var partyDiv = '<div id="party">'; var infoDiv = '<div id="party-info">'; for (var i = 1; i < 7; i++) { var slot = 'slot' + i; var slotInfo = slot + 'info'; partyDiv += '<div class="pokemon" id="' + slot + '"><div class="empty-slot" ondrop="pokeUI.dropPoke(event)" ondragover="pokeUI.allowPokeDrop(event)"></div></div>'; infoDiv += '<div id="' + slotInfo + '" class="hidden info-slot"></div>'; } partyDiv += '</div>'; infoDiv += '</div>'; // Insert divs $('#divPm').before(partyDiv); $('#party').after(infoDiv); $('.container').append('<div class="mws-panel hidden" id="pokeSkills"></div>'); // Add onhover events $('.pokemon').hover(hoverEnterSlot, hoverExitSlot); // Initially load party loadParty(); // Update after battle setInterval(function () { if (prevInBattle === true && bInBattle === false) { loadParty(); } prevInBattle = bInBattle; }, 1000); // Update after healing setInterval(function () { if (activeScript.length > 0) { var scriptData = activeScript[0].args; if (lastLine !== scriptData) { if (scriptData == 'Your Pokemon are fighting fit.' || scriptData === '...And done. Your Pokemon are good to go!') { loadParty(); } lastLine = scriptData; } } }, 10); })();