Discord.js | Cannot access "lol" before initialization - javascript

I am trying to get my bot to send random images in embeds but this logs in the terminal:
let lol = Math.floor (Math.random() * (lol - 1 + 1)) + 1;
^
ReferenceError: Cannot access 'lol' before initialization
This is the code its referring to:
case 'gif':
let maxImageNumber1 = 213;
let lol = Math.floor (Math.random() * (lol - 1 + 1)) + 1;
let imageName1 = `${maxImageNumber1}.gif`
let imagePath1 = `./GIF/${imageName1}`
let file2 = new Discord.MessageAttachment(imagePath1);
let embed1 = new Discord.MessageEmbed();
embed1.setImage(`attachment://${imageName1}`)
message.channel.send({ files: [file2], embed: embed1 });
break;
case 'aes':
let maxImageNumber = 100;
let imageNumber = Math.floor (Math.random() * (maxImageNumber - 1 + 1)) + 1;
let imageName = `${imageNumber}.jpg`
let imagePath = `./images/${imageName}`
let file1 = new Discord.MessageAttachment(imagePath);
let embed = new Discord.MessageEmbed();
embed.setImage(`attachment://${imageName}`)
message.channel.send({ files: [file1], embed: embed });
break;
How would i go about solving this issue?

where you trying to obtain a random number between 1 and maxImageNumber1?
if so, this is the answer:
let maxImageNumber1 = 213;
let lol = Math.floor(Math.random() * maxImageNumber1) + 1;
let imagePath1 = `./GIF/${lol}.gif`

Related

How do I search a Discord user input for a value and assign it to a var?

I'm trying to search Discord User input for integers attached to attributes (Number of attacks, skill of attack, strength, toughness, save) and then run those args through some calculations.
At the moment the function uses the order of args in the command:
!odds 5 3 4 5 3
which works, but I want something like this:
!odds at: 5 sk: 3 st: 4 t: 5 sv: 3
And the bot will search the user input for values attached to those attributes in any order and use those integers for its calculations.
In addition, if attributes aren't present the bot will not include them in the output (or assign default values) and by adding additional, single phrase attributes with no attached integer (for example fnp or res) it would then add another standard calculation and output.
This is what I have so far:
const { Message } = require('discord.js')
module.exports = {
name: 'odds',
aliases: ['stats', 'probability'],
usage: '[#attacks (1 = auto hit)] [skill] [strength] [toughness] [save (7 = no save)]',
description: 'What are the odds?',
execute(message, args) {
let attack = args[0]
let skill;
if (args[1]>=7) skill = 7;
else skill = args[1];
let strength = args[2]
let toughness = args[3]
let save;
if (args[4]<=6) save = args[4];
else save = 7;
let hits = parseFloat((attack*((7-skill)/6)).toFixed(2))
let hitSixes = parseFloat((attack*(1/6)).toFixed(2))
let woundFactor;
if (strength>=(2*toughness)) woundFactor = 2;
else
if (strength>toughness) woundFactor = 3;
else
if (strength==toughness) woundFactor = 4;
else
if (toughness>=(2*strength)) woundFactor = 6;
else
if (strength<toughness) woundFactor = 5;
let wounds = parseFloat((hits*((7-woundFactor)/6)).toFixed(2))
let woundSixes = parseFloat((hits*(1/6)).toFixed(2))
let unsavedWounds = parseFloat(((wounds-(wounds*((7-save)/6))).toFixed(2)))
message.channel.send(`On average you will make:\n${hits} successful hits (with ${hitSixes} sixes)\n${wounds} successful wounds (with ${woundSixes} sixes)\nGiving a total of ${unsavedWounds} unsaved wounds.`)
}}
Any and all help greatly appreciated!
// what you accept:
const inputs = {
at: 0,
sk: 0,
st: 0,
t: 0,
sv: 0,
}
for (let i = 0, arg; arg = args[i]; i++) {
const index = arg.indexOf(':'); // it must have an ":" as last character
if (index === -1) {
continue;
}
const keyword = arg.substr(0, index - 1); // get the word
if (!inputs.hasOwnProperty(keyword)) { // check if it's an element of inputs
continue;
}
if (i + 1 === args.length) { // make sure enough args are available
continue;
}
inputs[keyword] = isNaN(args[i + 1]) ? 0 : +args[i + 1]; // make sure it's a number
i++; // skip the next element
}
let attack = inputs.at;
let skill = inputs.sk >= 7 ? 7 : inputs.sk;
let strength = inputs.st;
let toughness = inputs.t;
let save = inputs.sv <= 6 ? inputs.sv : 7;

