nyx/util/functions/common.js

844 lines
26 KiB
JavaScript
Raw Permalink Normal View History

const data = require("../Data/data.json");
const QuickChart = require("quickchart-js");
const nmDt = require("../Data/aliases.json");
const weaponActualName = nmDt.weaponActualName;
const weaponAlliasName = nmDt.weaponAlliasName;
Object.defineProperty(String.prototype, "Simplify", {
2022-01-25 16:07:38 +01:00
// Function to remove all characters except 0-9 and a-z
2022-01-27 01:33:56 +01:00
// Eg "AK-47" -> "ak47"
2022-01-23 02:06:11 +01:00
value: function Simplify() {
return this.toLowerCase().replace(/[^0-9a-z]/g, "");
},
writable: true,
configurable: true,
});
Object.defineProperty(Number.prototype, "IsPositive", {
2022-01-25 16:07:38 +01:00
// Function to check the number is positive or not
2022-01-23 02:06:11 +01:00
value: function IsPositive() {
2022-01-25 16:07:38 +01:00
if (this > 0) return true;
else return false;
2022-01-23 02:06:11 +01:00
},
writable: true,
configurable: true,
});
Object.defineProperty(Number.prototype, "IsNegative", {
2022-01-25 16:07:38 +01:00
// Function to check the number is negative or not
2022-01-23 02:06:11 +01:00
value: function IsNegative() {
2022-01-25 16:07:38 +01:00
if (this < 0) return true;
else return false;
2022-01-23 02:06:11 +01:00
},
writable: true,
configurable: true,
});
Object.defineProperty(Number.prototype, "ToBool", {
2022-01-25 16:07:38 +01:00
// Function to check the number is one or not
2022-01-23 02:06:11 +01:00
value: function ToBool() {
2022-01-25 16:07:38 +01:00
if (this == 1) return true;
else return false;
2022-01-23 02:06:11 +01:00
},
writable: true,
configurable: true,
});
Object.defineProperty(Number.prototype, "PlusHL", {
2022-01-23 02:06:11 +01:00
value: function PlusHL() {
if (this.toString()[0] == "-") {
return parseFloat(this.toFixed(2)).toString();
}
2022-01-25 16:07:38 +01:00
return `+${parseFloat(this.toFixed(2)).toString()}`;
2022-01-23 02:06:11 +01:00
},
writable: true,
configurable: true,
});
2022-01-25 16:07:38 +01:00
/* Function to fix the input statement */
function inpFixer(inpmsg) {
const parts = PartSpliter(inpmsg);
2022-01-25 16:07:38 +01:00
// parts will be an array
//eg: ["fennec", "akimbo, mono"]
2022-01-23 02:06:11 +01:00
nmDt.attachmentAlliasName[0].map((x, i) =>
2022-01-25 16:07:38 +01:00
// x is the content of each index, i is the number of each index
2022-01-23 02:06:11 +01:00
x.map(y => {
if (parts[0].startsWith(y + " ") || parts[0].endsWith(" " + y)) {
inpmsg =
parts[0].replace(y + " ", "").replace(" " + y, "") +
(parts[1] ? ", " : " + ") +
nmDt.attachmentActualName[0][i];
2022-01-23 02:06:11 +01:00
}
})
);
2022-01-25 16:07:38 +01:00
// so it fking only fix akimbo and stopping power wtf
2022-01-23 02:06:11 +01:00
return inpmsg;
}
// Function to split weapon name and the attachments from the input statement
function PartSpliter(inpmsg) {
2022-01-23 02:06:11 +01:00
if (inpmsg.includes(" + ")) {
2022-01-25 16:07:38 +01:00
// If the input statement has multiple attachments joined by "+", split them and output them as an array of strings [0] is the weapon name, [1] is the attachments
// Eg: "M4A1 + Silencer + Flashlight" -> ["M4A1", "Silencer + Flashlight"]
2022-01-23 02:06:11 +01:00
const out = inpmsg
.split(" + ")
.map(x => x.split("+"))
.flat();
return [out.shift(), out.join(", ")];
}
2022-01-25 16:07:38 +01:00
// If there is only one attachment, output it as an array of strings [0] is the weapon name, [1] is the attachment
// Eg: "M4A1 with Flashlight" -> ["M4A1", "Flashlight"]
2022-01-23 02:06:11 +01:00
return inpmsg.split(" with ");
}
function hasAttachments(inpmsg) {
2022-01-23 02:06:11 +01:00
inpmsg = inpFixer(inpmsg);
// If the input statement has multiple attachments joined by "+" or "with", split them and output them as an array of strings [0] is the weapon name, [1] is the attachments
2022-01-23 02:06:11 +01:00
if (
inpmsg.split(" with ").filter(x => x.Simplify()).length > 1 ||
inpmsg.split(" + ").filter(x => x.Simplify()).length > 1
2022-01-23 02:06:11 +01:00
) {
return true;
}
return false;
}
function isolator(inpmsg) {
return PartSpliter(inpFixer(inpmsg));
}
2022-01-27 22:47:50 +01:00
// identifying the weapon
function weaponIdentifier(inpmsg) {
2022-01-23 02:06:11 +01:00
const inpWeaponName = isolator(inpmsg)[0];
2022-01-27 22:47:50 +01:00
// ["ak", "mono"] -> inpWeaponName: "ak"
// if weapon name is too short, return the error
2022-01-23 02:06:11 +01:00
if (inpWeaponName.length < 2) {
return inpmsg.trim().length
2022-01-25 16:07:38 +01:00
? `The name ${inpmsg.trim()} is too short.`
: "There isn't any weapon name.";
2022-01-23 02:06:11 +01:00
}
let probableWeapons = [];
2022-01-27 01:33:56 +01:00
// Loop through all the weapons to find the probable weapons
// Eg: "ak"
2022-01-23 02:06:11 +01:00
for (let i = 0; i < data.cguns.length; i++) {
if (inpWeaponName.Simplify() == data.cguns[i].gunname.Simplify()) {
2022-01-27 22:47:50 +01:00
// if the simplified name of the weapon is the same as the weapon name in the database, return the only one stats object
2022-01-23 02:06:11 +01:00
return JSON.parse(JSON.stringify(data.cguns[i]));
} else if (
data.cguns[i].gunname.Simplify().includes(inpWeaponName.Simplify())
) {
2022-01-27 22:47:50 +01:00
// If the weapon name is included in the actual name of the weapon
// push the weapon to the probableWeapons array
2022-01-23 02:06:11 +01:00
probableWeapons.push(i);
}
}
// if there is only one probable weapon, mean the gun has already been identified
2022-01-23 02:06:11 +01:00
if (probableWeapons.length == 1) {
2022-01-27 22:47:50 +01:00
// if there is only one probable weapon, return the only one stats object
2022-01-23 02:06:11 +01:00
return JSON.parse(JSON.stringify(data.cguns[probableWeapons[0]]));
}
// continue loop when there is no identified weapons or there are more than one identfied weaponds
2022-01-27 22:47:50 +01:00
// detecting aliases
// getting total number of weapons that had added aliases
2022-01-23 02:06:11 +01:00
for (let i = 0; i < weaponAlliasName.length; i++) {
2022-01-27 22:47:50 +01:00
// getting the number of aliases of each weapon
2022-01-23 02:06:11 +01:00
for (let j = 0; j < weaponAlliasName[i].length; j++) {
2022-01-27 22:47:50 +01:00
// weaponAliases[i][j] is the each alias of each weapon
// finding if simplified alias is same as input weapon name
2022-01-23 02:06:11 +01:00
if (weaponAlliasName[i][j].Simplify() == inpWeaponName.Simplify()) {
2022-01-27 22:47:50 +01:00
// if simplified alias is same as input weapon name
// eg "mow" == "mow", run the loop
2022-01-23 02:06:11 +01:00
for (let i2 = 0; i2 < data.cguns.length; i2++) {
2022-01-27 22:47:50 +01:00
if (weaponActualName[i] == data.cguns[i2].gunname) {
// use the actual name of the weapon to find the weapon
2022-01-23 02:06:11 +01:00
return JSON.parse(JSON.stringify(data.cguns[i2]));
}
}
}
}
}
2022-01-27 22:47:50 +01:00
// removing duplicates in the array
2022-01-23 02:06:11 +01:00
probableWeapons = [...new Set(probableWeapons)];
// if there is only one probable weapon, return the only one stats object
if (probableWeapons.length == 1)
2022-01-23 02:06:11 +01:00
return JSON.parse(JSON.stringify(data.cguns[probableWeapons[0]]));
else if (probableWeapons.length > 1) {
2022-01-27 22:47:50 +01:00
// reply with the question of probable weapons
2022-01-25 16:07:38 +01:00
return `Did you mean ${probableWeapons
.map(x => data.cguns[x].gunname)
.reduce((out, x, i) =>
[out, x].join(i === probableWeapons.length - 1 ? "` or `" : "`, `")
)}
?`;
} else return `Couldn't identify the weapon: "${inpWeaponName}"`;
}
// identifying attachments and return array or error
2022-02-01 01:29:22 +01:00
function attachmentsIdentifier(inpmsg, gun) {
if (!hasAttachments(inpmsg)) return [];
// no need for isolator because using slash commands, we get individual attachment
let inputAttachmentsNames = isolator(inpmsg)[1]
.split(/ & |, |,| and /)
.filter(x => x);
2022-02-01 01:29:22 +01:00
const tooSmall = inputAttachmentsNames.filter(x => x.length < 3);
2022-02-01 01:29:22 +01:00
// filter all elements thats shorter than 2 characters
inputAttachmentsNames = inputAttachmentsNames.filter(x => !(x.length < 3));
let errorMsgs = "",
errors = [],
unidentifined = [];
2022-01-25 16:07:38 +01:00
if (inputAttachmentsNames.length == 0)
errorMsgs += "\nAttachments are missing!\n";
2022-02-01 01:29:22 +01:00
// if (inputAttachmentsNames.length >= 10) return "Cocaineeeeee"; ?????????
// Can directly use args[] to return, no need for isolator, partExtractor, inpFixer
const splitAttachmentsDataName = [],
outAttachments = [];
2022-02-01 01:29:22 +01:00
for (let i = 0; i < gun.aments.length; i++) {
2022-02-02 21:40:53 +01:00
// Eg: "Stippled Grip Tape" -> ["Stippled", "Grip", "Tape"]
splitAttachmentsDataName.push([
...new Set(
2022-02-01 01:29:22 +01:00
gun.aments[i].name
.split(" ")
.filter(x => x)
.map(x => x.trim())
),
]);
2022-02-02 21:40:53 +01:00
// splitAttachmentsDataName[i] = ["Stippled", "Grip", "Tape"]
for (let j = 0; j < splitAttachmentsDataName[i].length; j++) {
2022-02-02 21:40:53 +01:00
// simplify the attachments name
// Eg: ["Stippled", "Grip", "Tape"] -> ["stippled", "grip", "tape"]
splitAttachmentsDataName[i][j] =
splitAttachmentsDataName[i][j].Simplify();
2022-01-23 02:06:11 +01:00
}
}
2022-02-03 12:21:05 +01:00
// inputAttachmentsNames = [["stippled", "grip", "tape"]
2022-01-23 02:06:11 +01:00
for (let i = 0; i < inputAttachmentsNames.length; i++) {
2022-02-03 12:21:05 +01:00
let probables = [];
2022-02-02 21:40:53 +01:00
// loop through all the input attachments and split them into words
2022-01-23 02:06:11 +01:00
var splitInputAttachmentsName = inputAttachmentsNames[i]
.split(" ")
.filter(x => x);
function finder() {
2022-02-02 21:40:53 +01:00
//splitInputAttachmentsName = [["stippled", "grip", "tape"], ["545", "ammo"], ["owc","lazer", "tactical"]]
2022-01-23 02:06:11 +01:00
for (let j = 0; j < splitAttachmentsDataName.length; j++) {
for (let i2 = 0; i2 < splitAttachmentsDataName[j].length; i2++) {
for (let i3 = 0; i3 < splitInputAttachmentsName.length; i3++) {
2022-02-02 21:40:53 +01:00
// if simplified input attachment name is included in the real attachments name
2022-01-23 02:06:11 +01:00
if (
splitAttachmentsDataName[j][i2].includes(
splitInputAttachmentsName[i3].Simplify()
)
) {
2022-02-02 21:40:53 +01:00
// if probables list doesn't include the attachment, push
2022-01-23 02:06:11 +01:00
let probablePushed = false;
for (let i4 = 0; i4 < probables.length; i4++) {
2022-02-03 11:57:59 +01:00
// push another attachment that also probable to the probables list to the same array that identified last loop
// Eg: probables = [ [32]] // as user input mag and first loop it identfified extended mag
// then as it got more possible, it will push large extended mag to the same array -> [ [32,33] ]
2022-01-23 02:06:11 +01:00
if (!probables[i4].includes(j)) {
probables[i4].push(j);
2022-02-03 11:57:59 +01:00
// make it true so that it doesn't push again in the next condition
2022-01-23 02:06:11 +01:00
probablePushed = true;
break;
}
}
2022-02-03 11:57:59 +01:00
// push if the attachment isn't been identified yet
2022-02-02 21:40:53 +01:00
if (!probablePushed) probables.push([j]);
2022-01-23 02:06:11 +01:00
}
}
}
}
}
finder();
2022-02-02 21:40:53 +01:00
// finding magazines attachments
2022-01-23 02:06:11 +01:00
if (
(inputAttachmentsNames[i].includes(" rounds mag") ||
2022-02-03 11:57:59 +01:00
inputAttachmentsNames[i].includes(" round mag") ||
inputAttachmentsNames[i].includes(" round") ||
inputAttachmentsNames[i].includes(" rounds")) &&
inputAttachmentsNames[i].startsWith(
2022-01-23 02:06:11 +01:00
inputAttachmentsNames[i].replace(/\D/g, "")
)
2022-01-23 02:06:11 +01:00
) {
var tmp1 = parseInt(inputAttachmentsNames[i]);
2022-02-03 11:57:59 +01:00
// calculating the sum of number of rounds and see if it matches the input number of rounds
2022-02-01 01:29:22 +01:00
const tmp2 = gun.aments.filter(
2022-01-23 02:06:11 +01:00
x =>
2022-02-01 01:29:22 +01:00
x.type === 8 && x.effects[27] + x.effects[28] + gun.stats[17] === tmp1
2022-01-23 02:06:11 +01:00
);
2022-02-03 11:57:59 +01:00
// push if the magazine is found
2022-01-23 02:06:11 +01:00
if (tmp2.length === 1) {
outAttachments.push(tmp2[0]);
continue;
}
}
2022-02-03 11:57:59 +01:00
// if probables is empty or there is more than one identified attachment
2022-01-23 02:06:11 +01:00
if (
probables.length === 0 ||
probables[probables.length - 1].length !== 1 ||
probables.length < splitInputAttachmentsName.length
2022-01-23 02:06:11 +01:00
) {
2022-02-03 12:21:05 +01:00
// empty probables as can't indentify the attachment
2022-01-23 02:06:11 +01:00
probables = [];
2022-02-03 11:57:59 +01:00
// the splitInputAttachmentsName isn't simplified pls rmb
2022-02-03 12:21:05 +01:00
splitInputAttachmentsName.map((x, i5) => {
2022-02-03 11:57:59 +01:00
// finding aliases
2022-02-03 12:21:05 +01:00
nmDt.attachmentAlliasName[1].map((y, i6) => {
2022-01-23 02:06:11 +01:00
y.map(z => {
2022-02-03 12:21:05 +01:00
if (z.Simplify().includes(x.Simplify())) {
2022-01-23 02:06:11 +01:00
splitInputAttachmentsName[i5] = nmDt.attachmentActualName[1][i6];
}
2022-02-03 12:21:05 +01:00
});
});
});
// simple iteration to make the array again
2022-01-23 02:06:11 +01:00
splitInputAttachmentsName = splitInputAttachmentsName
.join(" ")
.split(" ")
.filter(x => x);
2022-02-03 12:21:05 +01:00
// find one more time as we do aliases already
2022-01-23 02:06:11 +01:00
finder();
if (
probables.length === 0 ||
probables[probables.length - 1].length !== 1 ||
probables.length < splitInputAttachmentsName.length
2022-01-23 02:06:11 +01:00
) {
probables = [];
splitInputAttachmentsName = inputAttachmentsNames[i]
.split(" ")
.filter(x => x);
finder();
}
}
if (probables.length === 0) {
2022-02-03 12:21:05 +01:00
// push to unidentifined list as can't be identified after serveral times
2022-01-23 02:06:11 +01:00
unidentifined.push(inputAttachmentsNames[i]);
continue;
}
2022-02-03 12:21:05 +01:00
// curr is the most probable attachment
2022-01-23 02:06:11 +01:00
var curr = probables[probables.length - 1];
const temp1 = probables[probables.length - 1].filter(
2022-02-01 01:29:22 +01:00
x => gun.aments[x].name.Simplify() == inputAttachmentsNames[i].Simplify()
2022-01-23 02:06:11 +01:00
);
2022-02-03 23:08:59 +01:00
// see if the length of the array is the same or not
// Eg: splitAttachmentsDataName[x] = ["stippled", "grip", "tape"] and splitInputAttachmentsName = ["stippled", "grip", "tape"]
// then it it equal
2022-01-23 02:06:11 +01:00
const temp2 = probables[probables.length - 1].filter(
x =>
splitAttachmentsDataName[x].length == splitInputAttachmentsName.length
);
2022-02-03 23:08:59 +01:00
// if found probable, push it
if (temp1.length === 1 && temp2.length !== 1) {
2022-01-23 02:06:11 +01:00
probables.push([temp1]);
} else if (temp1.length !== 1 && temp2.length === 1) {
probables.push([temp2]);
} else if (
temp1.length === 1 &&
temp2.length === 1 &&
temp1[0] == temp2[0]
2022-01-23 02:06:11 +01:00
) {
probables.push([temp1]);
}
if (
probables[probables.length - 1].length != 1 ||
probables.length < splitInputAttachmentsName.length
2022-01-23 02:06:11 +01:00
) {
2022-02-08 13:10:53 +01:00
// ask the user if he means xxx = which attachment
2022-01-23 02:06:11 +01:00
errors.push(
2022-02-03 23:08:59 +01:00
`\`
${curr
2022-02-01 01:29:22 +01:00
.map(x => gun.aments[x].name)
2022-01-23 02:06:11 +01:00
.reduce((out, x, i) =>
[out, x].join(i === curr.length - 1 ? "` or `" : "`, `")
2022-02-03 23:08:59 +01:00
)} +
\` by \`"
${inputAttachmentsNames[i]}
"\``
2022-01-23 02:06:11 +01:00
);
}
2022-02-08 13:10:53 +01:00
// push the attachment to the output list
2022-02-01 01:29:22 +01:00
outAttachments.push(gun.aments[probables[probables.length - 1][0]]);
2022-01-23 02:06:11 +01:00
}
2022-02-04 12:50:08 +01:00
2022-01-23 02:06:11 +01:00
const outAttachmentsTypes = outAttachments.map(x => x.type - 1),
t1 = outAttachments
.map(x => x.effects[35])
.reduce((t, x) => t + x, 0)
.toString()
.padStart(11, "0")
.toString()
.split("")
.map((x, i) =>
parseInt(x) !== 0 && outAttachmentsTypes.includes(i) ? parseInt(i) : -1
)
.filter(x => x !== -1);
errorMsgs += t1.length
? "Can't equip `" +
t1
2022-01-23 02:06:11 +01:00
.map(x => data.attachmentTypes[x])
.reduce((out, x, i, a) =>
[out, x].join(i === a.length - 1 ? "` or `" : "`, `")
) +
"` with " +
outAttachments
2022-01-23 02:06:11 +01:00
.filter(x => x.effects[35])
.map(x => x.name)
.reduce((out, x, i, a) =>
[out, x].join(i === a.length - 1 ? " and " : ", ")
)
: "";
2022-01-25 16:07:38 +01:00
errorMsgs += errors.length ? `\nDid you mean ${errors.join(";\n")}?\n` : "";
2022-01-23 02:06:11 +01:00
errorMsgs += unidentifined.length
2022-01-25 16:07:38 +01:00
? `\nCouldn't identify the attachment(${
unidentifined.length === 1 ? "" : "s"
}): \`"${unidentifined.join('"`, `"')}"\`\n`
2022-01-23 02:06:11 +01:00
: "";
errorMsgs +=
outAttachments.length > 5 ? "\nCan't equip more than 5 attachments!\n" : "";
2022-01-23 02:06:11 +01:00
errorMsgs += outAttachments.filter((x, i, a) => a.indexOf(x) !== i).length
? "\nMultiple of same attachments found!\n"
: "";
errorMsgs += outAttachments
.map(x => x.type)
.filter((x, i, a) => a.indexOf(x) !== i).length
? "\nMultiple of attachments the same type found!\n"
: "";
errorMsgs += tooSmall.length
? "\nThe name" +
(tooSmall.length === 1 ? "" : "s") +
': `"' +
tooSmall.reduce((out, x, i) =>
2022-01-23 02:06:11 +01:00
[out, x].join(i === curr.length - 1 ? '"` and `"' : '"`, `"')
) +
'"` ' +
(tooSmall.length === 1 ? "is" : "are") +
" too short\n"
2022-01-23 02:06:11 +01:00
: "";
return errorMsgs ? errorMsgs.trim() : outAttachments;
}
// console.log(attachmentsIdentifier("chopper with heavy handle, red sight, granulated", data.cguns[38].aments)); makeError();
// console.log(attachmentsIdentifier("ak + 5mw lazer", data.cguns[0].aments)); makeError();
// console.log(attachmentsIdentifier("117 + 40 round mag", data.cguns[0].aments, data.cguns[0].stats)); makeError();
// console.log(attachmentsIdentifier("117 + rtc muzzle brake, rubberized griptape, tac lazer sight, 40 round mag, no stock", data.cguns[1].aments)); makeError();
2022-02-05 02:35:26 +01:00
// console.log(attachmentsIdentifier("47 + stipplied grip tape", data.cguns[0]));
// makeError();
function damageHandler(
2022-01-23 02:06:11 +01:00
currDmgs,
currRngs,
damageMulti,
hp,
tbs,
tbb,
bib,
pellets
) {
2022-01-23 02:06:11 +01:00
currDmgs = [...currDmgs];
currRngs = [...currRngs];
currRngs = currRngs.filter(x => x < 100).map(x => Math.round(x));
currDmgs.length = currRngs.length + 1;
currDmgs = currDmgs.map(x => Math.round(x * damageMulti));
let currSTKs = currDmgs.map(x => stk(x)),
currTTKs = currDmgs.map(x => ttk(x)),
currPDmg = null,
n = Math.max(...currTTKs.map(x => x.toString().length));
n = n < 3 ? 3 : n;
function worker1(inp) {
return inp.map(x => x.toString().padStart(n)).join(" -- ") + "\n";
}
function worker2(inp) {
return (
"".padStart(n + 1) +
inp.map(x => x.toString().padStart(2)).join("".padStart(n + 2)) +
"\n"
2022-01-23 02:06:11 +01:00
);
}
function stk(dmg) {
let out;
if (!pellets) {
out = Math.ceil(hp / dmg);
} else {
out = Math.ceil(hp / (dmg * pellets));
}
out = out == Infinity ? "∞" : out;
return out;
}
function ttk(dmg) {
const stkVal = stk(dmg);
if (stkVal == "∞") {
return stkVal;
}
if (!bib) {
return Math.round((stkVal - 1) * tbs);
}
let out = 0;
if (dmg > 0) {
if (stkVal % bib == 0) {
for (var i = 0; i < Math.floor(stkVal / bib) - 1; i++) {
out += tbs * (bib - 1) + tbb;
}
out = out + tbs * (bib - 1);
} else if (stkVal % bib != 0) {
for (var i = 0; i <= Math.floor(stkVal / bib) - 1; i++) {
out += tbs * (bib - 1) + tbb;
}
for (var i = 0; i < (stkVal % bib) - 1; i++) {
out += tbs;
}
}
out = Math.round(out);
if (out == Infinity) {
return "∞";
}
} else {
out = "No";
}
return out;
}
if (pellets) {
currPDmg = currDmgs.map(x => x + "×" + pellets);
n = Math.max(...currPDmg.map(x => x.toString().length));
}
return (
"```swift\n" +
"Damage : " +
worker1(currPDmg || currDmgs) +
(pellets ? "Total : " + worker1(currDmgs.map(x => x * pellets)) : "") +
"STK : " +
worker1(currSTKs) +
"TTK : " +
worker1(currTTKs) +
"Range : " +
(currRngs.length ? worker2(currRngs) : worker1(["∞"])) +
"```"
2022-01-23 02:06:11 +01:00
);
}
// console.log(damageHandler([30, 25, 20], [10, 20], 1, 100, 60000 / 720, 0, 0)); makeError();
// console.log(damageHandler([ 33, 23 ], [ 39 ], 1, 100, 109.0909090909091, 0, 0 )); makeError();
function recoilHandler(
2022-01-23 02:06:11 +01:00
xRecoil,
yRecoil,
xMultiplier,
yMultiplier,
bulletCount
) {
2022-01-23 02:06:11 +01:00
if (xRecoil.length != yRecoil.length) {
return "err";
}
const recoilLength = xRecoil.length;
if (recoilLength == 0) {
return "none";
}
const recoilPattern = [
{
x: 0,
y: 0,
},
];
let recoilObj;
for (let i = 0; i < bulletCount; i++) {
const xContinuationVal =
xRecoil[recoilLength - 1] - xRecoil[recoilLength - 2];
2022-01-23 02:06:11 +01:00
const yContinuationVal =
yRecoil[recoilLength - 1] - yRecoil[recoilLength - 2];
2022-01-23 02:06:11 +01:00
if (i < recoilLength) {
recoilObj = {
x: xRecoil[i] * (1 + xMultiplier / 100),
y: yRecoil[i] * (1 + yMultiplier / 100),
};
} else {
recoilObj = {
x:
(recoilPattern[recoilPattern.length - 1].x + xContinuationVal) *
xMultiplier,
2022-01-23 02:06:11 +01:00
y:
(recoilPattern[recoilPattern.length - 1].y + yContinuationVal) *
yMultiplier,
2022-01-23 02:06:11 +01:00
};
}
recoilPattern.push(recoilObj);
}
const chart = new QuickChart();
chart
.setConfig({
type: "scatter",
data: {
datasets: [
{
data: recoilPattern,
showLine: true,
fill: false,
pointRadius: 3,
backgroundColor: "rgba(056,205,255,1.00)", // "#38CDFF" fully transparent
borderColor: "rgba(056,205,255,0.75)", // "#38CDFF" 75% transparent
},
],
},
options: {
plugins: {
backgroundImageUrl: "https://i.imgur.com/jFAFaWF.png",
},
legend: {
display: false,
},
scales: {
yAxes: [
{
ticks: {
display: false,
min: 0,
max: 5050,
},
},
],
xAxes: [
{
ticks: {
display: false,
min: -4495,
max: 4495,
},
},
],
},
},
})
.setWidth(1780)
.setHeight(1000);
return chart;
}
function updateStatswithEffects(inpEffects, inpStats) {
2022-01-23 02:06:11 +01:00
const l = inpStats[18] / inpStats[17];
const outStats = [...inpStats];
var inpStatsarr = [1, 2, 5, 11, 14, 15, 20, 21, 22, 26, 27, 31];
var inpEfecsarr = [17, 18, 16, 19, 1, 10, 14, 14, 14, 6, 7, 42]; // Efecs is short for Effects
for (let i = 0; i < inpEffects.length; i++) {
if (inpEffects[inpEfecsarr[i]] != 0) {
outStats[inpStatsarr[i]] *= (inpEffects[inpEfecsarr[i]] + 100) / 100;
}
}
var inpStatsarr = [3, 4, 16, 28, 29, 30];
var inpEfecsarr = [20, 38, 0, 39, 40, 41];
for (let i = 0; i < inpEffects.length; i++) {
if (inpEffects[inpEfecsarr[i]] != 0) {
outStats[inpStatsarr[i]] = inpEffects[inpEfecsarr[i]];
}
}
var inpStatsarr = [0, 17, 25];
var inpEfecsarr = [29, 27, 9];
for (let i = 0; i < inpEffects.length; i++) {
if (inpEffects[inpEfecsarr[i]] != 0) {
outStats[inpStatsarr[i]] += inpEffects[inpEfecsarr[i]];
}
}
if (inpEffects[4] != 0) {
outStats[10] = 11 - (11 - inpStats[10]) * (1 + inpEffects[4] / 100); //
}
if (inpEffects[43] != 0 && inpStats[8] != -1) {
outStats[8] *= (inpEffects[43] + 100) / 100;
}
if (inpEffects[16] != 0) {
outStats[7] *= inpEffects[16] / -100 + 1;
}
outStats[18] = inpStats[17] * l;
return outStats;
}
function attachmentHandler(currEffects, currStats) {
2022-01-23 02:06:11 +01:00
const pos = [],
neg = [],
atr = [];
if (currEffects[0] > currStats[16]) {
pos.push(
currEffects[0] +
"% zoom (+" +
(currEffects[0] - currStats[16]) +
2022-01-23 02:06:11 +01:00
"% zoom)"
);
} else if (currEffects[0] != 0 && currEffects[0] != currStats[16]) {
neg.push(
currEffects[0] +
"% zoom (-" +
(currStats[16] - currEffects[0]) +
2022-01-23 02:06:11 +01:00
"% zoom)"
);
}
if (currEffects[0] != 0 && currStats[16] <= 110) {
atr.push("Easier to Aim");
}
negGood1(1, "ADS time");
negGood1(2, "Vertical Recoil");
negGood1(3, "Horizontal Recoil");
negGood1(4, "Bullet Spread");
negGood1(5, "Moving Bullet Spread");
posGood1(6, "Mobility");
posGood1(7, "ADS Mobility");
negGood1(8, "Recoil when Crouched or Prone");
posGood1(9, "Sprint Mobility");
negGood1(10, "Sprint to Fire Time");
negGood1(11, "Flinch");
negGood1(12, "Hipfire Spread");
posGood1(13, "Damage Range");
negGood1(14, "Reload Time");
posGood1(15, "Headshot Damage");
posGood1(16, "Rate of Fire");
posGood1(17, "Detonation Range");
posGood1(18, "Explosion Radius");
negGood1(19, "Idle Sway");
if (currEffects[20] > currStats[3]) {
pos.push(
currEffects[20].ToString().Replace(".", " ~ ") + " Explosion Damage"
);
} else if (currEffects[20] != 0 && currEffects[20] != currStats[3]) {
neg.push(
currEffects[20].ToString().Replace(".", " ~ ") + " Explosion Damage"
);
}
atrPush3(21, "Visible Laser when not ADS-ed");
atrPush3(22, "Visible Laser when ADS-ed");
atrPush3(23, "Visible Laser");
atrPush3(24, "Silenced Gunfire");
atrPush3(25, "Hidden Muzzle Flash");
posGood2(27, "Rounds/Mag");
posGood2(28, "Rounds/Tube");
posGood2(29, "Pellets per Shot");
posGood2(30, "Damage Over Time");
atrPush3(32, "Reworked ADS");
atrPush3(33, "Faster Melee QTE");
if (currEffects[35]) {
atr.push(
"Can Not use " +
currEffects[35]
2022-01-23 02:06:11 +01:00
.toString()
.padStart(11, "0")
.toString()
.split("")
.map((x, i) => (parseInt(x) !== 0 ? data.attachmentTypes[i] : 0))
.filter(x => x)
);
}
atrPush3(36, "Can't ADS");
if (currEffects[37] != 0) {
atr.push("New Lethality Profile");
}
if (currEffects[38] != 0 && currEffects[38] < currStats[4]) {
pos.push("Turns to " + data.firingModes[currEffects[38] - 1]);
} else if (currEffects[38] != 0 && currEffects[38] != currStats[4]) {
neg.push("Turns to " + data.firingModes[currEffects[38] - 1]);
}
posGood2(39, "Tick Damage");
posGood2(40, "Ticks");
negGood2(41, "ms Tick Interval");
posGood2(42, "Breath Holding Time");
posGood1(43, "Bullet Speed");
if (currEffects[44] == 1) {
atr.push("Higher Penetraion Damage");
} else if (currEffects[44] == -1) {
atr.push("Lower Penetraion Damage");
}
2022-01-25 16:07:38 +01:00
posGood2(45, `Round ${currEffects[45] - 1 ? "s" : ""} in Reserve`);
2022-01-23 02:06:11 +01:00
function posGood1(i, ext) {
if (currEffects[i].IsPositive()) {
pos.push(currEffects[i].PlusHL() + "% " + ext);
} else if (currEffects[i].IsNegative()) {
neg.push(currEffects[i].PlusHL() + "% " + ext);
}
}
function negGood1(i, ext) {
if (currEffects[i].IsNegative()) {
pos.push(currEffects[i].PlusHL() + "% " + ext);
} else if (currEffects[i].IsPositive()) {
neg.push(currEffects[i].PlusHL() + "% " + ext);
}
}
function posGood2(i, ext) {
if (currEffects[i].IsPositive()) {
pos.push(currEffects[i].PlusHL() + " " + ext);
} else if (currEffects[i].IsNegative()) {
neg.push(currEffects[i].PlusHL() + " " + ext);
}
}
function negGood2(i, ext) {
if (currEffects[i].IsNegative()) {
pos.push(currEffects[i].PlusHL() + " " + ext);
} else if (currEffects[i].IsPositive()) {
neg.push(currEffects[i].PlusHL() + " " + ext);
}
}
function atrPush3(i, ext) {
if (currEffects[i].ToBool()) {
atr.push(ext);
}
}
2022-01-25 16:07:38 +01:00
// Return the attributes when there is and use algorithms to join them
2022-01-23 02:06:11 +01:00
return [
pos.length
? {
name: "**Positives:**",
2022-01-25 16:07:38 +01:00
value: `\`\`\`ini\n[${pos.join("]\n[")}]\n\`\`\``,
2022-01-23 02:06:11 +01:00
inline: true,
}
: 0,
neg.length
? {
name: "**Negatives:**",
2022-01-25 16:07:38 +01:00
value: `\`\`\`css\n[${neg.join("]\n[")}]\n\`\`\``,
2022-01-23 02:06:11 +01:00
inline: true,
}
: 0,
atr.length
? {
name: "**Attributes:**",
2022-01-25 16:07:38 +01:00
value: `\`\`\`fix\n[${atr.join("]\n[")}]\n\`\`\``,
2022-01-23 02:06:11 +01:00
}
: 0,
].filter(x => x);
}
function interpretioner(inpAttachments) {
2022-01-23 02:06:11 +01:00
return inpAttachments.length
? " with " + inpAttachments.map(x => x.name).join(", ")
: "";
}
function totaler(inpAttachments) {
2022-01-23 02:06:11 +01:00
const totalEffects = inpAttachments[0].effects;
for (let j = 1; j < inpAttachments.length; j++) {
for (let i2 = 0; i2 < totalEffects.length; i2++) {
totalEffects[i2] += inpAttachments[j].effects[i2];
}
}
return totalEffects;
}
function makeError() {
2022-01-25 16:07:38 +01:00
undefined.split("L");
}
module.exports = {
2022-01-23 02:06:11 +01:00
weaponIdentifier,
attachmentsIdentifier,
recoilHandler,
attachmentHandler,
updateStatswithEffects,
makeError,
interpretioner,
damageHandler,
isolator,
totaler,
hasAttachments,
};