Skip to content

Commit

Permalink
Merge pull request #314 from the-hideout/used-in-tasks
Browse files Browse the repository at this point in the history
Add used in tasks info to /item and /key
  • Loading branch information
Razzmatazzz authored Sep 25, 2024
2 parents 2b873c1 + 62fcd4c commit 58e0ace
Show file tree
Hide file tree
Showing 14 changed files with 172 additions and 36 deletions.
5 changes: 4 additions & 1 deletion commands/item.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,14 @@ const defaultFunction = {
// Get the search string from the user invoked command
const searchString = interaction.options.getString('name');

const [ items, traders, hideout, barters, crafts, maps ] = await Promise.all([
const [ items, traders, hideout, barters, crafts, maps, tasks ] = await Promise.all([
gameData.items.getAll({lang, gameMode}),
gameData.traders.getAll({lang, gameMode}),
gameData.hideout.getAll({lang, gameMode}),
gameData.barters.getAll({ gameMode}),
gameData.crafts.getAll({ gameMode}),
gameData.maps.getAll({ lang, gameMode}),
gameData.tasks.getAll({ lang, gameMode }),
]);
const matchedItems = items.filter(i => i.name.toLowerCase().includes(searchString.toLowerCase()));

Expand Down Expand Up @@ -85,6 +86,8 @@ const defaultFunction = {
embeds.push(await createEmbed.unlockMaps(item, interaction, {maps, interactionSettings: {lang, gameMode}}));
}

embeds.push(await createEmbed.itemUsedInTasks(item, interaction, {tasks, interactionSettings: {lang, gameMode}}));

if (i >= MAX_ITEMS - 1) {
break;
}
Expand Down
5 changes: 4 additions & 1 deletion commands/key.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,14 @@ const defaultFunction = {
// Get the search string from the user invoked command
const searchString = interaction.options.getString('name');

const [ items, traders, hideout, barters, crafts, maps ] = await Promise.all([
const [ items, traders, hideout, barters, crafts, maps, tasks ] = await Promise.all([
gameData.items.getAll({lang, gameMode}),
gameData.traders.getAll({lang, gameMode}),
gameData.hideout.getAll({lang, gameMode}),
gameData.barters.getAll({ gameMode}),
gameData.crafts.getAll({ gameMode}),
gameData.maps.getAll({ lang, gameMode}),
gameData.tasks.getAll({ lang, gameMode }),
]);
const matchedItems = items.filter(i => i.name.toLowerCase().includes(searchString.toLowerCase()));

Expand Down Expand Up @@ -74,6 +75,8 @@ const defaultFunction = {

embeds.push(await createEmbed.unlockMaps(item, interaction, {maps, interactionSettings: {lang, gameMode}}));

embeds.push(await createEmbed.itemUsedInTasks(item, interaction, {tasks, interactionSettings: {lang, gameMode}}));

if (i >= MAX_ITEMS - 1) {
break;
}
Expand Down
24 changes: 16 additions & 8 deletions commands/player.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,20 @@ const defaultFunction = {
const t = getFixedT(lang);
const commandT = getFixedT(lang, 'command');
const accountId = interaction.options.getString('account');

const gameModeLabel = t(`Game mode: {{gameMode}}`, {gameMode: commandT(`game_mode_${gameMode}`)});

const embeds = [];

const embed = new EmbedBuilder();
embeds.push(embed);

if (isNaN(accountId)) {
embed.setTitle(`❌ ${t('{{accountId}} is not a valid account id', {accountId})}`);
embed.setDescription(t('Make sure you have the right game mode active and that the profile has been viewed on [tarkov.dev](https://tarkov.dev/players).'));
embed.setFooter({text: gameModeLabel});
return interaction.editReply({
content: `❌ ${t('{{accountId}} is not a valid account id', {accountId})}`
embeds,
});
}
let profilePath = 'profile';
Expand Down Expand Up @@ -85,11 +96,6 @@ const defaultFunction = {

const dogtagItem = items.find(i => i.id === dogtagIds[profile.info.side]);

const embeds = [];

const embed = new EmbedBuilder();
embeds.push(embed);

// Construct the embed
embed.setTitle(`${profile.info.nickname} (${playerLevel} ${t(profile.info.side)})`);
embed.setThumbnail(dogtagItem.iconLink);
Expand All @@ -115,7 +121,6 @@ const defaultFunction = {
embed.setDescription(descriptionParts.join('\n'));
moment.locale(lang);
const updatedText = t('Updated {{updateTimeAgo}}', {updateTimeAgo: moment(new Date(profile.updated)).fromNow()});
const gameModeLabel = t(`Game mode: {{gameMode}}`, {gameMode: commandT(`game_mode_${gameMode}`)});
const footerText = `${updatedText} | ${gameModeLabel}`;

const statTypes = {
Expand All @@ -124,7 +129,7 @@ const defaultFunction = {
};
for (const statType in statTypes) {
const sideLabel = statTypes[statType];
const raidCount = profile[`${statType}Stats`].eft.overAllCounters.Items?.find(i => i.Key.includes('Sessions'))?.Value ?? 0
const raidCount = profile[`${statType}Stats`].eft.overAllCounters.Items?.find(i => i.Key.includes('Sessions'))?.Value ?? 0;
const raidsSurvived = profile[`${statType}Stats`].eft.overAllCounters.Items?.find(i => i.Key.includes('Survived'))?.Value ?? 0;
const raidsDied = profile[`${statType}Stats`].eft.overAllCounters.Items?.find(i => i.Key.includes('Killed'))?.Value ?? 0;
const raidSurvivalRatio = raidCount > 0 ? raidsSurvived / raidCount : 0;
Expand Down Expand Up @@ -158,6 +163,9 @@ const defaultFunction = {
if (!completed) {
continue;
}
if (achievementsEmbed.data.fields?.length >= 25) {
break;
}
achievementsEmbed.addFields(
{ name: achievement.name, value: completed.toLocaleString(lang), inline: true },
);
Expand Down
10 changes: 5 additions & 5 deletions commands/tier.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ const defaultFunction = {
.setTitle(t('Loot Tiers'))
.setDescription(`
${t('Loot tiers are divided primarily by the per-slot value of the item')}:
${t((await getPriceTier(tiers.legendary)).msg)}${tiers.legendary.toLocaleString(lang)}
${t((await getPriceTier(0, true)).msg)}
${t((await getPriceTier(tiers.great)).msg)}${tiers.great.toLocaleString(lang)}
${t((await getPriceTier(tiers.average)).msg)}${tiers.average.toLocaleString(lang)}
${t((await getPriceTier(tiers.average -1)).msg)} < ${tiers.average.toLocaleString(lang)}
${t((await getPriceTier(tiers.legendary, false, gameMode)).msg)}${tiers.legendary.toLocaleString(lang)}
${t((await getPriceTier(0, true, gameMode)).msg)}
${t((await getPriceTier(tiers.great, false, gameMode)).msg)}${tiers.great.toLocaleString(lang)}
${t((await getPriceTier(tiers.average, false, gameMode)).msg)}${tiers.average.toLocaleString(lang)}
${t((await getPriceTier(tiers.average -1, false, gameMode)).msg)} < ${tiers.average.toLocaleString(lang)}
`)
.setFooter({text: gameModeLabel});
return interaction.reply({ embeds: [embed] });
Expand Down
41 changes: 40 additions & 1 deletion modules/create-embed.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,7 @@ const createEmbed = {
}

// Calculate item tier
let tier = await lootTier(tierPrice / (item.width * item.height), item.types.includes('noFlea'));
let tier = await lootTier(tierPrice / (item.width * item.height), item.types.includes('noFlea'), gameMode);
embed.setColor(tier.color);
body += `• ${t('Item Tier')}: ${t(tier.msg)}\n`;

Expand Down Expand Up @@ -557,6 +557,45 @@ const createEmbed = {
}
return unlocksEmbed;
},
itemUsedInTasks: async (item, interaction, options = {}) => {
const { lang, gameMode } = options.interactionSettings ?? await progress.getInteractionSettings(interaction);
const t = getFixedT(lang);

const [ tasks ] = await Promise.all([
options.tasks ?? gameData.tasks.getAll({lang, gameMode}),
]);

const embed = new EmbedBuilder();

for (const task of tasks) {
let needed = task.objectives.some(obj => obj.requiredKeys?.some(keyOptions => keyOptions.some(k => k.id === item.id)));
needed = needed || task.objectives.some(obj => obj.items?.some(i => i.id === item.id));
if (!needed) {
continue;
}

let alternates = task.objectives.some(obj => obj.requiredKeys?.some(keyOptions => keyOptions.some(k => k.id === item.id) && keyOptions.length > 1));
alternates = alternates || task.objectives.some(obj => obj.items?.some(i => i.id === item.id) && obj.items.length > 1);
const fieldValueLines = [];
if (alternates) {
fieldValueLines.push(t('Has alternates'));
} else {
fieldValueLines.push(t('No alternates'));
}
const fir = task.objectives.some(obj => obj.items?.some(i => i.id === item.id) && obj.foundInRaid);
if (fir) {
fieldValueLines.push(t('Found in raid'));
}
embed.addFields({name: task.name, value: `[${fieldValueLines.join('\n')}](https://tarkov.dev/task/${task.normalizedName})`});
}
if (embed.data?.fields?.length > 0) {
embed.setTitle(`${t('Used in tasks')} 📋`);
} else {
embed.setTitle(`${t('Not used in any tasks')} 📋`);
}

return embed;
},
};

export default createEmbed;
65 changes: 45 additions & 20 deletions modules/game-data.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -330,13 +330,13 @@ export async function updateBosses() {
id
name
}`;
const response = await graphqlRequest({ graphql: query }).then(response => response.data);
const response = await graphqlRequest({ graphql: query });

if (gameData.bosses && response.errors?.length) {
return gameData.bosses;
}

gameData.bosses = response.bosses.map(boss => {
gameData.bosses = response.data.bosses.map(boss => {
return {
...boss,
health: boss.health ? boss.health.reduce((total, healthPart) => {
Expand All @@ -346,11 +346,11 @@ export async function updateBosses() {
}
});

for (const lang in response) {
for (const lang in response.data) {
if (lang === 'bosses') {
continue;
}
gameData.bossNames[lang] = response[lang].reduce((langData, boss) => {
gameData.bossNames[lang] = response.data[lang].reduce((langData, boss) => {
langData[boss.id] = boss;
return langData;
}, {});
Expand Down Expand Up @@ -405,17 +405,16 @@ export async function updateTraders() {
payRate
}
}`;
const response = await graphqlRequest({ graphql: query }).then(response => response.data);
const response = await graphqlRequest({ graphql: query });


if (!gameData.traders[gameMode]) {
gameData.traders[gameMode] = {};
}
for (const lang in response) {
for (const lang in response.data) {
if (gameData.traders[gameMode][lang] && response.errors?.length) {
continue;
}
gameData.traders[gameMode][lang] = response[lang];
gameData.traders[gameMode][lang] = response.data[lang];
}
}

Expand Down Expand Up @@ -475,15 +474,15 @@ export async function updateHideout() {
level
}
}`;
const response = await graphqlRequest({ graphql: query }).then(response => response.data);
const response = await graphqlRequest({ graphql: query });
if (!gameData.hideout[gameMode]) {
gameData.hideout[gameMode] = {};
}
for (const lang in response) {
for (const lang in response.data) {
if (gameData.hideout[gameMode][lang] && response.errors?.length) {
continue;
}
gameData.hideout[gameMode][lang] = response[lang];
gameData.hideout[gameMode][lang] = response.data[lang];
}
}

Expand Down Expand Up @@ -675,12 +674,12 @@ export async function updateItemNames() {
}
}
}`;
const response = await graphqlRequest({ graphql: query }).then(response => response.data);
for (const lang in response) {
const response = await graphqlRequest({ graphql: query });
for (const lang in response.data) {
if (gameData.itemNames[lang] && response.errors?.length) {
continue;
}
gameData.itemNames[lang] = response[lang].reduce((langData, item) => {
gameData.itemNames[lang] = response.data[lang].reduce((langData, item) => {
langData[item.id] = item;
return langData;
}, {});
Expand Down Expand Up @@ -938,17 +937,40 @@ export async function updateTasks() {
id
}
}
...on TaskObjectiveExtract {
requiredKeys {
id
}
}
...on TaskObjectiveItem {
id
count
foundInRaid
requiredKeys {
id
}
items {
id
}
}
...on TaskObjectiveMark {
requiredKeys {
id
}
}
...on TaskObjectivePlayerLevel {
playerLevel
}
...on TaskObjectiveQuestItem {
requiredKeys {
id
}
}
...on TaskObjectiveShoot {
count
requiredKeys {
id
}
}
...on TaskObjectiveSkill {
skillLevel {
Expand All @@ -964,6 +986,9 @@ export async function updateTasks() {
}
...on TaskObjectiveUseItem {
count
requiredKeys {
id
}
}
}
trader {
Expand All @@ -981,16 +1006,16 @@ export async function updateTasks() {
}
}
}`;
const response = await graphqlRequest({ graphql: query }).then(response => response.data);
const response = await graphqlRequest({ graphql: query });

if (!gameData.tasks[gameMode]) {
gameData.tasks[gameMode] = {};
}
for (const lang in response) {
for (const lang in response.data) {
if (gameData.tasks[gameMode][lang] && response.errors?.length) {
continue;
}
gameData.tasks[gameMode][lang] = response[lang];
gameData.tasks[gameMode][lang] = response.data[lang];
}
}

Expand Down Expand Up @@ -1079,12 +1104,12 @@ export async function updateAchievements() {
name
adjustedPlayersCompletedPercent
}`;
const response = await graphqlRequest({ graphql: query }).then(response => response.data);
for (const lang in response) {
const response = await graphqlRequest({ graphql: query });
for (const lang in response.data) {
if (gameData.achievements[lang] && response.errors?.length) {
continue;
}
gameData.achievements[lang] = response[lang];
gameData.achievements[lang] = response.data[lang];
}

eventEmitter.emit('updatedAchievements');
Expand Down
4 changes: 4 additions & 0 deletions modules/loot-tier.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ export async function updateTiers(items, gameMode = 'regular') {
// get prices per slot
const prices = [];
for (const item of items) {
if (item.types.includes('noFlea')) {
// ignore values of flea banned items since they have their own category
continue;
}
let price = Math.min(item.avg24hPrice ?? 0, item.lastLowPrice ?? 0);
for (const traderPrice of item.sellFor) {
if (traderPrice.vendor.normalizedName === 'flea-market') continue;
Expand Down
Loading

0 comments on commit 58e0ace

Please sign in to comment.