MediaWiki:XPtable.js: Difference between revisions

From Blue Archive Wiki
Jump to navigation Jump to search
Content deleted Content added
Created page with "→‎XP tables generic - start: var xptable_data = {}; var xpTableCounter = 0; $( document ).ready(function() { initXPTable(); $(".xpcalc .controls > .levels input").on("change mouseup keyup click", function(){updateXPTable($(this).closest("table"));}); $(".xpcalc .controls > .items input").on("change mouseup keyup click", function(){updateXPTable($(this).closest("table"), false);}); $(".xpcalc .controls > .items img").on("click", function(){addItemCount($(t..."
 
m Minor fix due to mediawiki-generated html changes
 
(4 intermediate revisions by the same user not shown)
Line 7: Line 7:
initXPTable();
initXPTable();
$(".xpcalc .controls > .levels input").on("change mouseup keyup click", function(){updateXPTable($(this).closest("table"));});
$(".xpcalc .controls > .levels input").on("change mouseup keyup click", function(){updateXPTable($(this).closest("table"));});
$(".xpcalc .controls > .items input").on("change mouseup keyup click", function(){updateXPTable($(this).closest("table"), false);});
$(".xpcalc .controls > .items input").on("change mouseup keyup click", function(){updateXPTable($(this).closest("table"), false);});
$(".xpcalc .controls > .items img").on("click", function(){addItemCount($(this).closest("table"), $(this).closest("div.item").attr('data-itemnumber'),1);});
$(".xpcalc .controls > .items img").on("click", function(e){addItemCount($(this).closest("table"), $(this).closest("div.item").attr('data-itemnumber'),e);});
$(".xptable > div.content").children("div").on("click", function(){changeTargetLevel($(this).closest("table"),$(this).find('span.level').html());});
$(".xpcalc .xptable > div.content").children("div").on("click", function(){changeTargetLevel($(this).closest("table"),$(this).find('span.level').html());});

});
});
Line 20: Line 19:
var data = {};
var data = {};
data.settings = {
data.settings = {
'type': $(this).attr('data-type'),
'type': $(this).attr('data-type'),
'level_cap': parseInt($(this).attr('data-levelcap')),
'level_cap': parseInt($(this).attr('data-levelcap')),
'max_level': parseInt($(this).attr('data-levelcap')),
'max_level': parseInt($(this).attr('data-levelcap')),
'credit_price': parseInt($(this).attr('data-creditprice')),
'default_level': parseInt($(this).attr('data-defaultlevel')) || parseInt($(this).attr('data-levelcap')),
'credit_price': parseInt($(this).attr('data-creditprice')) || 0,
'level_from': 0,
'level_to': 0,
'level_from': 0,
'level_to': 0,
'target_xp':0,
'target_xp':0,
'planned_xp':0,
'planned_xp':0,
'xp_overshoot': 0,
'xp_overshoot': 0,
'total_credits': 0,
'total_credits': 0,
};
};


data.items = {};
data.items = {};
$(this).find(".controls > .items div.item").each(function(){
$(this).find(".controls > .items div.item").each(function(){
var item_number = $(this).attr('data-itemnumber');
var item_number = $(this).attr('data-itemnumber');
var value = $(this).attr('data-value');
var value = $(this).attr('data-value');
data.items[item_number] = parseInt(value);
data.items[item_number] = parseInt(value);
});
});


Line 45: Line 45:
data[level] = {};
data[level] = {};
var xp = $(this).find('span.xp').html();
var xp = $(this).find('span.xp').html();
var total_xp = $(this).find('span.total_xp').html();
var total_xp = $(this).find('span.total_xp').html();
data[level] = {'xp':parseInt(xp), 'total_xp':parseInt(total_xp)};
data[level] = {'xp':parseInt(xp), 'total_xp':parseInt(total_xp)};


if (level > data.settings.level_cap) {
if (level > data.settings.level_cap) {
$(this).addClass('tbd').attr('title', "Currently not attainable in the game");
$(this).addClass('tbd').attr('title', "Currently not attainable in the game");
data.settings.max_level = level;
data.settings.max_level = level;
//console.log(`Level ${level} if outside of expected cap`);
//console.log(`Level ${level} is outside of expected cap`);
}
}
});
});