Re-selecting another value and clac but old result displays in JS

I'm studying calc. I'm having problem with re-selecting value and calc.
Here is my whole program
https://jsfiddle.net/diessses/c9ykmsf2/6/
When user select value then press submit. it works perfectly. However when user change such as 'cb_amount' , s_month and 's_year' Then click submit below code part displays OLD result. Other part result works fine. Could you teach me write code please?
// PAY_START_END_MONTH_FMT message
const PAY_START_END_MONTH_FMT = "If loan start Month is :start ,<br> Final loan paying will be :end ";
let s_month = document.getElementById(elementId.s_month).value;
if (s_month) {
let s_year = document.getElementById(elementId.s_year).value;
let date = new Date();
date.setMonth(s_month - 1);
date.setFullYear(s_year);
let startMonth = DateManager.formatDate(date, DateManager.getFormatString().YYYY_MM);
DateManager.addMonth(date, (years * 12) - 1);
let endMonth = DateManager.formatDate(date, DateManager.getFormatString().YYYY_MM);
document.getElementById("pay_start_end_month").innerHTML = PAY_START_END_MONTH_FMT.replace(":start", startMonth).replace(":end", endMonth);
}
// CB_SENTENCE_FMT message
const CB_SENTENCE_FMT = "Combined bonus amount will be :j_actual_cb_ttl. Paying times is :j_cbTimes . mothly paying is :j_monthly_bns_payment";
if (bSecondToLastTtl > 1) {
let j_actual_cb_ttl = ValueUtils.comma(bSecondToLastTtl);
let j_cbTimes = cbTimes;
let j_monthly_bns_payment = ValueUtils.comma(monthly_b);
document.getElementById("j_cb_sentence").innerHTML = CB_SENTENCE_FMT.replace(":j_actual_cb_ttl", j_actual_cb_ttl).replace(":j_cbTimes", j_cbTimes).replace(":j_monthly_bns_payment", j_monthly_bns_payment);
}
There are a lot of variables which you are have declaration as "const". Try changing those to "let". Read about it here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const and https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let. I have forked your code and tried, seems to be updating the data based on the new values.
Forked fiddle https://jsfiddle.net/b5g73x02/. Below is what I changed.
let cbTimes = years * 2; //
let diff = amount - downpayment;
let justDevideCbAmount = cb_amount / cbTimes;
let monthly_b = (Math.floor(justDevideCbAmount / 100) * 100);
let bSecondToLastTtl = monthly_b * cbTimes;
let paymentTimes = years * 12;
let interestMod = 10000 + (interest * 100);
let ttlWInterest = parseInt(((amount - downpayment) * interestMod )/ 10000);
let ttlWInterestNegativeCb = ttlWInterest - bSecondToLastTtl;
let jstDevideMonthly = ttlWInterestNegativeCb / paymentTimes;
let secondToLastMonthlyPayment = (Math.floor(jstDevideMonthly / 100) * 100);
let firstMonthlyPayment = ttlWInterestNegativeCb - (secondToLastMonthlyPayment * (paymentTimes - 1));
let jKinri = (interest / 100).toFixed(5);
let kinriFinal = ValueUtils.comma(parseInt(ttlWInterest - (amount - downpayment)));

How to randomize the order of buttons in a div?

