NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript==
// @name Flight Rising Helper
// @namespace Flight Rising
// @author Jonathon Braswell
// @description A powerful, feature-rich toolbox for Flight Rising.
// @include http://flightrising.com/*
// @version 2.4
// @license MIT
// ==/UserScript==
/**
* MIT License
* Copyright (c) 2017 Jonathon Braswell
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
/*
* Flight Rising Helper
* @namespace FlightRisingHelper
* @dependency jQuery (included on site)
* @author Jonathon Braswell
*/
var FlightRisingHelper = (($) => {
/** UTILITY FUNCTIONS **/
let
/*
* Send async AJAX POST request.
* @function _request
* @private
* @param payload {object} Data payload to [path].
* @param path {string} Directory or URL path to send [payload] to.
*/
_request = (payload, path) => {
// Simply return AJAX promise.
return $.ajax({
type: 'POST'
,data: payload || {}
,url: path
,cache: false
});
}
/*
* Extract a dragon's unique identifier from a given [card] element.
* @function _extractDragonIdFromCard
* @private
* @param card {HTMLDomElement|jQuery Object} Element from which to extract a dragon's unique identifier.
*/
,_extractDragonIdFromCard = (card) => {
// Find the icon's anchor element and extract the unique identifier from its URL.
let anchor = $(card).find('a[rel]')
,link = $(anchor).attr('rel') || ''
,id = (link.split('id=')[1] || '').trim();
return id;
}
/*
* Extract a query string variable from the given [searchString].
* @function _getUrlVar
* @private
* @param key {string} Variable name to return value for.
* @param (searchString) {string} Optional. Source query string for search.
*/
,_getUrlVar = (key, searchString) => {
// Determine whether we're trying to query the parameter or the current URL and grab the variables.
let query = (typeof searchString !== 'undefined' ? searchString.split('?')[1] : window.location.search.substring(1))
,vars = query.split('&');
// Iterate the variables array until we find what we're looking for, then return the found value.
for (var i = 0; i < vars.length; i++) {
let pair = vars[i].split("=");
if (pair[0] == key) return pair[1];
}
}
/*
* Invoke the site's "assay dragons" functionality and create representation in the current DOM.
* @function _assayDragons
* @private
* @param firstDragonId {int} A dragon's unique identifier.
* @param secondDragonId {int} A dragon's unique identifier.
*/
,_assayDragons = (firstDragonId, secondDragonId) => {
// Invoke the site's native [showNewbies] function if it exists.
if (typeof showNewbies === 'function') showNewbies(); else return;
// Construct a payload and send a request to the site's scrying handler.
let payload = {
id1: firstDragonId
,id2: secondDragonId
};
_request(payload, 'includes/ol/scryer_bloodlines.php').done((result) => {
// Upon request completion determine if the given dragons are capable of
// "breeding", construct a box in the DOM to display the determination, and
// cache this element's intended parent.
let canMate = (result.toLowerCase().indexOf('success') > -1)
,canBreedBoxCss = {
padding: '20px'
,margin: '20px'
,textAlign: 'center'
,fontSize: '15px'
,background: (canMate ? 'lightgreen' : 'lightpink')
}
,nestBoxParent = $('.nestbox').parent();
// Apply style the box and prepend it to the intended parent.
$('<div />').attr('id', 'can-breed').css(canBreedBoxCss).prependTo(nestBoxParent);
// Place situational text in the display box.
$('#can-breed').html('These dragons <b>are' + (canMate ? '</b>' : ' not</b>') + ' eligible to breed as assayed.');
// Place "Breed" button.
if (canMate) {
let breedLink = $('<a href="" class="redbutton anybutton" target="_blank"></a>').text('Breed');
$(breedLink).attr('href', 'http://flightrising.com/main.php?p=lair&tab=nest&dids=' + firstDragonId + ',' + secondDragonId);
$('[onclick="showNewbies()"]').parent().css('width', '210px').append(breedLink);
}
});
}
/*
* Mark all visible checkboxes as the parameter value.
* @function _markAllCheckboxes
* @private
* @param checkValue {bool} Value to mark all visible checkboxes.
*/
,_markAllCheckboxes = (checkValue) => {
// Mark all checkboxes as the boolean value of the parameter.
$('input[type="checkbox"]:visible').prop('checked', checkValue);
}
/*
* Recurrently perform the site's "exalt" functionality on an array of dragons.
* @function _multiExalt
* @private
* @param index {int} Index of current iteration over the given [dragonIds] array.
* @param dragonIds {array} Array of dragons' unique identifiers to "exalt."
* @param callback {function} Callback function to invoke after the last array element's invocation.
*/
,_multiExalt = (index, dragonIds, callback) => {
// Determine the current iteration's dragon, whether this is the last iteration, and construct a payload.
let currentDragonId = dragonIds[index]
,isLast = (currentDragonId === dragonIds[dragonIds.length - 1])
,payload = {
dragon: currentDragonId
};
// Send a request to the site's dragon "exile" handler.
_request(payload, 'includes/ol/exiledragon.php').done(() => {
// Upon request completion invoke this function if the [currentDragonId] isn't the last element of [dragonIds].
// Othwerise invoke the given [callback] function.
if (!isLast) _multiExalt(++index, dragonIds, callback); else callback();
});
}
/*
* Return stored "offspring" records from [localStorage].
* @function _loadOffspring
* @private
*/
,_loadOffspring = () => {
// Ensure the data exists in [localStorage] and return JSON parsed data.
if (typeof localStorage.fhr_offspring === 'undefined') localStorage.fhr_offspring = '[]';
return JSON.parse(localStorage.fhr_offspring);
}
/*
* Update stored "offspring" in [localStorage] with the given [offpsring] array.
* @function _updateOffspring
* @private
* @param offspring {array} Updated array of "offspring" records for the current [localStorage] instance.
*/
,_updateOffspring = (offspring) => {
// Simply save the given stringified [offspring] onto [localStorage].
localStorage.fhr_offspring = JSON.stringify(offspring);
};
/** UTILITY CONSTANTS **/
const
// Minified CSS for various functionalities.
CSS = '#bonding{min-height:280px!important;}/* safari and chrome */ @-webkit-keyframes wiggle { 0% {-webkit-transform:rotate(4deg);} 50% {-webkit-transform:rotate(-4deg);} 100% {-webkit-transform:rotate(4deg);} } /* firefox */ @-moz-keyframes wiggle { 0% {-moz-transform:rotate(4deg);} 50% {-moz-transform:rotate(-4deg);} 100% {-moz-transform:rotate(4deg);} } /* anyone brave enough to implement the ideal method */ @keyframes wiggle { 0% {transform:rotate(4deg);} 50% {transform:rotate(-4deg);} 100% {transform:rotate(4deg);} }'
// Icon data or location URLs for various functionalities.
,ICONS = {
NEST: 'http://puu.sh/wJ9Rr/b889eca68f.png'
,HOARD: 'http://flightrising.com/images/layout/vault/vault_active.png'
,WRENCH: 'data:image/png;base64,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'
,COATHANGER: 'data:image/png;base64,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ld1d1wEAcEZMrAEAHmnu3Lnmf/7nf7J07vTp09WnTx+PK9U3GWNMnz599N577zl8bv78+bV582ZVr17dY79/AAD3Q7EGAHicS5cumZo1a+rYsWMOn9u/f3/FxcV5fCm8ceOGadeunX788UeHz+3YsaMWLlzo8d9DAID7YCk4AMDjTJkyJUulul69eho/frzd8Z2Cr6+vNXfuXBUrVszhc5OTk7Vw4UJe2QcAuA0m1gAAj3LlyhVTsWJF/fLLLw6dFxQUpPXr17OE+S++/vprExISIkfvJ9q3b68ffviB7yUAwC0wsQYAeJTExESHS7UkxcbGUqpvoXPnztYLL7zg8HlLly7VihUreHUfAOAWmFgDADzG9evXTZUqVRxeBt6sWTOtXr1aXl5eFOtbOHfunKlRo4bDL1g89NBD+vbbb/meAgBcHhNrAIDHmDVrlsOl2sfHR9OnT6dU/42iRYtaWfkYre+++04bN27kFX4AgMujWAMAPMaMGTMcPqd///6qX78+pfoOnnvuObVs2dLh87LybwIAgLNhKTgAwCPs3LnT1KpVy6Fz/Pz8tH//fpUqVYpinQkLFy40DzzwgEPnFC1aVMePH1f+/Pn5HgMAXBYTawCAR/joo48cPqdPnz6Uagd06tTJatWqlUPnnDt3Tl9//bXd0QEAyBaKNQDA7WVkZJiPP/7YoXN8fX318ssv2x3d5URGRjp8zuzZs+2ODQBAtlCsAQBu74cfftCRI0ccOuepp55ShQoVmFY7KCQkRI4uuf/mm2907tw53psGAHBZFGsAgNv79ttvHT7nueeeszu2S7Isy+rVq5dD56SmpmrRokV2RwcAIMso1gAAt7d48WKHjq9QoYLatWtnd2yX1bNnT3l7ezt0zpIlS+yODQBAllGsAQBu7cKFC2bz5s0OndOzZ08+tzobSpcubd17770OnePoix8AADgTijUAwK398MMPSk9Pd+icbt262R3b5T355JMOHb97924dPXqU91kDAFwSxRoA4NYcnYSWKFFCderUsTu2y+vYsaPD57AcHADgqijWAAC3tn79eoeOv++++2RZFsvAs6lChQpW5cqVHTrH0X8rAACcBcUaAODW9uzZ49Dxjr43GLd33333OXT87t277Y4MAECWUKwBAG7rzJkz5uzZsw6d07ZtW7tjuw1Hv5cUawCAq6JYAwDclqNF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aO/evXZHAdxGxYoVtWXLFhUoUIByDQAehqXgAOCBhgwZQqkGctjBgwc1dOhQu2MAAGzAxBoAPMx3331nHnnkEZaAA7nAsix99dVXCg4OZmoNAB6EYg0AHuTIkSOmUaNGOnPmjN1RALdVuHBhrV+/XlWqVKFcA4CHoFgDgIe4fv26adeundauXWt3FNyBj4+PqlSpoqCgoD/9+dmzZ3Xw4EG74yETGjZsqJUrV8rf359yDQAegGINAB4iLCzMJCYm2h0Dt1GkSBGFhIToiSeeUKdOnW5byM6ePWuSkpL02WefaeHChbp27Zrd0XEbvXr10ocffijLsijXAODmKNYA4AGio6PNiBEj7I6Bv/D29tajjz6qvn376v7775evr69DBezSpUvmyy+/VHx8vFatWmX3l4NbGDVqlF5//XWKNQC4OYo1ALi5Tz75xDz99NNsVuZEChcurF69eunFF19UxYoVc6R0bdq0ySQkJGjOnDm6cuWK3V8i/iAuLk79+/enXAOAG6NYA4AbS05ONp07d1ZqaqrdUSCpZs2aGjp0qJ566in5+fnlStE6e/asmT59umJjY3X69Gm7v2To/94z//nnn7NTOAC4MYo1ALipFStWmIcffliXL1+2O4rHq1u3roYMGaLu3bvL29s7T8rV9evXzaxZs/TGG2/o6NGjdn8LPF6+fPk0f/58hYSEUK4BwA1RrAHADa1cudI8/PDDunTpkt1RPFqDBg30yiuvqEuXLrZtYJWammo++eQTjR07Vj///LPd3xKPRrkGAPdFsQYAN7N8+XLzyCOPMKm2UfPmzfX666/rgQcecJoClZaWZubMmaMxY8bwkV028vPz0xdffKEHH3zQaX42AADZR7EGADeyePFi89hjj1GqbVKvXj298cYbevTRR522NKWmppqZM2dq7NixOnHihN1xPJKfn58++eQTPfbYY077cwIAcIyX3QEAADnj888/N507d6ZU26BixYpKTEzUxo0bnbpUS1K+fPmsfv36WQcOHFBiYqLuvvtuuyN5nGvXrumJJ55QQkIC0w0AcBNMrAHADUyZMsW8+OKLysjIsDuKRylfvryioqLUq1cv+fj4OHWhvp2LFy+aSZMm6Z133uE9+TYYM2aMXnvtNZf82QEA/H8UawBwYcYYM2bMGI0ZM8buKB4lKChIL7/8siIjI+Xv7+8Wpejs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rAFwSEpKinnjjTc0YcIEpaen2x3H7RUvXlwjR47UgAED5O3tzXM2gN9RrAH8bseOHWbo0KH65ptv7I7iEe69917Fx8erevXq3JwByJaffvrJhIaGau3atXZH8Qg1a9bUuHHjFBwczPM3AElsXgZA//d+vdDQUFOvXj1KdR4oWbKkZs2apcWLF1uUagA5oUGDBtbq1auVmJioggUL2h3H7e3cuVMhISHq1KmT2bJlC1MqAEysAU+WkpJi4uLi9Oabb+rSpUt2x3F7NzcnmzRpkooVK0ahBpArTpw4YSIjIzV79my7o3gELy8vde/eXTExMSpVqhTP7YCHolgDHigjI8PMmTNHw4cP14kTJ+yO4xHq1aunhIQEtWzZkpsuAHliwYIFZsCAATp06JDdUTxCYGCgBgwYoFdffVUFChTguR7wMBRrwMMkJyebIUOGaPPmzXZH8QgBAQEaOnSoXnnlFeXLl48bLQB56sqVK2bcuHF6++23lZqaanccj1CmTBm99tpr6t27NxucAR6EYg14iJ07d5phw4ZpwYIFdkfxGMHBwYqLi+OzTwHYbsuWLSYsLEyrV6+2O4rHqF27tsaPH6+HH36YawDgAdi8DHBzZ86cMYMGDTJ169alVOeRUqVKadasWUpKSrIo1QCcQb169ayVK1dq1qxZKlasmN1xPML27dv1yCOPqFOnTmbr1q1MsgA3x8QacFNXrlwx7777rt566y1dvHjR7jgewcvLSy+88ILGjx+vggULUqgBOKWTJ0+aYcOGsblZHvLx8dHzzz+v119/XXfffTfXB8ANUawBN2OMMfPnz9fQoUPZsCYPNWjQQImJiWrWrBk3TABcwpIlS0x4eLh2795tdxSPERQUpJdfflmRkZHy9/fnegG4EYo14EYWL15shgwZok2bNtkdxWMEBgZq1KhRGjJkCJvUAHA5V69eNTExMYqOjtb169ftjuMxypYtq1GjRumFF16Ql5cX1w7ADVCsATewe/duM2rUKM2bN8/uKB4lODhYU6dOVfny5bkpAuDS9uzZY/r166dFixbZHcWjNGnSRBMmTFD79u25jgAujs3LABd29uxZM2jQIFOnTh1KdR4qU6aM5s+fr6SkJItSDcAdVKtWzVq4cKFmzZql4sWL2x3HY6xfv14dOnRQp06dzPbt25l2AS6MiTXggq5evWpiY2MVHR3N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lE6fPm13HGRSlSpVNHXqVD344IM8cQIAgFyxYMECM3DgQB08eNDuKMikfPnyKSwsTGPGjFHhwoW5T3RBFGsXc3On7xEjRmjfvn12x0Em+fr66qWXXtLo0aPZDRIAAOS6K1eumHHjxuntt99Wamqq3XGQSUWLFtWwYcPYQdwFUaxdyOrVq83QoUO1cuVKu6PAAW3btlVCQoJq1arFkyMAAMhTW7ZsMWFhYVq9erXdUeCA8uXL69VXX9ULL7wgLy8v7iFdAJuXuYBdu3aZbt26mVatWlGqXUiRIkUUGxurH374gVINAABsUa9ePWvlypWaNWuWihUrZnccZNLhw4cVGhqq5s2ba/HixUxCXQATayd27Ngx8/rrr+v9999XWlqa3XHggK5du2rq1Km66667KNQAAMApnDx50gwbNozNzVxQx44dNWHCBNWvX597SydFsXZCly9fNlOnTtWbb76pS5cu2R0HDrjnnnsUHx+vjh078qQHAACc0pIlS0x4eLh2795tdxQ44OYO4uPGjVPFihW513QyFGsncnOn79dee02nTp2yOw4ccHNzsjFjxih//vw80QEAAKd29epVExMTo+joaF2/ft3uOHBAQECABg4cqBEjRqhQoULcdzoJirWTSEpKMi+//LJ+/vlnu6PAQe3bt1dCQoJq1KjBExsAAHApP//8swkPD9eiRYvsjgIHFStWTEOHDtXgwYMZ7DgBirXNli9fboYOHao1a9bYHQUOKlGihN555x316NGDJzIAAOCyjDHm/fff17Bhw3Tu3Dm748BB99xzj9566y116dJFlmVxX2oTirVN9uzZY0aOHKl58+bZHQUOsixLPXr00MSJE1W8eHGevAAAgFs4d+6cGTFihGbMmCE6gutp2rSpJkyYoHbt2nF/agOKdR47e/asGT9+vCZNmqTU1FS748BB1apVU3x8vO677z6esAAAgFtatmyZCQsL086dO+2Ogizo2LGjYmNjVbt2be5X8xCfY51HUlNTzeTJk02VKlUUExNDqXYx/v7+ioqK0tatWynVAADArbVr187avHmzoqOj5efnZ3ccOCg5OVkNGzZUaGioOX36NFPUPMLEOpcZY8z8+fMVGRmpAwcO2B0HWXDvvfcqPj5e1atXp1ADAACPsm/fPtOvXz/95z//sTsKsiAoKEgvv/yyhg8fLj8/P+5lcxHF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'
,SELECT_ALL: 'http://flightrising.com/images/layout/vault/select_all.png'
,SELECT_NONE: 'http://flightrising.com/images/layout/vault/select_none.png'
}
// Query variables.
,QUERY = {
DID: _getUrlVar('did')
,DIDS: _getUrlVar('dids')
,DRAGON: _getUrlVar('dragon')
,ID: _getUrlVar('id')
,PAGE: _getUrlVar('p')
,TAB: _getUrlVar('tab')
,VIEW: _getUrlVar('view')
};
/** SETUP/FUNCTIONALITY FUNCTIONS **/
let
/*
* Initialize functionality for the currency management system.
* @function _setupCurrencyManagement
* @private
*/
_setupCurrencyManagement = () => {
// Apply CSS to the page.
$('<style type="text/css" />').text(CSS).appendTo('head');
// Grab the "gem" and "treasure" currency containers, counts, and create deposit buttons for each.
let gemContainer = $('#usertab').children().last()
,treasureContainer = $(gemContainer).prev()
,gemCount = parseInt($('#user_gems').text()) || 0
,treasureCount = parseInt($('#user_treasure').text()) || 0
,gemDepositBtn = $('<img />')
.attr('id', 'gem-deposit')
.attr('src', ICONS.HOARD)
.attr('width', '15px')
.attr('height', '15px')
.click((event) => { // On "gem" deposit button click.
// Construct a payload and send a request to the vault transaction handler.
let payload = {
trans: 'deposit'
,curr: 1
,amount: gemCount
}
,button = event.target;
_request(payload, 'includes/ol/vault_withdep.php').done(() => {
// Upon request completion show a temporary message to the user for validation.
$('#user_gems').text('Deposited!');
setTimeout(() => {
$('#user_gems').text('0');
$(button).remove();
}, 2000);
});
}
)
,treasureDepositBtn = $('<img />')
.attr('id', 'treasure-deposit')
.attr('src', ICONS.HOARD)
.attr('width', '15px')
.attr('height', '15px')
.click((event) => { // On "treasure" deposit button click.
// Construct a payload and send a request to the vault transaction handler.
let payload = {
trans: 'deposit'
,curr: 0
,amount: treasureCount
}
,button = event.target;
_request(payload, 'includes/ol/vault_withdep.php').done(() => {
// Upon request completion show a temporary message to the user for validation.
$('#user_treasure').text('Deposited!');
setTimeout(() => {
$('#user_treasure').text('0');
$(button).remove();
}, 2000);
});
}
);
// If the user has "treasure" or "gem" currency available, add these buttons to the DOM.
if (treasureCount) $(treasureDepositBtn).appendTo(treasureContainer);
if (gemCount) $(gemDepositBtn).appendTo(gemContainer);
}
/*
* Initialize functionality for familiar icon replacement with full art.
* @function _setupFamiliarIconReplacement
* @private
*/
,_setupFamiliarIconReplacement = () => {
$('img[src^="/images/cms/familiar"]').each((i, familiar) => {
if (!familiar.src.includes('art')) {
familiar.src = familiar.src.replace('familiar', 'familiar/art');
}
});
}
/*
* Initialize functionality for bestiary familiar art coloration.
* @function _setupBestiaryColoration
* @private
*/
,_setupBestiaryColoration = () => {
$('img[src^="/images/cms/familiar"]').each((i, familiar) => {
if (familiar.src.includes('gray')) {
$(familiar).addClass('frh-locked');
}
});
$('.frh-locked').hover(function () {
let familiar = $(this);
if ($(familiar).attr('src').includes('gray')) {
$(familiar).attr('src', $(familiar).attr('src').replace('_gray', ''));
}
}, function () {
let familiar = $(this);
if (!$(familiar).attr('src').includes('gray')) {
$(familiar).attr('src', $(familiar).attr('src').replace('.png', '_gray.png'));
}
});
}
/*
* Initialize functionality for the "progeny" functionality shortcuts.
* @function _setupProgenyShortcuts
* @private
*/
,_setupProgenyShortcuts = () => {
// New up an array to track selected dragon unique identifiers.
let selectedDragonIds = [];
$('.dragoncard .miniclue').click((event) => { // On dragon card's "gender" icon click.
// Prevent bubble.
event.preventDefault(), event.stopPropagation();
// Cache the clicked element and extract this dragon's unique identifier.
let button = event.target
,id = _extractDragonIdFromCard($(button).closest('.dragoncard'));
// Add this dragon's unique identifier to the list of selected dragons.
selectedDragonIds.push(id);
// Change the border appearance to show that this is a selected entry.
$(button).closest('.dragoncard').css('border', '3px dashed #9f9a8f');
// If this is the second dragon selected, open a new window to the "progeny" page, then reset all the cards' border appearances.
if(selectedDragonIds.length > 1) {
let dIds = selectedDragonIds.join(',');
window.open('http://flightrising.com/main.php?p=scrying&view=progeny&dids=' + dIds, '_blank');
selectedDragonIds = [];
$('.dragoncard').each((i, card) => {
$(card).css('border', '1px solid #9f9a8f');
});
}
});
}
/*
* Initialize functionality for the "morphology" shortcuts.
* @function _setupMorphologyShortcuts
* @private
*/
,_setupMorphologyShortcuts = () => {
// Begin "dragon" tab functionality suite.
if (QUERY.TAB === 'dragon') {
// Cache the "morph" button container, create a button for the user, and append it to the container.
let btnContainer = $('.main');
$('<a />')
.addClass('morph-btn beigebutton thingbutton')
.text('Morph')
.css({
position: 'absolute'
,top: '46px'
,right: '360px'
,zIndex: '2'
})
.attr('href', 'http://flightrising.com/main.php?p=scrying&view=morphintime&did=' + QUERY.DID)
.attr('target', '_blank')
.prependTo(btnContainer);
}
// Iterate all the dragon cards on the page.
$('.dragoncard').each((i, card) => {
// Extract this dragon's unique identifier, "morph" URL, and container. Create a wrench tool image.
let id = _extractDragonIdFromCard(card)
,img = $('<img />')
.attr('src', ICONS.WRENCH)
.height('25')
.width('25')
.css('float', 'left')
,anchor = $('<a />')
.attr('href', 'http://flightrising.com/main.php?p=scrying&view=morphintime&did=' + id)
.attr('target', '_blank')
,container = $(card).children().last().children().last();
// Add the wrench tool image to the container.
$(img).appendTo($(anchor).prependTo(container));
// Add CSS animation effects to this card on hover.
$(card).hover(
() => {
$(card).find('.dragonthmb').css({
'-webkit-animation': 'wiggle 0.5s infinite'
,'-moz-animation': 'wiggle 0.5s infinite'
,'animation': 'wiggle 0.5s infinite'
});
}
,() => {
$(card).find('.dragonthmb').css({
'-webkit-animation': 'none'
,'-moz-animation': 'none'
,'animation': 'none'
});
}
);
});
}
/*
* Initialize functionality for the "bonding" shortcuts.
* @function _setupBondingShortcuts
* @private
*/
,_setupBondingShortcuts = () => {
// Create an invisible DOM element for storing a "bonding" action frame element.
let bondBin = $('<div />')
.attr('id', 'bond-bin')
.css('display', 'none')
.appendTo('body');
// Change the cursor style on the "famicon" button image.
$('img[src$="famicon.png"]')
.css('cursor', 'pointer')
.click((event) => { // On "famicon" button click.
// Cache this button and extract this dragon's URL.
let button = event.target
,url = $(button).closest('.dragoncard').find('a[rel]').attr('href');
// Load the dragon's URL into the bond bin and activate the "bond" functionality.
// Yes this ugly page scraping is the result of this site having no sense of APIs. :P
$(bondBin).load(url, () => {
$(bondBin).find('img[src$="button_bond.png"]').click();
$(bondBin).empty();
});
});
}
/*
* Initialize functionality for the "dressing room" shortcuts.
* @function _setupDressingRoomShortcuts
* @private
*/
,_setupDressingRoomShortcuts = () => {
// Define a scoped function for submitting a dragon's unique identifier to the "dressing room" functionality page.
let dressingRoomFormSubmit = (dragonId) => {
let input = $('<input id="dragon" name="dragon" type="text" />')
,form = $('<form action="http://www1.flightrising.com/dressing/outfit" method="POST" target="_blank"></form>');
$(form).hide().appendTo('body').append($(input).val(dragonId)).submit().remove();
};
// Begin "dragon" tab functionality suite.
if (QUERY.TAB === 'dragon') {
// Cache button container, create and append an action button to this container.
let btnContainer = $('.main');
$('<a />')
.addClass('dressing-room-btn beigebutton thingbutton')
.text('Dress')
.css({
position: 'absolute'
,top: '46px'
,right: '270px'
,zIndex: '2'
}).prependTo(btnContainer)
.click(() => { dressingRoomFormSubmit(QUERY.DID); }); // On "dress" button click: invoke [dressingRoomformSubmit] with the current page's dragon's unique identifier.
} else if (QUERY.ID && !QUERY.TAB) { // All other tab/id combo suite.
// Iterate each dragon card on the page.
$('.dragoncard').each((i, card) => {
// Create a "dress" button using this dragon's unique identifier.
let id = _extractDragonIdFromCard(card)
,img = $('<img />')
.attr('src', ICONS.COATHANGER)
.css({
height: '15px'
,width: '25px'
,float: 'left'
,marginTop: '5px'
,marginLeft: '-8px'
,cursor: 'pointer'
})
.click(() => { dressingRoomFormSubmit(id); })
,container = $(card).children().last().children().last();
// Append it to this iteration's container.
$(img).appendTo(container);
});
}
}
/*
* Initialize functionality for the "progeny" functionality page.
* @function _setupInitializedProgeny
* @private
*/
,_setupInitializedProgeny = () => {
// Only act if the query has unique identifiers.
if (QUERY.DIDS) {
// Grab the two query string identifier values.
let firstId = QUERY.DIDS.split(',')[0]
,secondId = QUERY.DIDS.split(',')[1];
// Place them into the "progeny" form.
$('#id10t1').val(firstId), $('#id10t2').val(secondId);
// Invoke our [_assayDragons] function with these values.
_assayDragons(firstId, secondId);
}
}
/*
* Initialize functionality for the "morphology" functionality page.
* @function _setupInitializedMorphology
* @private
*/
,_setupInitializedMorphology = () => {
// Set the form's input value to the current query's unique identifier and invoke the site's [AEGBAGA] (???) function to submit.
let id = QUERY.DID;
$('#greenranger').val(id), AEGBAGA();
setTimeout(() => {
// Wait a bit and flip the age of the dragon to adult, then refres the current view by invoking the site's [lolRedRanger] (again, ???) function.
$('#setage').val(1), lolRedRanger();
}, 1000);
}
/*
* Initialize functionality for the "
*/
,_setupInitializedNest = () => {
if ((QUERY.TAB === 'nest') && QUERY.DIDS) {
let firstId = QUERY.DIDS.split(',')[0]
,secondId = QUERY.DIDS.split(',')[1];
if ($('#dad').find('option[value="' + firstId + '"]').length) {
console.log('first id is dad');
$('#dad').val(firstId).change();
} else if ($('#mom').find('option[value="' + firstId + '"]').length) {
console.log('first id is mom');
$('#mom').val(firstId).change();
}
if ($('#mom').find('option[value="' + secondId + '"]').length) {
console.log('second id is mom');
$('#mom').val(secondId).change();
} else if ($('#dad').find('option[value="' + secondId + '"]').length) {
console.log('second id is dad');
$('#dad').val(secondId).change();
}
if (typeof showBabies === 'function') setTimeout(showBabies, 1000);
}
}
/*
* Initialize "hoard" functionality page.
* @function _setupHoard
* @private
*/
,_setupHoard = () => {
// Remove functionality we're replacing.
$('#food').parent().remove();
// Redefine the site's [uncheckAll] and [checkAll] functions with our versions.
uncheckAll = () => { _markAllCheckboxes(false); }
,checkAll = () => { _markAllCheckboxes(true); };
// Create check and uncheck buttons for pages that don't have them.
let container = $('#invent').children().last()
,checkLeft = (QUERY.PAGE === 'hoard' ? '0' : '415px')
,uncheckLeft = (QUERY.PAGE === 'hoard' ? '53px' : '470px');
// Only act if the check and uncheck buttons we need don't exist.
if (!$('img[onclick="checkAll(invent)"]:visible').length) {
// Create an uncheck all button, add a click event handler, and append it to the DOM.
$('<img />')
.attr('src', ICONS.SELECT_NONE)
.prependTo(container)
.click(() => { _markAllCheckboxes(false); })
.css({
position: 'absolute'
,left: uncheckLeft
,top: '0'
})
// Create a check all button, add a click event handler, and append it to the DOM.
,$('<img />')
.attr('src', ICONS.SELECT_ALL)
.prependTo(container)
.click(() => { _markAllCheckboxes(true); })
.css({
position: 'absolute'
,left: checkLeft
,top: '0'
});
}
// Begin "vault" page functionality suite.
if (QUERY.PAGE === 'vault') {
// Grab "treausure" and "gem" currency counts.
let treasureCount = $('#nodiving').text().trim()
,gemCount = $('#bling').text().trim();
// Create "treasure" withdraw button.
$('img[src="../images/layout/icon_treasure.png"]')
.css('cursor', 'pointer')
.unbind()
.click(() => { // On "treasure" withdraw button click.
// Construct a payload and send a request to the vault transaction handler.
let payload = {
trans: 'withdraw'
,curr: 0
,amount: treasureCount
};
_request(payload, 'includes/ol/vault_withdep.php').done(() => {
// Upon request completion show a temporary message to the user for validation.
$('#nodiving').text('Withdrawn!');
setTimeout(() => {
$('#nodiving').text('0');
}, 2000);
});
})
// Create "gem" withdraw button.
,$('img[src="../images/layout/icon_gems.png"]')
.css('cursor', 'pointer')
.unbind()
.click(() => { // On "gem" withdraw button click.
// Construct a payload and send a request to the vault transaction handler.
let payload = {
trans: 'withdraw'
,curr: 1
,amount: gemCount
};
_request(payload, 'includes/ol/vault_withdep.php').done(() => {
// Upon request completion show a temporary message to the user for validation.
$('#bling').text('Withdrawn!');
setTimeout(() => {
$('#bling').text('0');
}, 2000);
});
});
}
}
/*
* Initialize the "multiple-exalt" tool and custom functionality.
* @function _setupMultiExaltTool
* @private
*/
,_setupMultiExaltTool = () => {
// Init a selecting flag, an array to hold dragon identifiers.
let isSelecting = false
,exaltees = []
,btnContainer = $('#tunak').prev().children().last()
,marquee = $('<div />') // Create an element to act as a marquee to relay info to the user.
.css('text-align', 'center')
.html('<h2>Select the dragons that you wish to exalt and then click the Exalt button above.</h2>')
.hide()
,marqueePrev = $('form').prev().after(marquee) // Apply it to the DOM.
,handleExalteeSelection = (event) => { // Scoped function to handle dragon selection.
// Prevent bubble.
event.preventDefault(), event.stopPropagation();
// Grab the current card and extract its dragon's unique identifier.
let card = $(event.target).closest('.dragoncard')
,id = _extractDragonIdFromCard(card);
// If selected id is in the [exaltees] array, remove it. Otherwise add it.
if (exaltees.indexOf(id) > -1) {
exaltees.splice(exaltees.indexOf(id), 1);
$(card).css('border', '1px solid #9f9a8f');
} else {
exaltees.push(id);
$(card).css('border', '3px dashed #9f9a8f');
}
};
// Create an action button to toggle selection status/submission for "multiple-exalt" custom functionality.
$('<button />')
.addClass('multi-exalt-btn beigebutton thingbutton')
.text('Multi-Exalt')
.css({
position: 'absolute'
,top: '7px'
,left: '-125px'
}).prependTo(btnContainer)
.click((event) => { // On "Multi-Exalt" button click.
// Cache action button.
let button = event.target;
// If not already selecting, toggle selecting and init click event on all dragon cards.
if (!isSelecting) {
isSelecting = true;
$(button).removeClass('thingbutton beigebutton').addClass('redbutton anybutton').text('Exalt');
$('.dragoncard').click(handleExalteeSelection);
$(marquee).show();
} else { // If selecting, remove click event handler and reset selection form.
isSelecting = false;
$('.dragoncard').unbind('click', handleExalteeSelection);
$(marquee).hide();
$('.dragoncard').each((i, card) => {
$(card).css('border', '1px solid #9f9a8f');
});
$(button).removeClass('redbutton anybutton').addClass('beigebutton thingbutton').text('Multi-Exalt');
// If submitting and there are dragons to "exalt".
if (exaltees.length) {
// Confirm the user wants to "exalt" all the selected dragons.
$(button).text('Exalting...');
let isSingle = (exaltees.length === 1)
,confirmation = confirm('Are you sure you wish to exalt ' + (isSingle ? 'this' : 'these') + ' ' + exaltees.length + ' dragon' + (isSingle ? '': 's') + '?');
if (confirmation) {
// If user confirms, invoke our [_multiExalt] function starting at the 0th index of [exaltees] with callback of reloading the page.
_multiExalt(0, exaltees, () => {
window.location.reload();
});
} else {
// If the user cancels, reset the [exaltees] array, and reset the GUI.
exaltees = [];
$(button).removeClass('redbutton anybutton').addClass('beigebutton thingbutton').text('Multi-Exalt');
}
}
}
});
}
/*
* Initialize the "saved offspring" tool and custom functionality.
* @function _setupSavedOffspringTool
* @private
*/
,_setupSavedOffspringTool = () => {
// Gather saved offspring from [localStorage] and create a box to show the offspring in.
let savedOffspring = _loadOffspring()
,savedBox = $('<div class="saved-box" />')
.css({
background: '#dedacf',
borderRadius: '5px',
border: '1px solid #000',
textAlign: 'center',
width: '100%',
marginTop: '20px'
}).html('<h2>Saved Offspring</h2>')
// Scoped function to draw "saved offspring" functionality display box in the DOM.
,drawSavedOffspring = (saveBox) => {
// Ensure any previous instance is removed--gracefully.
$('.saved-box').empty().html('<h2>Saved Offspring</h2>').remove();
// Iterate each saved "offspring."
$(savedOffspring).each((i, offspring) => {
// Find the offspring URL that matches current URL.
if (offspring.url === window.location.search) {
// Append the drawn box to the DOM.
$('input[value="Preview"]').parent().after(saveBox);
// Only act if there are offspring.
if (offspring.offspring.length) {
// Iterate each offspring.
$(offspring.offspring).each((i, image) => {
// Create an image of the saved offspring.
let img = $('<img src="' + image + '" />')
.click(() => { // On offspring icon click.
// Confirm the user wants to remove saved offspring.
let confirmation = confirm('Are you sure you wish to remove this saved offspring?');
// If confirmed, remove this offspring and update the save. Then redraw the box.
if (confirmation) {
offspring.offspring.splice(offspring.offspring.indexOf(image), 1);
_updateOffspring(savedOffspring);
drawSavedOffspring(saveBox);
}
});
// Append the image to the saved box.
$(savedBox).append(img);
});
} else { // No offspring detected.
$(saveBox).append('<b>No offspring saved for this pair.</b><br/><br/>');
}
return;
}
});
}
/*
* Save clicked dragon as offspring for pair on the current page.
* @function offspringSavingHandler
* @private
* @param event {object} Click event object.
*/
,offspringSavingHandler = (event) => {
// Prevent bubble.
event.preventDefault(), event.stopPropagation();
// Cache clicked element and confirmation from user.
let image = event.target
,confirmation = confirm('Do you wish to save this offspring possibility for future reference?');
// Only act if the user confirmed.
if (confirmation) {
// Declare flag.
let thisPageExists = false;
// Iterate each saved "offspring."
$(savedOffspring).each((i, offspring) => {
// If this offspring matches the current page, flip the flag.
if (offspring.url === window.location.search) {
thisPageExists = true;
return;
}
});
// If this page doesn't exist in the offspring, save it to the offspring array.
if (!thisPageExists) {
let offspring = {
url: window.location.search,
offspring: [$(image).attr('src')]
};
savedOffspring.push(offspring);
_updateOffspring(savedOffspring);
} else {
// Otherwise update the existing entry for this offspring.
$(savedOffspring).each((i, offspring) => {
if (offspring.url === window.location.search) {
if (typeof offspring.offspring === 'undefined') offspring.offspring = [];
if (offspring.offspring.indexOf($(image).attr('src')) === -1) {
offspring.offspring.push($(image).attr('src'));
_updateOffspring(savedOffspring);
}
return;
}
});
}
// Redraw the "saved offspring" display box.
drawSavedOffspring(savedBox);
}
}
// If there are "saved offspring" entries, draw the "saved offspring" display box.
if (savedOffspring.length) drawSavedOffspring(savedBox);
// Scoped function to initialize the click event handler on the preview button on this page.
let initializer = () => {
$('#preview img')
.unbind('click')
.click(offspringSavingHandler);
};
// Register [initializer] to doc ready and AJAX.oncomplete.
$(document).ready(initializer).ajaxComplete(initializer);
}
/*
* Initialize the "setup lineage" tool and custom functionality.
*/
,_setupLineagePreviewTool = () => {
// If there is no "lineage preview" display box, draw one in the DOM.
if (!$('#lineage-preview').length) {
$('<div id="lineage-preview" style="position: fixed; display: none; border: 1px solid #000; background: #dad6c8; border-radius: 1em; padding:20px;"></div>').appendTo('body');
}
// Scoped function to handle "ancestor" name mouse hover.
let hoverHandler = (event) => {
// Cache clicked name.
let link = event.target;
// If the "lineage preview" display box is visible, hide it.
if ($('#lineage-preview').is(':visible')) {
$('#lineage-preview').hide();
} else {
// Otherwise grab the link's source and grab the dragon's unique identifier from this source.
let href = $(link).attr('href') || $(link).attr('src')
,dId = _getUrlVar('did', href) || _getUrlVar('dragon', href);
// Load dragon image from their page into the "lineage preview" display box.
$('#lineage-preview')
.load('http://flightrising.com/main.php?dragon=' + dId + ' #dragbuttons', () => {
if (!$('#lineage-preview').children().length) {
$('#lineage-preview')
.load('http://flightrising.com/main.php?dragon=' + dId + ' span[style="width:350px; height:350px; margin-bottom:20px; margin-top:28px; margin-left:15px; display:inline-block;"]', () => {
let left = (event.clientX - 420) + 'px'
,top = (event.clientY - 420) + 'px'
,div = document.getElementById('lineage-preview');
div.style.left = left;
div.style.top = top;
$('#lineage-preview').show();
});
} else {
let left = (event.clientX - 420) + 'px'
,top = (event.clientY - 420) + 'px'
,div = document.getElementById('lineage-preview');
div.style.left = left;
div.style.top = top;
$('#lineage-preview').show();
}
});
}
};
// Apply the [hoverHandler] function as hover event handlers to "ancestor" names on the page.
$('a[style="color:#000; font-weight:bold; text-decoration:underline;"]').on('mouseenter mouseleave', hoverHandler);
$('.itemicon.ah-listing-icon img').on('mouseenter mouseleave', hoverHandler);
$('#lineage-preview').hover((event) => { $(event.target).hide(); });
}
/*
* Replaces breeding cooldown icons with their numerical values.
* @function _replaceBreedingCooldownIcons
* @private
*/
,_replaceBreedingCooldownIcons = () => {
let eggElements = $('a[title^="This dragon will not be available to breed"]');
$(eggElements).each((i, element) => {
let cooldown = $(element).attr('title').replace(/\D/g, '');
$(element).find('img').replaceWith('<span style="font-size: 18px; color: #731d08; font-weight: bold;">' + cooldown + '</span>');
});
};
/** INITIALIZATION **/
/*
* Initialize script functionality!
* @function _init
* @private
*/
let _init = () => {
// Initialize currency management on all pages.
_setupCurrencyManagement();
// Switch on current page.
switch (QUERY.PAGE) {
// Initialize hoard custom functionalities and set AJAX.oncomplete handler.
case 'hoard': case 'vault': _setupHoard(), $(document).ajaxComplete(_setupHoard), $(document).ajaxComplete(_setupFamiliarIconReplacement); break;
// Initialize "multiple-exalt" and "bonding" shortcut tools.
case 'lair': _setupMultiExaltTool(), _setupBondingShortcuts(), _setupInitializedNest(), _replaceBreedingCooldownIcons();
// Initialize "progeny" and "morphology" shortcut tools.
case 'view': _setupProgenyShortcuts(), _setupMorphologyShortcuts();
// Begin "dragon" tab, "" dragon, and AH Dragons functionality suite.
// Initialize the "lineage preview" tool and the "dressing room" shortcuts tool.
if (QUERY.TAB === 'dragon' || QUERY.DRAGON !== '' || window.location.pathname === '/auction-house/buy/realm/dragons') _setupLineagePreviewTool(); _setupDressingRoomShortcuts(); break;
// Initialize "initialized progeny, morphology" and "saved offspring" tools.
case 'scrying':
switch (QUERY.VIEW) {
case 'progeny': _setupInitializedProgeny(), _setupSavedOffspringTool(); break;
case 'morphintime': _setupInitializedMorphology(); break;
};
break;
// Initialize "bestiary familiar coloration" tool.
case 'bestiary': _setupBestiaryColoration(); break;
};
};
return {
/*
* Initialize!
* @method init
* @memberof FlightRisingHelper
* @public
*/
init: _init
};
})($);
// Attach FRH.init as doc.ready event handler.
$(document).ready(FlightRisingHelper.init);
// EOF