$(this).find(".controls > .levels .level-from").append('<input type="number" value="1" step="1" min="1" max="'+data.settings.max_level+'">');
$(this).find(".controls > .levels .level-from").append('<input type="number" value="1" step="1" min="1" max="'+data.settings.max_level+'">');
$(this).find(".controls > .levels .level-to").append('<input type="number" value="'+data.settings.level_cap+'" step="1" min="1" max="'+data.settings.max_level+'">');
$(this).find(".controls > .levels .level-to").append('<input type="number" value="'+data.settings.default_level+'" step="1" min="1" max="'+data.settings.max_level+'">');
$(this).find(".controls > .items .item").append('<input type="number" value="0" step="1" min="0" max="999"></span>');
$(this).find(".controls > .items .item").append('<input type="number" value="0" step="1" min="0" max="999"></span>');


xptable_data[id] = data;
xptable_data[id] = data;
Line 67: Line 67:


function changeTargetLevel (xpcalc, target_level) {
function changeTargetLevel (xpcalc, target_level) {
xpcalc.find('.controls > .levels > .level-to > input').val(target_level);
xpcalc.find('.controls > .levels > .level-to > input').val(target_level);
updateXPTable(xpcalc);
updateXPTable(xpcalc);
}
}


function addItemCount (xpcalc, item_id, count) {
function addItemCount (xpcalc, item_id, event) {
var count = 1;
var input = xpcalc.find('.controls > .items .item-'+item_id+' > input');
if (event.shiftKey) count *= 10;
input.val( parseInt(input.val())+count );
if (event.ctrlKey) count *= -1;
updateXPTable(xpcalc, false);

var input = xpcalc.find('.controls > .items .item-'+item_id+' > input');
input.val( parseInt(input.val())+count );
updateXPTable(xpcalc, false);
}
}




function planXPItems (id) {
function planXPItems (id) {
//var data = xptable_data[id]
//var data = xptable_data[id]
var settings = xptable_data[id].settings;
var settings = xptable_data[id].settings;
var items = xptable_data[id].items;
var items = xptable_data[id].items;
var itemplan = new Array(Object.keys(items).length); for (let i=1; i<Object.keys(items).length+1; ++i) itemplan[i] = 0;
var itemplan = new Array(Object.keys(items).length); for (let i=1; i<Object.keys(items).length+1; ++i) itemplan[i] = 0;
var planned_xp = 0; //actual XP of planned items, should be >= target with minimal overshot
var planned_xp = 0; //actual XP of planned items, should be >= target with minimal overshot
var target_xp = 0; //the minimum XP amount needed to reach target level
var target_xp = 0; //the minimum XP amount needed to reach target level
var hysteresis = items[1];
var hysteresis = items[1];


for (var index = settings.level_from; index < settings.level_to; index++) {
for (var index = settings.level_from; index < settings.level_to; index++) {
target_xp += xptable_data[id][index].xp;
target_xp += xptable_data[id][index].xp;
}
}
settings.target_xp = target_xp;
settings.target_xp = target_xp;


for (index = Object.keys(items).length; index > 0; index--) {
for (index = Object.keys(items).length; index > 0; index--) {
itemplan[index] = Math.floor((target_xp + hysteresis)/items[index]);
itemplan[index] = Math.floor((target_xp + hysteresis)/items[index]);
planned_xp += items[index] * itemplan[index];
if ( itemplan[index] > 999 ) itemplan[index] = 999;
target_xp -= items[index] * itemplan[index];
planned_xp += items[index] * itemplan[index];
target_xp -= items[index] * itemplan[index];


//console.log(`Added item ${index} x ${itemplan[index]}, remaining target xp is ${target_xp} `);
//console.log(`Added item ${index} x ${itemplan[index]}, remaining target xp is ${target_xp} `);
}
}
settings.planned_xp = planned_xp;
settings.planned_xp = planned_xp;
if (target_xp<0) settings.xp_overshoot = -target_xp;
if (target_xp<0) settings.xp_overshoot = -target_xp;
settings.total_credits = planned_xp*settings.credit_price;
settings.total_credits = planned_xp*settings.credit_price;
settings.itemplan = itemplan;
settings.itemplan = itemplan;
}
}