I'm making a education website and I need some help.
I have this code:
challenge1 = num1*num2;
challenge2 = num1*2+Math.floor(Math.random() *3) + 1;;
challenge3 = num1*num2+Math.floor(Math.random() *9) + 1;
challenge4 = num2+Math.floor(Math.random() *9) + 1;
makeButton(challenge1);
makeButton(challenge2);
makeButton(challenge3);
makeButton(challenge4);
function makeButton(number) {
btncount = btncount+1;
/* create a button */
var b = document.createElement('button');
b.setAttribute('class', 'pure-button');
b.setAttribute('onclick', `check(${number})`);
b.setAttribute('id', btncount);
b.textContent = number;
var buttons = document.getElementById("buttons");
buttons.appendChild(b);
}
<div id='buttons' class="pure-button-group" role="group"></div>
and it works but it's very easy to spot that the correct answer will always be the first button.
Is there a way to randomize the order of those? Thanks.
It's about shuffling a list. you should create an array of elements first(without appending them to the parent), shuffle it, and then parent.append(...list).
You can find out how to shuffle a list here:
How to randomize (shuffle) a JavaScript array?
following your snippet you can swap first and last randomly
let btncount = 0;
function makeButton(number) {
btncount = btncount+1;
/* create a button */
var b = document.createElement('button');
b.setAttribute('class', 'pure-button');
b.setAttribute('onclick', `check(${number})`);
b.setAttribute('id', btncount);
b.textContent = number;
var buttons = document.getElementById("buttons");
buttons.appendChild(b);
//randomly swap first and last
if(Math.round(Math.random())) {
// swap first and last
buttons.appendChild(buttons.firstElementChild);
}
}
const num1 = 1, num2 = 2;
const challenge1 = num1*num2;
const challenge2 = num1*2+Math.floor(Math.random() *3) + 1;;
const challenge3 = num1*num2+Math.floor(Math.random() *9) + 1;
const challenge4 = num2+Math.floor(Math.random() *9) + 1;
makeButton(challenge1);
makeButton(challenge2);
makeButton(challenge3);
makeButton(challenge4);
<div id="buttons">
</div>
You could make an array of challenges and sort this array with a custom comparator:
challenges = [
num1*num2,
num1*2+Math.floor(Math.random() *3) + 1,
num1*num2+Math.floor(Math.random() *9) + 1,
num2+Math.floor(Math.random() *9) + 1
]
function randomizer () { return Math.random() > 0.5 }
challenges.sort(randomizer)
for (challenge of challenges) makeButton(challenge)
EDIT
To have a better randomization you can make a list of object with a random index and sort it normally:
challenges = [
{ challenge: num1*num2, index: Math.random() },
{ challenge: num1*2+Math.floor(Math.random() *3) + 1, index: Math.random() },
{ challenge: num1*num2+Math.floor(Math.random() *9) + 1, index: Math.random() },
{ challenge: num2+Math.floor(Math.random() *9) + 1, index: Math.random() }
]
function compare(a,b) { return a.index == b.index ? 0 : a.index > b.index ? 1 : -1 }
challenges.sort(compare)
for (i in challenges) makeButton(challenges[i].challenge)
Put the "challenges" into an array and shuffle it. You can shuffle in plain javascript as described in this answer, but I prefer to shuffle with rando.js, like this:
console.log( randoSequence(["a", "b", "c"]) );
<script src="https://randojs.com/2.0.0.js"></script>
Apply that shuffle to your buttons, and you have this:
var num1 = 2;
var num2 = 4;
var btncount = 0;
challenge1 = num1 * num2;
challenge2 = num1 * 2 + Math.floor(Math.random() * 3) + 1;;
challenge3 = num1 * num2 + Math.floor(Math.random() * 9) + 1;
challenge4 = num2 + Math.floor(Math.random() * 9) + 1;
//------------CHANGED PART------------
var shuffledChallenges = randoSequence([challenge1, challenge2, challenge3, challenge4]);
makeButton(shuffledChallenges[0].value);
makeButton(shuffledChallenges[1].value);
makeButton(shuffledChallenges[2].value);
makeButton(shuffledChallenges[3].value);
//--------END OF CHANGED PART.--------
function makeButton(number) {
btncount = btncount + 1;
/* create a button */
var b = document.createElement('button');
b.setAttribute('class', 'pure-button');
b.setAttribute('onclick', `check(${number})`);
b.setAttribute('id', btncount);
b.textContent = number;
var buttons = document.getElementById("buttons");
buttons.appendChild(b);
}
<script src="https://randojs.com/2.0.0.js"></script>
<div id='buttons' class="pure-button-group" role="group"></div>

Javascript - time delay between spawns

I have this function ( feel free to use it if you guys need it) that generates monsters for me in random positions outside the play area. After the monster is generated, the monster then follows a way to the character.
But, the problem is that, the monsters are generated all at the same time. What i am trying to do is put some time delay between spawns. Like, 1st monster is generated at the start of the game; second monster i want to be generated after 1 second. Any ideeas how can i achieve this?
I've tried making a time variable that iterates and then spawn an enemy if counter > time. But that dosen't seem to work proprely
function init(){
}
function update(dt){
}
function signal(name, value){
let x1 = 6;
let x2 = -6;
let y1 = 20;
let y2 = 1;
let cadran = Math.floor(Math.random() * (+4 - +1)) + +1;
if(value){
for(i=0;i<5;i++){
if(cadran == 1){
monsterGenerator(this,x2,x1,y1 ,1);
}
if(cadran == 2){
monsterGenerator(this,x2,x1,y2,2);
}
if(cadran == 3){
monsterGenerator(this,y2,y1,x1,3);
}
if(cadran == 4){
monsterGenerator(this,y2,y1,x2,4);
}
cadran++;
if(cadran==5){
cadran = 1;
}
}
}
}
function monsterGenerator(ob,min,max,stat,rand) {
let assetName = ob.attribute('Asset Name');
let ent = ob.scene().create(assetName);
if(ent == null) error('Asset "'+assetName+'" does not exist');
let pos = ob.entity().worldPosition();
let rot = ob.entity().rotation();
let scl = ob.entity().scale();
let random = Math.floor(Math.random() * (+max - +min)) + +min;
if(rand==1){
ent.setPosition(pos.x = random, pos.y =stat , pos.z);
}
if(rand==2){
ent.setPosition(pos.x = random, pos.y =stat , pos.z);
}
if(rand==3){
ent.setPosition(pos.x = stat, pos.y =random , pos.z);
}
if(rand==4){
ent.setPosition(pos.x = stat, pos.y =random , pos.z);
}
ent.setRotation(rot.x, rot.y, rot.z);
ent.setScale(scl.x, scl.y, scl.z);
}

How can I avoid sending two commands at once?

I'm creating a discord bot and part of its commands is to roll dice with different values (d6, d10, d20, d100). I've set it up like this:
const Discord = require('discord.js');
const client = new Discord.Client();
function commandIs (str, msg){
return msg.content.toLowerCase().startsWith("!" + str)
} //Function that shortens all response commands.
client.on ('message', message => {
if(commandIs("rolld6", message)){
var result = Math.floor(Math.random() * ((6 - 1) + 1) + 1);
message.channel.sendMessage (result);
} //rolls a d6
if(commandIs("rolld10", message)){
var result = Math.floor(Math.random() * ((10 - 1) + 1) + 1);
message.channel.sendMessage (result);
} //rolls a d10
if(commandIs("rolld20", message)){
var result = Math.floor(Math.random() * ((20 - 1) + 1) + 1);
message.channel.sendMessage (result);
} //rolls a d20
if(commandIs("rolld100", message)){
var result = Math.floor(Math.random() * ((100 - 1) + 1) + 1);
message.channel.sendMessage (result);
} //rolls a d100
})
client.login('<Discord bot token>'); //Bot token so it can login to Discord
The issue I have is when I send '!rolld100', the bot answers as if I sent '!rolld10' and '!rolld100' at the same time since 10 is in 100.
Any possible fixes? I'm also new to javascript so if you could explain what your solution does it would help me a lot.
The code seems to be a little complicated with duplicated code. You can simplify this down to a few lines of code by using a regular expression
const Discord = require('discord.js');
const client = new Discord.Client();
client.on ('message', message => {
const rollMatch = message.match(/roll(\d+)\s/)
if (rollMatch) {
const sides = Number(rollMatch)
var result = Math.floor(Math.random() * sides + 1);
message.channel.sendMessage (result);
}
})
client.login('<Discord bot token>'); //Bot token so it can login to Discord
Now if you want to do it your way. You basically would need to do
if(commandIs("rolld100", message)){ }
else if(commandIs("rolld10", message)){ }
else if(commandIs("rolld20", message)){ }
else if(commandIs("rolld6", message)){ }

Categories

Resources