Skip to content

Instantly share code, notes, and snippets.

@Erquint
Last active September 11, 2020 10:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Erquint/5ed7be3f1c62c606d7c514deec4d091d to your computer and use it in GitHub Desktop.
Save Erquint/5ed7be3f1c62c606d7c514deec4d091d to your computer and use it in GitHub Desktop.
Extends The Cycle Wiki Weapons Calculator by Silarious and ArtemusMaximus with extra metrics one might find useful for assessing gunfeel and realistic DPS output beyond one magazine. Install using the following link: https://gist.github.com/Erquint/5ed7be3f1c62c606d7c514deec4d091d/raw/CycleWikiCalcExtender.user.js
// ==UserScript==
// @name CycleWikiCalc Extender
// @description Extends The Cycle Wiki Weapons Calculator by Silarious and ArtemusMaximus with extra metrics one might find useful for assessing gunfeel and realistic DPS output beyond one magazine.
// @version 1.2
// @namespace gness.na@gmail.com
// @author https://gist.github.com/Erquint
// @homepageURL https://gist.github.com/Erquint/5ed7be3f1c62c606d7c514deec4d091d
// @updateURL https://gist.github.com/Erquint/5ed7be3f1c62c606d7c514deec4d091d/raw/CycleWikiCalcExtender.user.js
// @downloadURL https://gist.github.com/Erquint/5ed7be3f1c62c606d7c514deec4d091d/raw/CycleWikiCalcExtender.user.js
// @match http*://thecycle.wiki/apps/calculator/
// @run-at document-end
// @inject-into page
// @noframes
// @grant none
// ==/UserScript==
/*
try {
Array.from(document.getElementsByClassName('hidden')).forEach(e => e.classList.length == 1 ? e.removeAttribute('class') : e.classList.remove('hidden'));
document.getElementById('hidden').removeAttribute("id");
} catch (e) {};
*/
let extra = {};
function calcExtra() {
let stock = document.getElementById('weapons_selector')
.selectedOptions[0].attributes;
let burstinterval = parseFloat(stock.m_burstinterval.value);
let amountofburst = parseInt(stock.m_amountofburst.value);
(amountofburst < 0) && (amountofburst = 0);
let spinuptime = parseFloat(
document.getElementById('spinupTime2').textContent);
let reloadtime = parseFloat(
document.getElementById('reloadTime2').textContent);
let ammoinclip = parseFloat(
document.getElementById('magSize2').textContent);
let refiretime = parseFloat(
document.getElementById('refireTime2').textContent);
let dps = parseFloat(document.getElementById('damageDPS2').textContent);
let upgradelevel = (document.querySelector('select#upg_level_selector')
.selectedIndex);
Array.from(document.getElementById('Selected_attr').children).filter(e =>
/burst/i.test(e.attributes.m_attribute.value)).map(e =>
e.attributes).forEach(e => {
let value = e.m_modifiervalue.value;
switch(e.m_attribute.value) {
case 'WeaponBurstCount':
switch(e.m_modifiertype.value) {
case 'Override':
amountofburst = parseInt(value);
break;
case 'Additive':
amountofburst += parseInt(value);
break;
};
break;
case 'WeaponBurstInterval':
switch(e.m_modifiertype.value) {
case 'Override':
burstinterval = parseFloat(value);
break;
case 'Multiplicitive_PreAdd':
burstinterval *= parseFloat(value);
break;
};
break;
};
});
let burst = amountofburst > 0 ? (parseInt(amountofburst) + 1) : false;
let triggerCycletime = amountofburst * burstinterval + refiretime;
let triggerCyclesPerMag = ammoinclip / (amountofburst + 1);
let triggersPerMag = Math.ceil(triggerCyclesPerMag);
let magUptime = triggerCyclesPerMag * triggerCycletime;
let magDowntime = reloadtime + (burst ?
(triggersPerMag * spinuptime) : spinuptime);
let magCycletime = magUptime + magDowntime;
let uptimeRatio = magUptime / magCycletime;
let adjustedDPS = dps * uptimeRatio;
console.log('ExtraDebug:');
console.log({
burstinterval: burstinterval,
amountofburst: amountofburst,
spinuptime: spinuptime,
reloadtime: reloadtime,
ammoinclip: ammoinclip,
refiretime: refiretime,
dps: dps,
amountofburst: amountofburst,
burstinterval: burstinterval
});
extra = {
upgradelevel: upgradelevel,
burst: burst,
triggerCyclesPerMag: triggerCyclesPerMag,
triggersPerMag: triggersPerMag,
triggerCycletime: triggerCycletime,
magUptime: magUptime,
magDowntime: magDowntime,
magCycletime: magCycletime,
uptimeRatio: uptimeRatio,
adjustedDPS: adjustedDPS
};
};
function layoutMainExtra() {
try {
Array.from(document.getElementsByClassName('extra')).forEach(e =>
e.remove());
} catch(e) {};
let tdElement = document.createElement('td');
tdElement.setAttribute('colspan', 4);
tdElement.style.textAlign = 'center';
tdElement.textContent = 'Extra Stats';
let trElement = document.createElement('tr');
trElement.className = 'extra';
trElement.appendChild(tdElement);
let mainTable = document.getElementById('dmgValueMain').parentNode;
mainTable.appendChild(trElement);
mainTable.appendChild(
mainExtraRow('Burst', extra.burst));
mainTable.appendChild(
mainExtraRow('Triggers/Mag', extra.triggersPerMag));
mainTable.appendChild(
mainExtraRow('Trigger Cycles/Mag', (extra.triggerCyclesPerMag % 1 == 0) ?
extra.triggerCyclesPerMag : extra.triggerCyclesPerMag.toFixed(2)));
mainTable.appendChild(
mainExtraRow('Trigger Cycletime', extra.triggerCycletime.toFixed(2)));
mainTable.appendChild(
mainExtraRow('Mag Uptime', extra.magUptime.toFixed(2)));
mainTable.appendChild(
mainExtraRow('Mag Downtime', extra.magDowntime.toFixed(2)));
mainTable.appendChild(
mainExtraRow('Mag Cycletime', extra.magCycletime.toFixed(2)));
mainTable.appendChild(
mainExtraRow('Uptime Ratio', extra.uptimeRatio.toFixed(2)));
mainTable.appendChild(
mainExtraRow('Uptime-adjusted DPS', extra.adjustedDPS.toFixed(2)));
};
function mainExtraRow(k, v) {
trElement = document.createElement('tr');
trElement.className = 'extra';
tdElement = document.createElement('td');
tdElement.className = 'td2';
tdElement.textContent = k;
trElement.appendChild(tdElement);
tdElement = document.createElement('td');
tdElement.setAttribute('colspan', 3);
tdElement.style.textAlign = 'center';
tdElement.className = 'td2';
tdElement.textContent = v;
trElement.appendChild(tdElement);
return trElement;
};
function updateMainExtra() {
calcExtra();
layoutMainExtra();
};
function initializeExtra() {
updateMainExtra();
headerCompExtra();
};
document.getElementById('weapons_selector').onchange = (e => {
weaponPicker();
updateMainExtra();
});
document.getElementById('SLOT1').onchange = (e => {
fillAttributes('SLOT1');
updateMainExtra();
});
document.getElementById('SLOT2').onchange = (e => {
fillAttributes('SLOT2');
updateMainExtra();
});
document.getElementById('SLOT3').onchange = (e => {
fillAttributes('SLOT3');
updateMainExtra();
});
document.getElementById('SLOT4').onchange = (e => {
fillAttributes('SLOT4');
updateMainExtra();
});
document.getElementById('upg_level_selector').onchange = (e => {
fillUpgAttr();
updateMainExtra();
});
document.getElementById('target_selector').onchange = (e => {
RecalculateResults();
updateMainExtra();
});
document.querySelector('input[value="Reset Variables"]').onclick = (e => {
resetSliders();
updateMainExtra();
});
document.querySelector('input[value="Reset Mod Selection"]').onclick = (e => {
resetMods();
updateMainExtra();
});
/*
// Range, accuracy, headshot and enemy health are not supported yet,
// because I don't care.
document.getElementById('distance-box').onchange = (e => {
distanceLimit(this);
RecalculateResults();
updateMainExtra();
});
document.getElementById('accuracy-box').onchange = (e => {
accuracyLimit(this);
RecalculateResults();
updateMainExtra();
});
document.getElementById('HSaccuracy-box').onchange = (e => {
accuracyLimit(this);
RecalculateResults();
updateMainExtra();
});
document.getElementById('EnemyHealth-box').onchange = (e => {
healthLimit(this);
RecalculateResults();
updateMainExtra();
});
*/
initializeExtra();
function headerCompExtra() {
let tdElement = document.createElement('td');
// tdElement.style.textAlign = 'center';
tdElement.textContent = 'Extra Stats';
let trElement = document.createElement('tr');
trElement.className = 'extraPermHeader';
trElement.appendChild(tdElement);
let compTable = document.getElementById('tblCompare').firstElementChild;
compTable.appendChild(trElement);
compTable.appendChild(headerCompExtraRow('Upgrade Level'));
compTable.appendChild(headerCompExtraRow('Burst'));
compTable.appendChild(headerCompExtraRow('Triggers/Mag'));
compTable.appendChild(headerCompExtraRow('Trigger Cycles/Mag'));
compTable.appendChild(headerCompExtraRow('Trigger Cycletime'));
compTable.appendChild(headerCompExtraRow('Mag Uptime'));
compTable.appendChild(headerCompExtraRow('Mag Downtime'));
compTable.appendChild(headerCompExtraRow('Mag Cycletime'));
compTable.appendChild(headerCompExtraRow('Uptime Ratio'));
compTable.appendChild(headerCompExtraRow('Uptime-adjusted DPS'));
};
function headerCompExtraRow(v) {
let tdElement = document.createElement('td');
tdElement.className = 'td2';
tdElement.textContent = v;
let trElement = document.createElement('tr');
trElement.className = 'td2 extraPerm';
trElement.appendChild(tdElement);
return trElement;
};
function layoutCompExtra() {
let column = [];
Array.from(document.getElementsByClassName('extraPerm')).forEach(e => {
let tdElement = document.createElement('td');
tdElement.className = 'td2';
column.push(e.appendChild(tdElement));
});
column[0].textContent = extra.upgradelevel;
column[1].textContent = extra.burst;
column[2].textContent = extra.triggersPerMag;
column[3].textContent = (extra.triggerCyclesPerMag % 1 == 0) ?
extra.triggerCyclesPerMag : extra.triggerCyclesPerMag.toFixed(2);
column[4].textContent = extra.triggerCycletime.toFixed(2);
column[5].textContent = extra.magUptime.toFixed(2);
column[6].textContent = extra.magDowntime.toFixed(2);
column[7].textContent = extra.magCycletime.toFixed(2);
column[8].textContent = extra.uptimeRatio.toFixed(2);
column[9].textContent = extra.adjustedDPS.toFixed(2);
let rows = [];
Array.from(document.getElementsByClassName('extraPerm')).forEach(e =>
rows.push(Array.from(e.children).filter((e, i) => (i > 0)))
);
rows.forEach(e => e.forEach(e => e.style.color = 'white'));
rows.forEach((e, i) => {
let colors = [6].includes(i) ? ['lime', 'red'] : ['red', 'lime'];
let values = e.map(e => e.textContent);
let min = Math.min(...values);
let max = Math.max(...values);
e.forEach(e => {
switch(parseFloat(e.textContent)) {
case min:
e.style.color = colors[0];
break;
case max:
e.style.color = colors[1];
break;
};
});
});
};
document.getElementById('btnAddBuild').onclick = (e => {
AddCompareData();
layoutCompExtra();
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment