Skrip ini tidak untuk dipasang secara langsung. Ini adalah pustaka skrip lain untuk disertakan dengan direktif meta // @require https://update.greasyfork.org/scripts/7611/50299/GOTA_Extender_Production.js
var production = (function ($, localStorage, log, error, buildingBySymbol,
buildingProducing, buildingFinished, buildingBySymbol,
doFinishProduction, userContext, doProduction,
applySelectedUpgrade, buildingUpgrades, inform) {
var _this = {
init: init,
attempt: attempt,
persist: persist,
enqueue: enqueue,
render: render,
config: config,
clear: clear,
getElement: getElement,
removeElement: removeElement,
executeElement: executeElement,
speedUp: speedUp,
queue: [],
queueDelay: 4E3,
superiorMaterials: true,
doSpeedUp: false
};
// Retrieves production
// queue from localStorage
function init(o) {
_this.queue = localStorage.get("productionQueue", []);
_this.config(o);
$("#modal_dialogs_top").on('click', '#upgradeQueue', enqueue);
$("#modal_dialogs_top").on('click', 'span.btnwrap.btnmed.equipbtn.queue', enqueue);
$('body').on('click', '.tableRow', deleteTableRow);
// Attempt production on initialize
//attempt();
}
function config(o){
//console.debug(o);
try {
_this.queueDelay = o.queueDelay * 1E3;
_this.superiorMaterials = o.superiorMaterials;
_this.doSpeedUp = o.doSpeedUp;
} catch(e){
error(e);
}
}
function clear(building) {
_this.queue = building != void 0
? _this.queue.filter(function (a) {
return a.activeBuildingPanel != building
}) : [];
persist();
}
// Saves the queue locally
// NOTE: do it after every change of the queue!
function persist() {
localStorage.set("productionQueue", _this.queue);
}
// Attempts building
// production
function attempt(bSymbol) {
if (!_this.queue || _this.queue.length == 0) {
log('Attempted production, but queue was missing or empty. Exiting...', "PRODUCTION");
return;
}
var element;
var building;
if (bSymbol != void 0) {
// Check _this building for production
building = buildingBySymbol(bSymbol);
if (buildingProducing(building)) {
log("Building " + building.symbol + " is busy.", "PRODUCTION");
return;
}
if (buildingFinished(building)) {
log("Building " + building.symbol + " finished production.", "PRODUCTION");
doFinishProduction(building.item_id, function () {
setTimeout(function () {
attempt(building.symbol);
}, _this.queueDelay);
});
return;
}
element = getElement(building.symbol);
element && executeElement(element);
return;
}
for (var i = 0; i < userContext.buildingsData.length; i++) {
building = userContext.buildingsData[i];
if (buildingProducing(building)) {
log("Building " + building.symbol + " is busy.", "PRODUCTION");
continue;
}
if (buildingFinished(building)) {
log("Building " + building.symbol + " finished production.", "PRODUCTION");
doFinishProduction(building.item_id, function () {
setTimeout(function () {
attempt();
}, _this.queueDelay);
});
return;
}
element = getElement(building.symbol);
element && executeElement(element,
function () {
attempt();
});
}
}
function getElement(bSymbol) {
//if (!_this.queue || _this.queue.length == 0) {
// log('Attempted to extract item from queue, but the production queue was missing or empty. Exiting...', "PRODUCTION");
// return null;
//}
var element;
for (var i = 0; i < _this.queue.length; i++) {
if (_this.queue[i].activeBuildingPanel == bSymbol) {
element = _this.queue[i];
break;
}
}
if (!element) {
log('No elements enqueued for building ' + bSymbol + '. Array size: ' + _this.queue.length, "PRODUCTION");
return null;
}
return element;
}
function executeElement(element, callback) {
var index = _this.queue.indexOf(element);
log('Production of element ' + element.name + ' : ' + element.type + ' with index ' + index + ' initiated. ' +
(callback == void 0 ? 'No callback set.' : 'Callback set after production.'), "PRODUCTION");
if (element.type == "item") {
userContext.recipeData = element.recipeData;
userContext.activeBuildingPanel = element.activeBuildingPanel;
doProduction(element.outputSymbol, element.recipeCategory, null, null, element.recipeName, callback);
_this.queue.splice(index, 1);
persist();
log('Production details: ' + element.name + ' at ' + element.activeBuildingPanel + ', ' + element.outputSymbol + ', ' + element.recipeCategory + ', ' + element.recipeName + ';', "PRODUCTION");
} else {
var buildingId = buildingBySymbol(element.activeBuildingPanel).id;
applySelectedUpgrade({building_id: buildingId, id: element.upgradeId, gold: 0, silver: 0}, null, callback);
_this.queue.splice(index, 1);
persist();
log('Production details: ' + element.name + ' : ' + element.type + ' at ' + element.activeBuildingPanel + ', ' + element.symbol + ';', "PRODUCTION");
}
}
function removeElement(index) {
if (_this.queue.length == 1) {
_this.queue.pop();
} else {
_this.queue.splice(index, 1);
persist();
}
}
function enqueue(e) {
e.preventDefault();
try {
var queueingUpgrade = $(this).hasClass('upgradeQueue');
log("Queing " + (queueingUpgrade ? "upgrade." : "item(s)."));
if (queueingUpgrade) {
var container = $(this).parents('div#selected_upgrade');
var name = $(container).find('h5:first').text();
var infoBtm = $(this).parents('div.buildinginfobtm');
var func = $(infoBtm).find('.upgradeicon.active').attr('onclick');
var upgradeImg = $(infoBtm).find('.upgradeicon.active .upgradeiconart img').attr('src');
if (func.indexOf("clickSelectUpgrade") == -1) {
error("Cannot resolve upgrade id.");
return;
}
// TODO: Improve...
// "return clickSelectUpgrade('7', 'balcony');"
var symbol = func.split("'")[3];
log("Selected " + symbol + " upgrade. Retrieve successful.");
var upgradeId;
var bUpgrades = buildingUpgrades[userContext.activeBuildingPanel];
for (var j = 0; j < bUpgrades.length; j++) {
if (bUpgrades[j].symbol == symbol) {
upgradeId = bUpgrades[j].id;
break;
}
}
if (!upgradeId) {
error("Fatal error, cannot resolve upgrade id.");
return;
}
log("Upgrade id resolved: " + upgradeId);
var upgrade = {
"name": name,
"upgradeId": upgradeId,
"type": "upgrade",
"symbol": symbol,
"img": upgradeImg,
"activeBuildingPanel": userContext.activeBuildingPanel
};
_this.queue.push(upgrade);
persist();
log("Pushed upgrade to queue.");
} else {
// Extract and construct object
var statview = $(this).parents(".statview");
var imgSrc = $(statview).find("div.statviewimg img").attr('src');
if (typeof (imgSrc) == "undefined") {
imgSrc = $(statview).find("span.iconview img").attr('src');
}
var statViewName = $(statview).find(".statviewname h3").text();
var quantity = $(this).attr("data-quantity");
// Extract variables needed
var recipeName;
var recipeData;
var source = userContext.productionItemsClick[userContext.currentProductionItem];
if (!source) {
error('Failed to extract source production item.');
return;
}
for (var i = 0; i < userContext.recipeData.length; i++) {
var r = userContext.recipeData[i];
if (r.output == source.outputSymbol) {
recipeName = r.symbol;
recipeData = [r];
break;
}
if (r.success_loot_table && r.success_loot_table == source.outputSymbol) {
recipeName = r.symbol;
recipeData = [r];
break;
}
if (r.success_loot_item && r.success_loot_item == source.outputSymbol) {
recipeName = r.symbol;
recipeData = [r];
break;
}
}
// Last attempt, these here are expensive operations
if (!recipeName) {
for (var i = 0; i < userContext.recipeData.length; i++) {
var r = userContext.recipeData[i];
var recipeInputs = JSON.stringify(r.input.split(","));
if (JSON.stringify(source.recipeInputs) === recipeInputs) {
recipeName = r.symbol;
recipeData = [r];
break;
}
}
}
if (!recipeName) {
error('Failed to extract recipeName.');
return;
}
if (!recipeData) {
error('Failed to extract recipeData.');
return;
}
log('All needed variables were extracted.');
do {
// Construct production element
var element = {
"recipeName": recipeName,
"name": statViewName,
"img": imgSrc,
"type": "item",
"outputSymbol": source.outputSymbol,
"recipeCategory": source.recipeCategory,
"recipeData": recipeData,
"activeBuildingPanel": userContext.activeBuildingPanel
};
// Insert the element into the queueArray (cloneInto for Mozilla)
//if (typeof (cloneInto) == "function") {
// var elementClone = cloneInto(element, unsafeWindow);
// _this.queue.push(elementClone);
//} else {
// _this.queue.push(element);
//}
_this.queue.push(element);
persist();
//options._this.queue = _this.queue;
//options.set("_this.queue");
quantity--;
log('Pushed element to queue.');
} while (quantity > 0);
}
log('Attempting immediate production...');
attempt(userContext.activeBuildingPanel);
inform('Enqueued.');
} catch (err) {
error(err);
}
}
function speedUp(building, timer) {
var speedUpAt = 300 - _this.queueDelay / 1000;
// Analyze and get rid of timer
if (timer && timer == speedUpAt) { // check at the exact time
log('Timer reached speeding up boundary: ' + timer + 's, try sequence.', 'PRODUCTION');
speedUp(building);
return;
} else if (timer && timer < speedUpAt - 30) { // check thirty seconds later
log('Timer falls into speed up boundary: ' + timer + 's, suspend further calls and try sequence.', 'PRODUCTION');
// Suspend further calls to this function
clearTimeout(userContext.buildingTimer[building.symbol]);
speedUp(building);
return;
} else if (timer != void 0){ // exit function in all other times if the timer exists
return;
}
doFinishProduction(building.item_id, function (r) {
if (r.building == void 0) {
warn("Cannot resolve building!", "PRODUCTION");
return;
}
// Analyze response
var b = r.building;
// building finished up
if (!buildingProducing(b)) {
log('Building is idle, attempt production.', 'PRODUCTION');
setTimeout(function () {
attempt(building.symbol);
}, _this.queueDelay);
return;
}
if (r.building.build_remaining == void 0) {
warn("Cannot resolve remaining time for this building!", "PRODUCTION");
return;
}
// building should undergo speed up check
var br = r.building.build_remaining;
log('Building undergoes speed up check...', 'PRODUCTION');
if (br <= speedUpAt) {
var d = building;
var c = building.id;
if (_this.doSpeedUp) {
log('Production speed up is enabled, trying to speed up building now.', 'PRODUCTION');
clearTimeout(userContext.buildingTimer[d.symbol]);
doInstantSpeedUp(c, false, function () {
speedUp(building);
});
} else {
log('Production speed up is disabled, attempt a finish on production after ' + (br + _this.queueDelay / 1000) + 's.', 'PRODUCTION');
// Suspend further calls to this function
clearTimeout(userContext.buildingTimer[building.symbol]);
setTimeout(function () {
speedUp(building);
}, (br * 1E3 + _this.queueDelay));
}
} else { // building does not hit the speedAt limit
log('Building cannot speed up at the moment, check again after ' + (br - speedUpAt) + 's.', 'PRODUCTION');
setTimeout(function () {
speedUp(building);
}, (br - speedUpAt) * 1E3);
}
});
}
function tableRow(i, el) {
return '<tr class="tableRow" style="cursor: pointer">' +
'<td><span class="ranklist colsort">' + i + '</span></td>' +
'<td><span class="ranklist colsort">' + el.type + '</span></td>' +
'<td><span class="name colsort">' + el.activeBuildingPanel + '</span></td>' +
'<td><span class="name colsort">' + el.name + '</span></td>' +
'<td><span class="avatarimg"><img src="' + el.img + '"></span></td>' +
'</tr>';
}
function deleteTableRow(e) {
e.preventDefault();
try {
var index = $(this).find("td:first span.ranklist").text();
log("Attempting to delete element with index " + index + " from the queue array.");
removeElement(index);
render(userContext.activeBuildingPanel);
} catch (err) {
error(err);
}
}
function render(building) {
log("Rendering production queue table. Building: " + (building == void 0 ? "All" : building));
var qTable = $(".queueTable.powertable:visible");
if (qTable.length == 0) {
error("Can't find queue table! Rendering production items failed.");
return;
}
// Clear table from any rows first
qTable.find(".tableRow").each(function () {
$(this).remove();
});
if (!_this.queue || _this.queue.length == 0) {
log("No queue was found to render.");
return;
}
// Render items
for (var i = 0; i < _this.queue.length; i++) {
if(building != void 0 && building != _this.queue[i].activeBuildingPanel) {
continue;
}
qTable.find(".headerRow").after(tableRow(i, _this.queue[i]));
}
log("Production queue rendered. Queue length: " + _this.queue.length + " items.");
}
return _this;
}($, localStorage, log, error, buildingBySymbol,
buildingProducing, buildingFinished, buildingBySymbol,
doFinishProduction, userContext, doProduction,
applySelectedUpgrade, buildingUpgrades, inform));