nyx

The first CODM discrod bot -- cath.exe Template
git clone https://codeberg.org/night0721/nyx
Log | Files | Refs | LICENSE

stats.js (7863B)


      1 const common = require("../../util/functions/common");
      2 const data = require("../../util/Data/data.json");
      3 const { EmbedBuilder } = require("discord.js");
      4 
      5 let currGun,
      6   currStats,
      7   currAttachments,
      8   currRecoilArr,
      9   currDRM,
     10   interpretion,
     11   recoilAvailable,
     12   chart,
     13   hasError;
     14 module.exports = {
     15   name: "stats",
     16   description: "Check gun stats",
     17   usage: "(Gun)",
     18   category: "CODM",
     19   options: [
     20     {
     21       type: 3,
     22       name: "gun_name",
     23       description: "Name of the gun",
     24       required: true,
     25       choices: [],
     26     },
     27     {
     28       type: 3,
     29       name: "1st_attchment",
     30       description: "First attachment",
     31     },
     32     {
     33       type: 3,
     34       name: "2nd_attchment",
     35       description: "Second attachment",
     36     },
     37     {
     38       type: 3,
     39       name: "3rd_attchment",
     40       description: "Third attachment",
     41     },
     42     {
     43       type: 3,
     44       name: "4th_attchment",
     45       description: "Forth attachment",
     46     },
     47     {
     48       type: 3,
     49       name: "5th_attchment",
     50       description: "Fifth attachment",
     51     },
     52   ],
     53   run: async (client, interaction, args) => {
     54     repEmb = null;
     55     recoilAvailable = false;
     56     hasError = false;
     57     if (args.length == 1)
     58       repEmb = statsHandler(args.join(" ").replace("\n", " "));
     59     else repEmb = statsHandler(args.join(" + ").replace("\n", " "));
     60     if (hasError) {
     61       interaction.followUp({
     62         content: `**${repEmb || "An error has occured"}**`,
     63       });
     64     } else {
     65       if (recoilAvailable) {
     66         repEmb.fields.push({
     67           name: "**Recoil Graph**",
     68           value:
     69             "```\nThe Recoil graph below is dynamic (change based on attachment equipped)```",
     70         });
     71         const recoilImageLink = await chart.getShortUrl();
     72         repEmb.image = { url: recoilImageLink };
     73       }
     74       interaction.followUp({ embeds: [new EmbedBuilder(repEmb)] });
     75     }
     76   },
     77 };
     78 
     79 function inpHandler(inpmsg) {
     80   statsHandler(inpmsg.split("+")[0]);
     81 }
     82 
     83 function statsHandler(inpmsg) {
     84   let statsNames = [
     85       "Pellets", //0
     86       "Detonation Range", //1
     87       "Explosion Radius", //2
     88       "Explosion Damage", //3
     89       "Firing Mode", //4
     90       "Rate of Fire", //5
     91       "Bullet in Burst", //6
     92       "Time Between Burst", //7
     93       "Bullet Speed", //8
     94       "Penetration Level", //9
     95       "Bullet Spread", //10
     96       "Idle Sway", //11
     97       "Hipfire Pellet Spread", //12
     98       "ADS Pellet Spread", //13
     99       "ADS Time", //14
    100       "Sprint-to-Fire Time", //15
    101       "ADS Zoom", //16
    102       "Magazine", //17
    103       "Reserve", //18
    104       "Reload Type", //19
    105       "Cancel Reload Time", //20
    106       "Reload Time", //21
    107       "Full Reload Time", //22
    108       "Drop Time", //23
    109       "Raise Time", //24
    110       "Sprinting Speed", //25
    111       "Walking Speed", //26
    112       "Straifing Speed", //27
    113       "Damage per Tick", //28
    114       "Number of Ticks", //29
    115       "Time Between Ticks", //30
    116       "Breath Hold Time", //31
    117       "shouldNeverHappen0",
    118       "shouldNeverHappen1",
    119       "shouldNeverHappen2",
    120       "shouldNeverHappen3",
    121       "shouldNeverHappen4",
    122     ],
    123     out = [];
    124 
    125   currGun = common.weaponIdentifier(inpmsg);
    126   if (typeof currGun == "string") {
    127     hasError = true;
    128     return currGun;
    129   }
    130   currStats = currGun.stats;
    131   currDRM = currGun.drm[0];
    132   currAttachments = [];
    133   currAttachments = common.attachmentsIdentifier(inpmsg, currGun);
    134   if (typeof currAttachments == "string") {
    135     hasError = true;
    136     return currAttachments;
    137   }
    138   currRecoilArr = [1, 1, currGun.stats[17]];
    139   if (currAttachments.length != 0) {
    140     const totalEffects = common.totaler(currAttachments);
    141 
    142     currStats = common.updateStatswithEffects(totalEffects, currStats);
    143     currRecoilArr = [totalEffects[2], totalEffects[3], currGun.stats[17]]; // must happen after currStats update
    144     currDRM = currGun.drm[totalEffects[37]];
    145     currDRM.range = currDRM.range.map(x =>
    146       Math.round(x * (1 + totalEffects[13] / 100))
    147     );
    148     out = common.attachmentHandler(totalEffects, currStats);
    149   }
    150   function statsWorker() {
    151     if (currStats[19] === 2) {
    152       currStats[21] =
    153         currStats[20] + currStats[21] * currStats[17] + currStats[22];
    154       currStats[20] = 0;
    155       currStats[22] = 0;
    156     }
    157     currStats[25] = (currStats[25] * currStats[26]) / 100;
    158 
    159     const outReady = currStats.map((x, i) =>
    160       x ? statsNames[i].padEnd(24) + ":".padEnd(3) + beautifier(i) : ""
    161     );
    162     out = [
    163       ...[
    164         "Basic Stats",
    165         "ADS Stats",
    166         "Bullet Stats",
    167         "Magazine",
    168         "Handling Stats",
    169         "Mobility Stats",
    170         "Miscellaneous Stats",
    171       ].map((x, i) =>
    172         fieldMaker(
    173           x,
    174           [
    175             [04, 05, 09],
    176             [14, 16, 11, 31],
    177             [00, 06, 07, 08, 10, 12, 13],
    178             [17, 18, 19, 20, 21, 22],
    179             [23, 24],
    180             [25, 26, 27, 15],
    181             [28, 29, 30, 01, 02, 03],
    182           ][i]
    183         )
    184       ),
    185       ...out,
    186     ];
    187     function fieldMaker(inpName, inpIndx) {
    188       inpIndx = inpIndx.filter(x => outReady[x]);
    189       return inpIndx.length
    190         ? {
    191             name: `**${inpName}**`,
    192             value: `\`\`\`\n${inpIndx.map(x => outReady[x]).join("\n")}\`\`\``,
    193           }
    194         : "";
    195     }
    196   }
    197   statsWorker();
    198 
    199   function beautifier(j) {
    200     switch (j) {
    201       case 04:
    202         return data.firingModes[currStats[j] - 1];
    203       case 09:
    204         return data.penetrationLevels[currStats[j] - 1];
    205       case 19:
    206         return data.reloadTypes[currStats[j] - 1];
    207       case 08:
    208         if (currStats[j] == -1) {
    209           return "Infinity";
    210         } else {
    211           return parseFloat(currStats[j].toFixed(2)).toString() + " m/s";
    212         }
    213       case 03:
    214         return parseFloat(currStats[j].toFixed(2))
    215           .toString()
    216           .replace(".", " ~ ");
    217       default:
    218         return parseFloat(currStats[j].toFixed(2)).toString() + addUnit(j);
    219     }
    220 
    221     function addUnit(j) {
    222       switch (j) {
    223         case 7:
    224         case 14:
    225         case 15:
    226         case 23:
    227         case 24:
    228         case 31:
    229           return " ms";
    230         case 25:
    231         case 26:
    232         case 27:
    233         case 28:
    234           return " m/s";
    235         case 20:
    236         case 21:
    237         case 22:
    238           return " s";
    239         case 16:
    240           return "%";
    241         case 6:
    242           return " Rounds";
    243         case 5:
    244           return " RPM";
    245         default:
    246           return "";
    247       }
    248     }
    249   }
    250   interpretion = currGun.gunname + common.interpretioner(currAttachments);
    251   if (currGun.recoil.hr.length > 2) {
    252     chart = common.recoilHandler(
    253       currGun.recoil.hr,
    254       currGun.recoil.vr,
    255       currRecoilArr[0],
    256       currRecoilArr[1],
    257       currRecoilArr[2]
    258     );
    259     recoilAvailable = true;
    260   } else recoilAvailable = false;
    261 
    262   if (chart == "none") recoilAvailable = false;
    263   if (chart == "err") hasError = true;
    264 
    265   const dmg =
    266     common.damageHandler(
    267       currDRM.damage,
    268       currDRM.range,
    269       1,
    270       100,
    271       60000 / currStats[5],
    272       currStats[7],
    273       currStats[6],
    274       currStats[0]
    275     ) || "```This should never happen```";
    276   out = [
    277     currGun.description
    278       ? {
    279           name: "**Description:**",
    280           value: `\`\`\`\n${currGun.description}\`\`\``,
    281         }
    282       : {},
    283     { name: "**Damage Profile:**", value: dmg },
    284     ...out,
    285   ];
    286   out = out.filter(x => x.value);
    287   return {
    288     title: interpretion,
    289     color: 5814783,
    290     fields: out,
    291     footer: {
    292       text: "[OUTDATED] All data courtesy of Project Lighthouse 2.0 and CoDM Research Crew",
    293       icon_url:
    294         "https://media.discordapp.net/attachments/735590814662656102/806960573753327657/cc.png",
    295     },
    296   };
    297 }