function getXPItems (xpcalc, id) {
function getXPItems (xpcalc, id) {
var data = xptable_data[id];
var data = xptable_data[id];
var settings = xptable_data[id].settings;
var settings = xptable_data[id].settings;
var items = xptable_data[id].items;
var items = xptable_data[id].items;
var itemplan = new Array(Object.keys(items).length);
var itemplan = new Array(Object.keys(items).length);
var planned_xp = 0; //actual XP of planned items, should be >= target with minimal overshot
var planned_xp = 0; //actual XP of planned items, should be >= target with minimal overshot
var target_xp = 0; //the minimum XP amount needed to reach target level
var target_xp = 0; //the minimum XP amount needed to reach target level
//var hysteresis = items[1];
//var hysteresis = items[1];
//var level_to = 0;
//var level_to = 0;
for (let index=1; index<Object.keys(items).length+1; ++index) {
for (let index=1; index<Object.keys(items).length+1; ++index) {
itemplan[index] = parseInt(xpcalc.find('.controls > .items .item-'+index+' > input').val());
itemplan[index] = parseInt(xpcalc.find('.controls > .items .item-'+index+' > input').val());
planned_xp += items[index] * itemplan[index];
if (itemplan[index] < 0) itemplan[index] = 0;
planned_xp += items[index] * itemplan[index];
}
}
settings.itemplan = itemplan;
settings.planned_xp = planned_xp;
settings.itemplan = itemplan;
settings.total_credits = planned_xp*settings.credit_price;
settings.planned_xp = planned_xp;
settings.total_credits = planned_xp*settings.credit_price;


//console.log(`Starting with planned xp ${planned_xp}`)
//console.log(`Starting with planned xp ${planned_xp}`)
for (var index = settings.level_from; index < settings.max_level; index++) {
for (var index = settings.level_from; index < settings.max_level; index++) {
if (planned_xp < data[index].xp) break;
if (planned_xp < data[index].xp) break;
planned_xp -= data[index].xp;
planned_xp -= data[index].xp;
target_xp += data[index].xp;
target_xp += data[index].xp;
settings.level_to = index+1;
settings.level_to = index+1;
}
}


//console.log(`Upgraded to level ${settings.level_to } with remaining planned xp ${planned_xp}`);
//console.log(`Upgraded to level ${settings.level_to } with remaining planned xp ${planned_xp}`);
settings.target_xp = target_xp;
settings.target_xp = target_xp;
settings.xp_overshoot = planned_xp;
settings.xp_overshoot = planned_xp;
xpcalc.find('.controls > .levels > .level-to > input').val(settings.level_to);
xpcalc.find('.controls > .levels > .level-to > input').val(settings.level_to);


}
}
Line 143: Line 149:


