const Utility = require("./Utility"); const chooseWeightedRandom = require("../Utility/chooseWeightedRandom"); const uniqueCategories = { 5: true }; const uniqueItems = {}; class Reward { constructor(information) { this.distributionType = information.distributionType; this.baseReward = information.baseReward; this.damage = information.damage; }; single(amountOfItems, inventory, cb) { if (this.distributionType !== 2) return; const { baseReward } = this; const allRewardCategories = Object.entries(baseReward); const rewardChances = []; const rewardEntries = []; const finalRewards = []; allRewardCategories.forEach(category => { const [categoryName, categoryEntries] = category; Object.entries(categoryEntries).forEach(subEntry => { const [id, entry] = subEntry; const isUniqueReward = uniqueCategories[categoryName] || uniqueItems[categoryName] && uniqueItems[categoryName][id]; const isAlreadyAcquired = inventory[categoryName] && inventory[categoryName].hasElement(+id); if (isUniqueReward && isAlreadyAcquired) return; const rewardEntry = { categoryID: +categoryName, id: +id, amount: entry.amountMaximum ? Utility.RandomIntegerBetween(entry.amountMinimum, entry.amountMaximum) : entry.amountMinimum, index: rewardEntries.length }; if (entry.chance === 100) finalRewards.push(rewardEntry); else { rewardChances.push(entry.chance); rewardEntries.push(rewardEntry); }; }); }); const batchedRewards = {}; if (rewardEntries.length) { for (let i = 0; i < amountOfItems; i++) { const chosenItem = chooseWeightedRandom(rewardEntries, rewardChances); const batchedEntryIndex = batchedRewards[`${chosenItem.categoryID}-${chosenItem.id}`]; if (batchedEntryIndex !== undefined) { finalRewards[batchedEntryIndex].amount += chosenItem.amount; } else { batchedRewards[`${chosenItem.categoryID}-${chosenItem.id}`] = finalRewards.length; finalRewards.push(Object.assign({}, chosenItem)); const isUniqueReward = uniqueCategories[chosenItem.categoryID] || uniqueItems[chosenItem.categoryID] && uniqueItems[chosenItem.categoryID][chosenItem.id]; if (isUniqueReward) rewardChances[chosenItem.index] = 0; }; }; }; cb(finalRewards); } multiple(data, cb) { if (this.distributionType !== 1) return; const { baseReward } = this; const { playerInventory, damage, maximum, lastShotAuthorID } = data; const allRewardCategories = Object.keys(baseReward); const totalParticipants = Object.keys(damage); totalParticipants.forEach(playerID => { playerID = parseInt(playerID); const rewards = []; allRewardCategories.forEach(category => { category = parseInt(category); const rew = baseReward[category]; Object.keys(rew).forEach(id => { id = parseInt(id); const isUniqueReward = uniqueCategories[category] || uniqueItems[category] && uniqueItems[category][id]; const isAlreadyAcquired = playerInventory[category] && playerInventory[category].hasElement(id); if (isUniqueReward && isAlreadyAcquired) return; if (rew[id].lastShot && playerID !== lastShotAuthorID) return; if (rew[id].chance < Math.random() * 100) return; const baseRewardAmount = rew[id].amountMaximum ? Utility.RandomIntegerBetween(rew[id].amountMinimum, rew[id].amountMaximum) : rew[id].amountMinimum; const amountOfReward = rew[id].lastShot ? baseRewardAmount : Math.round(baseRewardAmount / 100 * (damage[playerID] / maximum * 100)); if (amountOfReward <= 0) return; rewards.push({ categoryID: category, id, amount: amountOfReward }); }); }); cb({ id: playerID }, rewards); }); } dynamic(cb) { if (this.distributionType !== 3) return; for (let i = 0, length = this.baseReward.length; i < length; i++) { const reward = this.baseReward[i]; const baseRewardAmount = reward.amountMaximum ? Utility.RandomIntegerBetween(reward.amountMinimum, reward.amountMaximum) : reward.amountMinimum; cb([{ categoryID: reward.categoryID, id: reward.id, amount: baseRewardAmount }]); }; } }; module.exports = Reward;