Widget:GWHonorCalculator
Jump to navigation
Jump to search
<style>
.gw-calc {
border-spacing: 0px;
border: 0;
}
.gw-calc .gw-calc-ratio {
text-align: center;
}
.gw-calc .gw-calc-name {
text-align: center;
}
.gw-calc td, .gw-calc input, .gw-calc select {
text-align: right;
}
.gw-calc caption {
/*background-color: #9BC2E6;*/
}
.gw-calc > tr > th, .gw-calc > tr > td {
padding: 2px 5px;
}
.gw-calc td {
border: 0 !important;
border-bottom: 1px solid #ddd !important;
}
.gw-calc th {
/*background-color: #BDD7EE;*/
}
.gw-calc-total td {
/*background-color: #BDD7EE;*/
}
</style><table class="wikitable gw-calc gw-calc-options">
<tr>
<th colspan="8">Options</th>
</tr>
<tr>
<td>Current meat:</td>
<td><input id="meat_current" type="number" min="0" max="100000" step="1" value="0" /></td>
<td>Current tokens:</td>
<td><input id="token_current" type="number" min="0" max="9999999" step="1" value="0" /></td>
<td>Current box:</td>
<td><input id="box_current" type="number" min="1" max="250" step="1" value="1" /></td>
<td>Current honor:</td>
<td><input id="honor_current" type="number" min="0" max="99999999999" step="1" value="0" /></td>
</tr>
<tr>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td><span class="tooltip">Target box:<span class="tooltiptext">Your minimum desired number of boxes, or eternals weapons.</span></span></td>
<td><input id="box_target" type="number" min="1" max="250" step="1" value="45" /></td>
<td><span class="tooltip">Target honor:<span class="tooltiptext">Your minimum desired honor.</span></span></td>
<td><input id="honor_target" type="number" min="1" max="99999999999" step="1" value="1000000000" /></td>
</tr>
</table>
<table class="wikitable gw-calc gw-calc-bosses">
<tr>
<th colspan="15">Bosses</th>
</tr>
<tr>
<th rowspan="2"><span class="tooltip">Ratio<span class="tooltiptext">Enter which EX you're doing and an estimate how much meat you'll use for each type of NM.</span></span></th>
<th rowspan="2">Name</th>
<th colspan="2">Per battle</th>
<th colspan="5">Total</th>
<th colspan="2"><span class="tooltip">Pace (m)<span class="tooltiptext">Your average battle to battle pace, in minutes.</span></span></th>
<th colspan="2"><span class="tooltip">Time (h)<span class="tooltiptext">Expected time to finish all battles, in hours.</span></span></th>
</tr>
<tr>
<th>Honor</th>
<th><span class="tooltip">Meat<span class="tooltiptext">Average number of meat obtained per battle.</span></span></th>
<th>Battles</th>
<th>Meat</th>
<th>Tokens</th>
<th>Honor</th>
<th>Pots</th>
<th>Slow</th>
<th>Fast</th>
<th>Slow</th>
<th>Fast</th>
</tr>
<tr id="now_row">
<td> </td>
<td class="gw-calc-name">Have</td>
<td> </td>
<td> </td>
<td id="now_battles"> </td>
<td id="now_meat_sum">0</td>
<td><span class="tooltip"><span id="now_tokens">0</span><span class="tooltiptext">Includes tokens that will be earned from the Final Rally rewards based on your current Honor.</span></td>
<td id="now_honor_sum">0</td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
</tr>
<tr id="ex0_row">
<td class="gw-calc-ratio"><input type="radio" id="ex_ratio" name="ex_ratio" value="ex0"></td>
<td class="gw-calc-name">EX</td>
<td><input id="ex0_honor" type="number" min="1000" max="90000000" step="1000" value="51000" /></td>
<td><input id="ex0_meat" type="number" min="0.1" max="99.9" step="0.1" value="5" /></td>
<td id="ex0_battles">0</td>
<td id="ex0_meat_sum">0</td>
<td id="ex0_tokens">0</td>
<td id="ex0_honor_sum">0</td>
<td id="ex0_pots">0</td>
<td><input id="ex0_pace_slow" type="number" min="0.1" max="9" step="0.05" value="1" /></td>
<td><input id="ex0_pace_fast" type="number" min="0.1" max="9" step="0.05" value="0.3" /></td>
<td id="ex0_time_slow">0m</td>
<td id="ex0_time_fast">0m</td>
</tr>
<tr id="exx_row">
<td class="gw-calc-ratio"><input type="radio" id="ex_ratio" name="ex_ratio" value="exx" checked></td>
<td class="gw-calc-name">EX+</td>
<td><input id="exx_honor" type="number" min="1000" max="90000000" step="1000" value="88000" /></td>
<td><input id="exx_meat" type="number" min="0.1" max="99.9" step="0.1" value="6.5" /></td>
<td id="exx_battles">0</td>
<td id="exx_meat_sum">0</td>
<td id="exx_tokens">0</td>
<td id="exx_honor_sum">0</td>
<td id="exx_pots">0</td>
<td><input id="exx_pace_slow" type="number" min="0.1" max="9" step="0.05" value="1" /></td>
<td><input id="exx_pace_fast" type="number" min="0.1" max="9" step="0.05" value="0.3" /></td>
<td id="exx_time_slow">0m</td>
<td id="exx_time_fast">0m</td>
</tr>
<tr id="n90_row">
<td><select id="n90_ratio">
<option value="0">0%</option>
<option value="10">10%</option>
<option value="20">20%</option>
<option value="30">30%</option>
<option value="40">40%</option>
<option value="50">50%</option>
<option value="60">60%</option>
<option value="70">70%</option>
<option value="80">80%</option>
<option value="90">90%</option>
<option value="100">100%</option>
</select></td>
<td class="gw-calc-name">NM 90</td>
<td><input id="n90_honor" type="number" min="1000" max="90000000" step="1000" value="250000" /></td>
<td id="n90_meat">-5</td>
<td id="n90_battles">0</td>
<td id="n90_meat_sum">0</td>
<td id="n90_tokens">0</td>
<td id="n90_honor_sum">0</td>
<td id="n90_pots">0</td>
<td><input id="n90_pace_slow" type="number" min="0.1" max="30" step="0.1" value="1" /></td>
<td><input id="n90_pace_fast" type="number" min="0.1" max="30" step="0.1" value="0.3" /></td>
<td id="n90_time_slow">0m</td>
<td id="n90_time_fast">0m</td>
</tr>
<tr id="n95_row">
<td><select id="n95_ratio">
<option value="0">0%</option>
<option value="10">10%</option>
<option value="20">20%</option>
<option value="30" selected>30%</option>
<option value="40">40%</option>
<option value="50">50%</option>
<option value="60">60%</option>
<option value="70">70%</option>
<option value="80">80%</option>
<option value="90">90%</option>
<option value="100">100%</option>
</select></td>
<td class="gw-calc-name">NM 95</td>
<td><input id="n95_honor" type="number" min="1000" max="90000000" step="1000" value="910000" /></td>
<td id="n95_meat">-10</td>
<td id="n95_battles">0</td>
<td id="n95_meat_sum">0</td>
<td id="n95_tokens">0</td>
<td id="n95_honor_sum">0</td>
<td id="n95_pots">0</td>
<td><input id="n95_pace_slow" type="number" min="0.1" max="30" step="0.1" value="4" /></td>
<td><input id="n95_pace_fast" type="number" min="0.1" max="30" step="0.1" value="2" /></td>
<td id="n95_time_slow">0m</td>
<td id="n95_time_fast">0m</td>
</tr>
<tr id="n10_row">
<td><select id="n10_ratio">
<option value="0">0%</option>
<option value="10">10%</option>
<option value="20">20%</option>
<option value="30">30%</option>
<option value="40">40%</option>
<option value="50">50%</option>
<option value="60">60%</option>
<option value="70">70%</option>
<option value="80">80%</option>
<option value="90">90%</option>
<option value="100">100%</option>
</select></td>
<td class="gw-calc-name">NM 100</td>
<td><input id="n10_honor" type="number" min="1000" max="90000000" step="1000" value="2650000" /></td>
<td id="n10_meat">-20</td>
<td id="n10_battles">0</td>
<td id="n10_meat_sum">0</td>
<td id="n10_tokens">0</td>
<td id="n10_honor_sum">0</td>
<td id="n10_pots">0</td>
<td><input id="n10_pace_slow" type="number" min="0.1" max="30" step="0.1" value="10" /></td>
<td><input id="n10_pace_fast" type="number" min="0.1" max="30" step="0.1" value="5" /></td>
<td id="n10_time_slow">0m</td>
<td id="n10_time_fast">0m</td>
</tr>
<tr id="n15_row">
<td><select id="n15_ratio">
<option value="0">0%</option>
<option value="10">10%</option>
<option value="20">20%</option>
<option value="30" selected>30%</option>
<option value="40">40%</option>
<option value="50">50%</option>
<option value="60">60%</option>
<option value="70">70%</option>
<option value="80">80%</option>
<option value="90">90%</option>
<option value="100">100%</option>
</select></td>
<td class="gw-calc-name">NM 150</td>
<td><input id="n15_honor" type="number" min="1000" max="90000000" step="1000" value="4100000" /></td>
<td id="n15_meat">-20</td>
<td id="n15_battles">0</td>
<td id="n15_meat_sum">0</td>
<td id="n15_tokens">0</td>
<td id="n15_honor_sum">0</td>
<td id="n15_pots">0</td>
<td><input id="n15_pace_slow" type="number" min="0.1" max="30" step="0.1" value="10" /></td>
<td><input id="n15_pace_fast" type="number" min="0.1" max="30" step="0.1" value="5" /></td>
<td id="n15_time_slow">0m</td>
<td id="n15_time_fast">0m</td>
</tr>
<tr id="n20_row">
<td><select id="n20_ratio">
<option value="0">0%</option>
<option value="10">10%</option>
<option value="20">20%</option>
<option value="30">30%</option>
<option value="40" selected>40%</option>
<option value="50">50%</option>
<option value="60">60%</option>
<option value="70">70%</option>
<option value="80">80%</option>
<option value="90">90%</option>
<option value="100">100%</option>
</select></td>
<td class="gw-calc-name">NM 200</td>
<td><input id="n20_honor" type="number" min="1000" max="90000000" step="1000" value="13350000" /></td>
<td id="n20_meat">-20</td>
<td id="n20_battles">0</td>
<td id="n20_meat_sum">0</td>
<td id="n20_tokens">0</td>
<td id="n20_honor_sum">0</td>
<td id="n20_pots">0</td>
<td><input id="n20_pace_slow" type="number" min="0.1" max="30" step="0.1" value="15" /></td>
<td><input id="n20_pace_fast" type="number" min="0.1" max="30" step="0.1" value="7" /></td>
<td id="n20_time_slow">0m</td>
<td id="n20_time_fast">0m</td>
</tr>
<tr id="total_row" class="gw-calc-total">
<th colspan="4">Total:</th>
<td id="total_battles">0</td>
<td><span class="tooltip"><span id="total_meat">0</span><span class="tooltiptext">Excess meat thrown away.</span></span></td>
<td id="total_tokens">0</td>
<td id="total_honor">0</td>
<td id="total_pots">0</td>
<td colspan="2"> </td>
<td id="total_time_slow">0h</td>
<td id="total_time_fast">0h</td>
</tr>
</table>
<script type="application/javascript">
(function() {
// Make an array for token boxes
let token_boxes = (function(){
let boxes = [];
boxes[0] = {
box: 0,
tokens: 0,
total: 0
};
let prev = 0;
let total = 0;
for (let i = 1; i < 250; i++) {
let tokens = ({
1: 1600,
2: 2400,
3: 2400,
4: 2400,
5: 2000,
46: 10000,
81: 15000,
})[i] || prev;
prev = tokens;
total += tokens;
boxes[i] = {
box: i,
tokens: tokens,
total: total
};
}
return boxes;
})();
// Make an array with the available bosses and updates it with inputs from the bosses table
let get_bosses = (function() {
let bosses = [
{ ix: 'ex0', name: 'EX', meat: 0, ap: 30, base_tokens: 54 },
{ ix: 'exx', name: 'EX+', meat: 0, ap: 30, base_tokens: 66 },
{ ix: 'n90', name: 'NM 90', meat: -5, ap: 30, base_tokens: 83 },
{ ix: 'n95', name: 'NM 95', meat: -10, ap: 40, base_tokens: 111 },
{ ix: 'n10', name: 'NM 100', meat: -20, ap: 50, base_tokens: 168 },
{ ix: 'n15', name: 'NM 150', meat: -20, ap: 50, base_tokens: 257 },
{ ix: 'n20', name: 'NM 200', meat: -20, ap: 50, base_tokens: 338 },
];
let ratio_sum_meat_use = 0;
for (let i = 0; i < bosses.length; i++) {
let boss = bosses[i];
if (boss.meat == 0) {
let ratio_radio = document.querySelector('input[name="ex_ratio"]:checked');
boss.ratio = (ratio_radio.value == boss.ix) ? 100 : 0;
} else {
let ratio_select = document.querySelector('select#'+boss.ix+'_ratio');
boss.ratio = parseFloat(ratio_select.value);
ratio_sum_meat_use += Math.abs(boss.ratio);
}
}
for (let i = 0; i < bosses.length; i++) {
let boss = bosses[i];
let ratio_sum = boss.meat > 0 ? 100 : ratio_sum_meat_use;
if (ratio_sum == 0) {
boss.percent = 0;
} else {
boss.percent = boss.ratio / ratio_sum;
}
let honor_input = document.querySelector('input#'+boss.ix+'_honor');
boss.honor = parseFloat(honor_input.value);
boss.tokens = boss.base_tokens + (boss.honor / 16667);
let meat_input = document.querySelector('input#'+boss.ix+'_meat');
if (meat_input != null)
boss.meat = parseFloat(meat_input.value);
let slow_input = document.querySelector('input#'+boss.ix+'_pace_slow');
boss.pace_slow = parseFloat(slow_input.value);
let fast_input = document.querySelector('input#'+boss.ix+'_pace_fast');
boss.pace_fast = parseFloat(fast_input.value);
}
return bosses;
});
// Make an object with the values in the user options table
let get_options = (function() {
return {
meat_current: parseFloat(document.querySelector('input#meat_current').value),
token_current: parseFloat(document.querySelector('input#token_current').value),
box_current: parseFloat(document.querySelector('input#box_current').value),
box_target: parseFloat(document.querySelector('input#box_target').value),
honor_current: parseFloat(document.querySelector('input#honor_current').value),
honor_target: parseFloat(document.querySelector('input#honor_target').value),
};
});
// Calculate the amount of honor and tokens one EX battle plus resulting NM battles reward
let ex_value = (function(bosses) {
let gained_meat = 0;
let gained_honor = 0;
let gained_tokens = 0;
for (let i = 0; i < bosses.length; i++) {
let boss = bosses[i];
if (boss.ratio == 0) continue;
if (boss.meat <= 0) continue;
gained_meat = boss.meat;
gained_honor = boss.honor;
gained_tokens = boss.tokens;
}
for (let i = 0; i < bosses.length; i++) {
let boss = bosses[i];
if (boss.meat >= 0) continue;
let used_meat = gained_meat * boss.percent;
let meat_ratio = used_meat / Math.abs(boss.meat);
gained_tokens += boss.tokens * meat_ratio;
gained_honor += boss.honor * meat_ratio;
}
return {
meat: gained_meat,
honor: gained_honor,
tokens: gained_tokens,
};
});
// Calculate static values
let update_calc = (function() {
console.time("gw token calc");
let bosses = get_bosses();
let options = get_options();
let ex = ex_value(bosses);
// How much is our current supply of meat worth?
let stock_tokens = 0;
let stock_honor = 0;
for (let i = 0; i < bosses.length; i++) {
let boss = bosses[i];
if (boss.meat >= 0) continue;
if (boss.ratio == 0) continue;
let fights = Math.floor((boss.percent * options.meat_current) / Math.abs(boss.meat));
//console.log(boss.ratio, options.meat_current, fights);
stock_tokens += fights * boss.tokens;
stock_honor += fights * boss.honor;
}
// How many ex to get enough tokens
let current_box = token_boxes[Math.max(0, options.box_current)];
let current_tokens = current_box.total - current_box.tokens + options.token_current + Math.floor(options.honor_current / 16667);
let target_box = token_boxes[Math.min(250, options.box_target)];
let target_tokens = target_box.total;
let remaining_tokens = target_tokens - stock_tokens - current_tokens;
let token_fights = Math.ceil(remaining_tokens / ex.tokens);
// How many ex to get enough honor
let remaining_honor = options.honor_target - stock_honor - options.honor_current;
let honor_fights = Math.ceil(remaining_honor / ex.honor);
let ex_fights = Math.max(token_fights, honor_fights);
// The amount of meat we'll have from stock and ex fights
let available_meat = Math.floor(ex_fights * ex.meat + options.meat_current);
let remaining_meat = available_meat;
let consumed_meat = 0;
for (let i = bosses.length-1; i >= 0; i--) {
let boss = bosses[i];
boss.fights = 0;
boss.tokens_gained = 0;
boss.honor_gained = 0;
boss.pots_spent = 0;
if (boss.meat >= 0) continue;
if (boss.ratio == 0) continue;
boss.fights = Math.round(available_meat * boss.percent / Math.abs(boss.meat))
consumed_meat += boss.fights * Math.abs(boss.meat);
}
for (let i = 0; i < bosses.length; i++) {
let boss = bosses[i];
if ((boss.meat <= 0) || (boss.ratio <= 0)) continue;
boss.fights = Math.max(0, Math.ceil((consumed_meat - options.meat_current) / boss.meat));
}
for (let i = 0; i < bosses.length; i++) {
let boss = bosses[i];
boss.meat_flow = boss.fights * boss.meat;
}
let sum_fights = 0;
let sum_meat = options.meat_current;
let sum_tokens = options.token_current + Math.floor(options.honor_current / 16667);
let sum_honor = options.honor_current;
let sum_pots = 0;
let sum_slow = 0;
let sum_fast = 0;
document.querySelector('td#now_meat_sum').innerHTML = sum_meat.toLocaleString();
document.querySelector('span#now_tokens').innerHTML = sum_tokens.toLocaleString();
document.querySelector('td#now_honor_sum').innerHTML = sum_honor.toLocaleString();
for (let i = 0; i < bosses.length; i++) {
let boss = bosses[i];
boss.tokens_gained = Math.floor(boss.fights * boss.tokens);
boss.honor_gained = Math.floor(boss.fights * boss.honor);
boss.pots_spent = boss.fights * (boss.ap / 75);
boss.time_fast = boss.fights * (boss.pace_fast / 60);
boss.time_slow = boss.fights * (boss.pace_slow / 60);
sum_fights += boss.fights;
sum_meat += boss.meat_flow;
sum_tokens += boss.tokens_gained;
sum_honor += boss.honor_gained;
sum_pots += boss.pots_spent;
sum_slow += boss.time_slow;
sum_fast += boss.time_fast;
document.querySelector('td#'+boss.ix+'_battles').innerHTML = boss.fights.toLocaleString();
document.querySelector('td#'+boss.ix+'_meat_sum').innerHTML = boss.meat_flow.toLocaleString();
document.querySelector('td#'+boss.ix+'_tokens').innerHTML = boss.tokens_gained.toLocaleString();
document.querySelector('td#'+boss.ix+'_honor_sum').innerHTML = boss.honor_gained.toLocaleString();
document.querySelector('td#'+boss.ix+'_pots').innerHTML = boss.pots_spent.toFixed(1);
document.querySelector('td#'+boss.ix+'_time_slow').innerHTML = boss.time_slow.toFixed(1) + 'h';
document.querySelector('td#'+boss.ix+'_time_fast').innerHTML = boss.time_fast.toFixed(1) + 'h';
}
document.querySelector('td#total_battles').innerHTML = sum_fights.toLocaleString();
document.querySelector('#total_meat').innerHTML = sum_meat.toLocaleString();
document.querySelector('td#total_tokens').innerHTML = sum_tokens.toLocaleString();
document.querySelector('td#total_honor').innerHTML = sum_honor.toLocaleString();
document.querySelector('td#total_pots').innerHTML = sum_pots.toFixed(1);
document.querySelector('td#total_time_slow').innerHTML = sum_slow.toFixed(1) + 'h';
document.querySelector('td#total_time_fast').innerHTML = sum_fast.toFixed(1) + 'h';
document.querySelector('#total_meat').style.color = (sum_meat > 1000 ? 'red' : (sum_meat > 50 ? 'orange' : 'green'));
console.timeEnd("gw token calc");
});
let inputs = document.querySelectorAll('.gw-calc select, .gw-calc input');
inputs.forEach(function(input) {
input.addEventListener('change', function(event) { update_calc(); });
});
update_calc();
})();
</script>