function updateXPTable (xpcalc, optimize_items){
function updateXPTable (xpcalc, optimize_items){
optimize_items = (typeof optimize_items !== 'undefined') ? optimize_items : true; //default true, ES5 does not support function defaults
optimize_items = (typeof optimize_items !== 'undefined') ? optimize_items : true; //default true, ES5 does not support function defaults


var id = xpcalc.attr('id');
var id = xpcalc.attr('id');
var settings = xptable_data[id].settings;
var settings = xptable_data[id].settings;
//console.log(settings);
//console.log(settings);


var level_from = parseInt(xpcalc.find('.controls > .levels > .level-from > input').val());
var level_from = parseInt(xpcalc.find('.controls > .levels > .level-from > input').val());
var level_to = parseInt(xpcalc.find('.controls > .levels > .level-to > input').val());
var level_to = parseInt(xpcalc.find('.controls > .levels > .level-to > input').val());
level_from = (typeof level_from !== 'undefined' && !isNaN(level_from)) ? level_from : 1;
level_from = (typeof level_from !== 'undefined' && !isNaN(level_from)) ? level_from : 1;
level_to = (typeof level_to !== 'undefined' && !isNaN(level_to)) ? level_to : settings.level_cap;
level_to = (typeof level_to !== 'undefined' && !isNaN(level_to)) ? level_to : settings.level_cap;
if (level_from < 1) { xpcalc.find('.controls > .levels > .level-from > input').val(1); level_from = 1; }
if (level_from < 1) { xpcalc.find('.controls > .levels > .level-from > input').val(1); level_from = 1; }
if (level_from >= settings.max_level) { xpcalc.find('.controls > .levels > .level-from > input').val(settings.max_level-1); level_from = settings.max_level-1; }
if (level_from >= settings.max_level) { xpcalc.find('.controls > .levels > .level-from > input').val(settings.max_level-1); level_from = settings.max_level-1; }


if (level_to <= level_from) { xpcalc.find('.controls > .levels > .level-to > input').val(level_from+1); level_to = level_from+1; }
if (level_to <= level_from) { xpcalc.find('.controls > .levels > .level-to > input').val(level_from+1); level_to = level_from+1; }
if (level_to > settings.max_level) { xpcalc.find('.controls > .levels > .level-to > input').val(settings.max_level); level_to = settings.max_level; }
if (level_to > settings.max_level) { xpcalc.find('.controls > .levels > .level-to > input').val(settings.max_level); level_to = settings.max_level; }


settings.level_from = level_from;
settings.level_from = level_from;
settings.level_to = level_to;
settings.level_to = level_to;


//console.log (`Calculating Exp from level ${level_from} to ${level_to}`)
//console.log (`Calculating Exp from level ${level_from} to ${level_to}`)
if (optimize_items) planXPItems(id);
if (optimize_items) planXPItems(id);
else getXPItems(xpcalc, id);
else getXPItems(xpcalc, id);
//console.log('Itemplan after is '+settings.itemplan);
//console.log('Itemplan after is '+settings.itemplan);
//console.log (`Exp ${settings.planned_xp}/${settings.target_xp}; total price ${settings.total_credits}`)
//console.log (`Exp ${settings.planned_xp}/${settings.target_xp}; total price ${settings.total_credits}`)


for (var index = Object.keys(xptable_data[id].items).length; index > 0; index--) {
for (var index = Object.keys(xptable_data[id].items).length; index > 0; index--) {
xpcalc.find('.controls > .items .item-'+index+' > input').val(settings.itemplan[index]);
xpcalc.find('.controls > .items .item-'+index+' > input').val(settings.itemplan[index]);
}
}
xpcalc.find('.controls > .output > .total-xp > span').html(settings.planned_xp.toLocaleString()).attr('title','XP: '+settings.planned_xp+'/'+settings.target_xp+'\nOvershoot: '+settings.xp_overshoot);
xpcalc.find('.controls > .output > .total-xp > span:last-of-type').html(settings.planned_xp.toLocaleString());
xpcalc.find('.controls > .output').attr('title','XP: '+settings.planned_xp+'/'+settings.target_xp+'\nOvershoot: '+settings.xp_overshoot);
if (settings.target_xp>0 && settings.xp_overshoot > xptable_data[id].items[1]) xpcalc.find('.controls > .output').addClass('warn');
else xpcalc.find('.controls > .output').removeClass('warn');
if (settings.target_xp>0 && settings.xp_overshoot > xptable_data[id].items[1]) xpcalc.find('.controls > .output').addClass('warn');
xpcalc.find('.controls > .output > .total-credits > span').html(settings.total_credits.toLocaleString());
else xpcalc.find('.controls > .output').removeClass('warn');
if (settings.credit_price) xpcalc.find('.controls > .output > .total-credits > span:last-of-type').html(settings.total_credits.toLocaleString());
}
}
/* XP tables generic - end */
/* XP tables generic - end */

Latest revision as of 02:26, 7 November 2023

/* XP tables generic - start */
var xptable_data = {};
var xpTableCounter = 0;

	
$( document ).ready(function() {
	initXPTable();
	$(".xpcalc .controls > .levels input").on("change mouseup keyup click", function(){updateXPTable($(this).closest("table"));});
	$(".xpcalc .controls > .items input").on("change mouseup keyup click", function(){updateXPTable($(this).closest("table"), false);});
	$(".xpcalc .controls > .items img").on("click", function(e){addItemCount($(this).closest("table"), $(this).closest("div.item").attr('data-itemnumber'),e);});
	$(".xpcalc .xptable > div.content").children("div").on("click", function(){changeTargetLevel($(this).closest("table"),$(this).find('span.level').html());});
});
	

