Advertisement
Nico105

Bonus Entries

Jan 16th, 2021
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. async roll(winnerCount) {
  2.         if (!this.message) return [];
  3.         // Pick the winner
  4.         const reactions = this.message.reactions.cache;
  5.         const reaction = reactions.get(this.reaction) || reactions.find((r) => r.emoji.name === this.reaction);
  6.         if (!reaction) return [];
  7.         const guild = this.channel.guild;
  8.         // Fetch guild members
  9.         if (this.manager.options.hasGuildMembersIntent) await guild.members.fetch();
  10.         const users = (await reaction.users.fetch())
  11.             .filter((u) => !u.bot || u.bot === this.botsCanWin)
  12.             .filter((u) => u.id !== this.message.client.user.id);
  13.  
  14.         let userArray; 
  15.         if (
  16.             this.extraData &&
  17.             this.extraData.bonusEntryRoles &&
  18.             this.extraData.bonusEntryRoles.every(
  19.                 ber =>
  20.                     Object.keys(ber).every(k => k === 'roleID' || k === 'entries') &&
  21.                     typeof ber.roleID === 'string' &&
  22.                     typeof ber.entries === 'number'
  23.             )
  24.         ) {
  25.             userArray = users.array().slice(); // Copy all users once
  26.             /**
  27.              * Each user who has a bonus entry role is pushed into the array
  28.              * until they are in the array as many times as has been specified for the bonus entry role with the highest entrie amount which they own
  29.              */
  30.             for (const user of userArray.slice()) {
  31.                 const isUserValidEntry = await this.checkWinnerEntry(user);
  32.                 if (!isUserValidEntry) continue;
  33.  
  34.                 const validBonusEntryRoles = this.extraData.bonusEntryRoles.filter(ber => Number.isInteger(ber.entries) && ber.entries > 1);
  35.                 if (!validBonusEntryRoles.length) continue;
  36.                 const memberRoles = this.channel.guild.member(user.id).roles.cache.array();
  37.                 const intersectedRoles = validBonusEntryRoles.filter(ber => memberRoles.map(r => r.id).includes(ber.roleID));
  38.                 if (!intersectedRoles.length) continue;
  39.  
  40.                 const highestEntries = Math.max.apply(Math, intersectedRoles.map(ber => ber.entries))
  41.                 for (var i = 0; i < highestEntries - 1; i++) userArray.push(user)
  42.             }
  43.         }
  44.  
  45.         let rolledWinners;
  46.         if (!userArray || userArray.length <= (winnerCount || this.winnerCount)) {
  47.             rolledWinners = users.random(Math.min(winnerCount || this.winnerCount, users.size));
  48.         } else {
  49.             /** The same as https://github.com/discordjs/collection/blob/master/src/index.ts#L193
  50.              * because collections/maps do not allow dublicates and so we need our own roll mechanism for the userArray
  51.             */
  52.             const amount = winnerCount || this.winnerCount;
  53.             if (!amount) rolledWinners = userArray[Math.floor(Math.random() * userArray.length)];
  54.             else rolledWinners = Array.from({ length: Math.min(amount, users.size) }, () => userArray.splice(Math.floor(Math.random() * userArray.length), 1)[0]);
  55.         }
  56.  
  57.         const winners = [];
  58.  
  59.         for (const u of rolledWinners) {
  60.             const isValidEntry = await this.checkWinnerEntry(u) && !winners.some((winner) => winner.id === u.id);
  61.             if (isValidEntry) winners.push(u);
  62.             else {
  63.                 // Find a new winner
  64.                 for (const user of (userArray || user.array())) {
  65.                     const alreadyRolled = winners.some((winner) => winner.id === user.id);
  66.                     if (alreadyRolled) continue;
  67.                     const isUserValidEntry = await this.checkWinnerEntry(user);
  68.                     if (!isUserValidEntry) continue;
  69.                     else {
  70.                         winners.push(user);
  71.                         break;
  72.                     }
  73.                 }
  74.             }
  75.         }
  76.  
  77.         return winners.map((user) => guild.member(user) || user);
  78.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement