134 lines
5.1 KiB
JavaScript
134 lines
5.1 KiB
JavaScript
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; |