function initXPTable(){
	$(".xpcalc").each(function(){
		var id = 'xpcalc-'+(++xpTableCounter);
		$(this).attr('id',id);
		
		var data = {};
		data.settings = {
			'type': $(this).attr('data-type'), 
			'level_cap': parseInt($(this).attr('data-levelcap')),
			'max_level': parseInt($(this).attr('data-levelcap')),
			'default_level': parseInt($(this).attr('data-defaultlevel')) || parseInt($(this).attr('data-levelcap')), 
			'credit_price': parseInt($(this).attr('data-creditprice')) || 0, 
			'level_from': 0, 
			'level_to': 0, 
			'target_xp':0,
			'planned_xp':0,
			'xp_overshoot': 0,
			'total_credits': 0,
		};

		data.items = {};
		$(this).find(".controls > .items div.item").each(function(){
			var item_number = $(this).attr('data-itemnumber');
			var value = $(this).attr('data-value');
			data.items[item_number] = parseInt(value);
		});


		$(this).find(".xptable .content > div").each(function(){
			var level = $(this).find('span.level').html();
			data[level] = {};
			var xp = $(this).find('span.xp').html();
			var total_xp = $(this).find('span.total_xp').html();
			data[level] = {'xp':parseInt(xp), 'total_xp':parseInt(total_xp)};

			if (level >  data.settings.level_cap) {
				$(this).addClass('tbd').attr('title', "Currently not attainable in the game");
				data.settings.max_level = level;
				//console.log(`Level ${level} is outside of expected cap`);
			}
		});

		$(this).find(".controls > .levels .level-from").append('<input type="number" value="1" step="1" min="1" max="'+data.settings.max_level+'">');
		$(this).find(".controls > .levels .level-to").append('<input type="number" value="'+data.settings.default_level+'" step="1" min="1" max="'+data.settings.max_level+'">');
		$(this).find(".controls > .items .item").append('<input type="number" value="0" step="1" min="0" max="999"></span>');

		xptable_data[id] = data;

		updateXPTable($(this));
	});
}


function changeTargetLevel (xpcalc, target_level) {
	xpcalc.find('.controls > .levels > .level-to > input').val(target_level);
	updateXPTable(xpcalc);
}

function addItemCount (xpcalc, item_id, event) {
	var count = 1;
	if (event.shiftKey) count *= 10; 
	if (event.ctrlKey) count *= -1;

	var input = xpcalc.find('.controls > .items .item-'+item_id+' > input');
	input.val( parseInt(input.val())+count );
	updateXPTable(xpcalc, false);
}


function planXPItems (id) {
	//var data = xptable_data[id]
	var settings = xptable_data[id].settings;
	var items = xptable_data[id].items;
	var itemplan = new Array(Object.keys(items).length); for (let i=1; i<Object.keys(items).length+1; ++i) itemplan[i] = 0;
	var planned_xp = 0; //actual XP of planned items, should be >= target with minimal overshot
	var target_xp = 0; //the minimum XP amount needed to reach target level
	var hysteresis = items[1];
	

	for (var index = settings.level_from; index < settings.level_to; index++) {
		target_xp += xptable_data[id][index].xp;
	}
	settings.target_xp = target_xp;

	for (index = Object.keys(items).length; index > 0; index--) {
		itemplan[index] = Math.floor((target_xp + hysteresis)/items[index]);
		if ( itemplan[index] > 999 ) itemplan[index] = 999;
		planned_xp += items[index] * itemplan[index];
		target_xp -= items[index] * itemplan[index];

		//console.log(`Added item ${index} x ${itemplan[index]}, remaining target xp is ${target_xp} `);
	}
	settings.planned_xp = planned_xp;
	if (target_xp<0) settings.xp_overshoot = -target_xp;
	settings.total_credits = planned_xp*settings.credit_price;
	settings.itemplan = itemplan;
}
	

