MediaWiki:XPtable.js

From Blue Archive Wiki
Revision as of 16:30, 23 April 2023 by Electricsheep (talk | contribs) (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...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Press Ctrl-F5.
/* 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($(this).closest("table"), $(this).closest("div.item").attr('data-itemnumber'),1);});
	$(".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')),
            'credit_price': parseInt($(this).attr('data-creditprice')), 
            '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} if 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.level_cap+'" 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, count) {
    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]);
        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());
        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').html(settings.planned_xp.toLocaleString()).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');
    xpcalc.find('.controls > .output > .total-credits > span').html(settings.total_credits.toLocaleString());
    
}
/* XP tables generic - end */