2021-11-18 18:56:42 +01:00
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 ,
2021-11-18 18:56:42 +01:00
} ) ;
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 ,
2021-11-18 18:56:42 +01:00
} ) ;
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 ,
2021-11-18 18:56:42 +01:00
} ) ;
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 ,
2021-11-18 18:56:42 +01:00
} ) ;
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 ,
2021-11-18 18:56:42 +01:00
} ) ;
2022-01-25 16:07:38 +01:00
/* Function to fix the input statement */
2021-11-18 18:56:42 +01:00
function inpFixer ( inpmsg ) {
2022-01-29 14:55:43 +01:00
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 =
2021-11-18 18:56:42 +01:00
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 ;
2021-11-18 18:56:42 +01:00
}
2022-01-29 14:55:43 +01:00
// 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 " ) ;
2021-11-18 18:56:42 +01:00
}
function hasAttachments ( inpmsg ) {
2022-01-23 02:06:11 +01:00
inpmsg = inpFixer ( inpmsg ) ;
2022-01-29 14:55:43 +01:00
// 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 ||
2021-11-18 18:56:42 +01:00
inpmsg . split ( " + " ) . filter ( x => x . Simplify ( ) ) . length > 1
2022-01-23 02:06:11 +01:00
) {
return true ;
}
return false ;
2021-11-18 18:56:42 +01:00
}
function isolator ( inpmsg ) {
2022-01-29 14:55:43 +01:00
return PartSpliter ( inpFixer ( inpmsg ) ) ;
2021-11-18 18:56:42 +01:00
}
2022-01-27 22:47:50 +01:00
// identifying the weapon
2021-11-18 18:56:42 +01:00
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 ) ;
}
}
2022-01-29 14:55:43 +01:00
// 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 ] ] ) ) ;
}
2022-01-29 14:55:43 +01:00
// 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 ) ] ;
2022-01-29 14:55:43 +01:00
// 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 ] ] ) ) ;
2022-01-29 14:55:43 +01:00
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 `" : "`, `" )
) }
? ` ;
2022-01-29 14:55:43 +01:00
} else return ` Couldn't identify the weapon: " ${ inpWeaponName } " ` ;
2021-11-18 18:56:42 +01:00
}
2022-01-29 14:55:43 +01:00
// identifying attachments and return array or error
2022-02-01 01:29:22 +01:00
function attachmentsIdentifier ( inpmsg , gun ) {
2022-01-29 14:55:43 +01:00
if ( ! hasAttachments ( inpmsg ) ) return [ ] ;
2021-11-18 18:56:42 +01:00
// 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
2021-11-18 18:56:42 +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
2021-11-18 18:56:42 +01:00
inputAttachmentsNames = inputAttachmentsNames . filter ( x => ! ( x . length < 3 ) ) ;
let errorMsgs = "" ,
errors = [ ] ,
unidentifined = [ ] ;
2022-01-25 16:07:38 +01:00
if ( inputAttachmentsNames . length == 0 )
2021-11-18 18:56:42 +01:00
errorMsgs += "\nAttachments are missing!\n" ;
2022-02-01 01:29:22 +01:00
// if (inputAttachmentsNames.length >= 10) return "Cocaineeeeee"; ?????????
2021-11-18 18:56:42 +01:00
// 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"]
2021-11-18 18:56:42 +01:00
splitAttachmentsDataName . push ( [
... new Set (
2022-02-01 01:29:22 +01:00
gun . aments [ i ] . name
2021-11-18 18:56:42 +01:00
. split ( " " )
. filter ( x => x )
. map ( x => x . trim ( ) )
) ,
] ) ;
2022-02-02 21:40:53 +01:00
// splitAttachmentsDataName[i] = ["Stippled", "Grip", "Tape"]
2021-11-18 18:56:42 +01:00
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"]
2021-11-18 18:56:42 +01:00
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" ) ) &&
2021-11-18 18:56:42 +01:00
inputAttachmentsNames [ i ] . startsWith (
2022-01-23 02:06:11 +01:00
inputAttachmentsNames [ i ] . replace ( /\D/g , "" )
2021-11-18 18:56:42 +01:00
)
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 ||
2021-11-18 18:56:42 +01:00
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 ||
2021-11-18 18:56:42 +01:00
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 &&
2021-11-18 18:56:42 +01:00
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 ||
2021-11-18 18:56:42 +01:00
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-03-02 19:37:05 +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-03-02 19:37:05 +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 `" +
2021-11-18 18:56:42 +01:00
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 `" : "`, `" )
) +
2021-11-18 18:56:42 +01:00
"` 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 ? ` \n Did 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
? ` \n Couldn't identify the attachment( ${
unidentifined . length === 1 ? "" : "s"
} ) : \ ` " ${ unidentifined . join ( '"`, `"' ) } " \` \n `
2022-01-23 02:06:11 +01:00
: "" ;
errorMsgs +=
2021-11-18 18:56:42 +01:00
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" +
2021-11-18 18:56:42 +01:00
( 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 `"' : '"`, `"' )
2021-11-18 18:56:42 +01:00
) +
'"` ' +
( tooSmall . length === 1 ? "is" : "are" ) +
" too short\n"
2022-01-23 02:06:11 +01:00
: "" ;
return errorMsgs ? errorMsgs . trim ( ) : outAttachments ;
2021-11-18 18:56:42 +01:00
}
// console.log(attachmentsIdentifier("chopper with heavy handle, red sight, granulated", data.cguns[38].aments)); makeError();
2022-01-29 14:55:43 +01:00
// console.log(attachmentsIdentifier("ak + 5mw lazer", data.cguns[0].aments)); makeError();
2021-11-18 18:56:42 +01:00
// 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();
2021-11-18 18:56:42 +01:00
function damageHandler (
2022-01-23 02:06:11 +01:00
currDmgs ,
currRngs ,
damageMulti ,
hp ,
tbs ,
tbb ,
bib ,
pellets
2021-11-18 18:56:42 +01:00
) {
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 ) +
2021-11-18 18:56:42 +01:00
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 ;
2022-03-13 20:07:05 +01:00
if ( ! pellets ) out = Math . ceil ( hp / dmg ) ;
else out = Math . ceil ( hp / ( dmg * pellets ) ) ;
return out == Infinity ? "∞" : out ;
2022-01-23 02:06:11 +01:00
}
function ttk ( dmg ) {
const stkVal = stk ( dmg ) ;
2022-03-13 20:07:05 +01:00
if ( stkVal == "∞" ) return stkVal ;
if ( ! bib ) return Math . round ( ( stkVal - 1 ) * tbs ) ;
2022-01-23 02:06:11 +01:00
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" +
2021-11-18 18:56:42 +01:00
"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
) ;
2021-11-18 18:56:42 +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
2021-11-18 18:56:42 +01:00
) {
2022-03-13 20:07:05 +01:00
if ( xRecoil . length != yRecoil . length ) return "err" ;
2022-01-23 02:06:11 +01:00
const recoilLength = xRecoil . length ;
2022-03-13 20:07:05 +01:00
if ( recoilLength == 0 ) return "none" ;
2022-01-23 02:06:11 +01:00
const recoilPattern = [
{
x : 0 ,
y : 0 ,
} ,
] ;
let recoilObj ;
for ( let i = 0 ; i < bulletCount ; i ++ ) {
const xContinuationVal =
2021-11-18 18:56:42 +01:00
xRecoil [ recoilLength - 1 ] - xRecoil [ recoilLength - 2 ] ;
2022-01-23 02:06:11 +01:00
const yContinuationVal =
2021-11-18 18:56:42 +01:00
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 :
2021-11-18 18:56:42 +01:00
( recoilPattern [ recoilPattern . length - 1 ] . x + xContinuationVal ) *
xMultiplier ,
2022-01-23 02:06:11 +01:00
y :
2021-11-18 18:56:42 +01:00
( 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 ;
2021-11-18 18:56:42 +01:00
}
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 ;
2021-11-18 18:56:42 +01:00
}
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 ] +
2021-11-18 18:56:42 +01:00
"% 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 ] +
2021-11-18 18:56:42 +01:00
"% 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 " +
2021-11-18 18:56:42 +01:00
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 ) ;
2021-11-18 18:56:42 +01:00
}
function interpretioner ( inpAttachments ) {
2022-01-23 02:06:11 +01:00
return inpAttachments . length
? " with " + inpAttachments . map ( x => x . name ) . join ( ", " )
: "" ;
2021-11-18 18:56:42 +01:00
}
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 ;
2021-11-18 18:56:42 +01:00
}
function makeError ( ) {
2022-01-25 16:07:38 +01:00
undefined . split ( "L" ) ;
2021-11-18 18:56:42 +01:00
}
module . exports = {
2022-01-23 02:06:11 +01:00
weaponIdentifier ,
attachmentsIdentifier ,
recoilHandler ,
attachmentHandler ,
updateStatswithEffects ,
makeError ,
interpretioner ,
damageHandler ,
isolator ,
totaler ,
hasAttachments ,
2021-11-18 18:56:42 +01:00
} ;