function getXPItems (xpcalc, id) {
	var data = xptable_data[id];
	var settings = xptable_data[id].settings;
	var items = xptable_data[id].items;
	var itemplan = new Array(Object.keys(items).length); 
	var planned_xp = 0; //actual XP of planned items, should be >= target with minimal overshot
	var target_xp = 0; //the minimum XP amount needed to reach target level
	//var hysteresis = items[1];
	//var level_to = 0;
	
	for (let index=1; index<Object.keys(items).length+1; ++index) {
		itemplan[index] = parseInt(xpcalc.find('.controls > .items .item-'+index+' > input').val());
		if (itemplan[index] < 0) itemplan[index] = 0; 
		planned_xp += items[index] * itemplan[index];
	}
	settings.itemplan = itemplan;
	settings.planned_xp = planned_xp;
	settings.total_credits = planned_xp*settings.credit_price;

	//console.log(`Starting with planned xp ${planned_xp}`)
	for (var index = settings.level_from; index < settings.max_level; index++) {
		if (planned_xp < data[index].xp) break;	 
		planned_xp -= data[index].xp;
		target_xp += data[index].xp;
		settings.level_to = index+1;
	}

	//console.log(`Upgraded to level ${settings.level_to } with remaining planned xp ${planned_xp}`);
	settings.target_xp = target_xp;
	settings.xp_overshoot = planned_xp;
	
	xpcalc.find('.controls > .levels > .level-to > input').val(settings.level_to);

}


function updateXPTable (xpcalc, optimize_items){
	optimize_items = (typeof optimize_items !== 'undefined') ? optimize_items : true; //default true, ES5 does not support function defaults

	var id = xpcalc.attr('id');
	var settings = xptable_data[id].settings;
	//console.log(settings);

	var level_from = parseInt(xpcalc.find('.controls > .levels > .level-from > input').val());
	var level_to = parseInt(xpcalc.find('.controls > .levels > .level-to > input').val());
	
	level_from = (typeof level_from !== 'undefined' && !isNaN(level_from)) ? level_from : 1;
	level_to = (typeof level_to !== 'undefined' && !isNaN(level_to)) ? level_to : settings.level_cap;
	
	if (level_from < 1) 	 				{ xpcalc.find('.controls > .levels > .level-from > input').val(1);	level_from = 1; }
	if (level_from >= settings.max_level) 	{ xpcalc.find('.controls > .levels > .level-from > input').val(settings.max_level-1); level_from = settings.max_level-1; }

	if (level_to <= level_from) 			{ xpcalc.find('.controls > .levels > .level-to > input').val(level_from+1);	level_to = level_from+1; }
	if (level_to > settings.max_level) 		{ xpcalc.find('.controls > .levels > .level-to > input').val(settings.max_level); level_to = settings.max_level; }

	settings.level_from = level_from;
	settings.level_to = level_to;

	//console.log (`Calculating Exp from level ${level_from} to ${level_to}`)
	if (optimize_items) planXPItems(id);
	else getXPItems(xpcalc, id);
	//console.log('Itemplan after is '+settings.itemplan);
	
	//console.log (`Exp ${settings.planned_xp}/${settings.target_xp}; total price ${settings.total_credits}`)

	
	for (var index = Object.keys(xptable_data[id].items).length; index > 0; index--) {
		xpcalc.find('.controls > .items .item-'+index+' > input').val(settings.itemplan[index]);
	}	
	
	xpcalc.find('.controls > .output > .total-xp > span:last-of-type').html(settings.planned_xp.toLocaleString());
	xpcalc.find('.controls > .output').attr('title','XP: '+settings.planned_xp+'/'+settings.target_xp+'\nOvershoot: '+settings.xp_overshoot);
	if (settings.target_xp>0 && settings.xp_overshoot > xptable_data[id].items[1])  xpcalc.find('.controls > .output').addClass('warn'); 
	else xpcalc.find('.controls > .output').removeClass('warn');
	
	if (settings.credit_price) xpcalc.find('.controls > .output > .total-credits > span:last-of-type').html(settings.total_credits.toLocaleString());
	
}
/* XP tables generic - end */