Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add /key and /item commands #312

Merged
merged 4 commits into from
Sep 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 2 additions & 71 deletions commands/barter.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { EmbedBuilder, SlashCommandBuilder } from 'discord.js';
import gameData from '../modules/game-data.mjs';
import progress from '../modules/progress-shard.mjs';
import { getFixedT, getCommandLocalizations } from '../modules/translations.mjs';
import createEmbed from '../modules/create-embed.mjs';

const MAX_BARTERS = 3;

Expand Down Expand Up @@ -74,77 +75,7 @@ const defaultFunction = {

for (let i = 0; i < matchedBarters.length; i = i + 1) {
const barter = barters.find(b => b.id === matchedBarters[i]);
let totalCost = 0;
const embed = new EmbedBuilder();

const rewardItem = items.find(it => it.id === barter.rewardItems[0].item.id);
let title = rewardItem.name;

if (barter.rewardItems[0].count > 1) {
title += " (" + barter.rewardItems[0].count + ")";
}

//title += `\r\n ${traders.find(tr => tr.id === barter.trader.id).name} ${t('LL')}${barter.level}${locked}`;
embed.setTitle(title);
embed.setURL(rewardItem.link);
const locked = prog.traders[barter.trader.id] < barter.level ? '🔒' : '';
const trader = traders.find(tr => tr.id === barter.trader.id);
embed.setAuthor({
name: `${trader.name} ${t('LL')}${barter.level}${locked}`,
iconURL: trader.imageLink,
url: `https://tarkov.dev/trader/${trader.normalizedName}`,
});

if (rewardItem.iconLink) {
embed.setThumbnail(rewardItem.iconLink);
}

for (const req of barter.requiredItems) {
const reqItem = items.find(i => i.id === req.item.id);
let itemCost = reqItem.avg24hPrice || 0;

if (reqItem.lastLowPrice > itemCost && reqItem.lastLowPrice > 0) {
itemCost = reqItem.lastLowPrice;
}

for (const offer of reqItem.buyFor) {
if (!offer.vendor.trader) {
continue;
}
let traderPrice = offer.priceRUB;

if ((traderPrice < itemCost && prog.traders[offer.vendor.trader.id] >= offer.vendor.minTraderLevel) || itemCost == 0) {
itemCost = traderPrice;
}
}

let bestSellPrice = 0;
for (const offer of reqItem.sellFor) {
if (!offer.vendor.trader) {
continue;
}
if (offer.priceRUB > bestSellPrice) {
bestSellPrice = offer.priceRUB;
}
}

let reqName = reqItem.name;
if (itemCost === 0) {
itemCost = bestSellPrice;

const isDogTag = req.attributes.some(att => att.name === 'minLevel');
if (isDogTag) {
const tagLevel = req.attributes.find(att => att.name === 'minLevel').value;
itemCost = bestSellPrice * tagLevel;
reqName += ' >= '+tagLevel;
}
}

totalCost += itemCost * req.count;
embed.addFields({name: reqName, value: itemCost.toLocaleString(lang) + "₽ x " + req.count, inline: true});
}

embed.addFields({name: t('Total'), value: totalCost.toLocaleString(lang) + "₽", inline: false});
const embed = await createEmbed.barter(barter, interaction, {items, traders, progress: prog, interactionSettings: {lang, gameMode}});

embeds.push(embed);

Expand Down
26 changes: 13 additions & 13 deletions commands/boss.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,39 +7,39 @@ import progress from '../modules/progress-shard.mjs';

const bossDetails = [
{
"name": "cultist-priest",
"id": "sectantPriest",
"details": "Sneaky bois. Cultists lurk in the shadows in groups of 3-5, waiting for a player to approach. They silently approach their enemies and stab them using either normal knives or, in case of the priests, the poisoned Cultist knife. If fired upon, the Cultists will return fire using firearms and grenades. After they attack a player with their knife, they may choose to run off into the woods again and return to the shadows.",
},
{
"name": "death-knight",
"id": "bossKnight",
"details": "The leader of 'The Goons'. Can spawn on many different maps.",
},
{
"name": "glukhar",
"id": "bossGluhar",
"details": "Glukhar and his many guards are extremely hostile. It's very unlikely to find success while fighting in any open areas. Small hallways and closed rooms are preferable. Glukhar and his guards are very accurate. Glukhar and his guards will stay near each other at all times and his guards will follow him to wherever he goes.",
},
{
"name": "killa",
"id": "bossKilla",
"details": "The true Giga Chad of Tarkov. Killa uses a light machine gun or other automatic weapon to suppress the enemy, while lurking from cover to cover, getting closer to his target for the final push. During the assault he moves in a zig-zag pattern, uses smoke and fragmentation grenades, and relentlessly suppresses enemies with automatic fire. He will follow his target large distances out of his patrol route, so be sure to run very far to get away from him if he has locked onto you.",
},
{
"name": "reshala",
"id": "bossBully",
"details": "He will normally try to stay at the back of the fight and hidden from the player's view. Additionally, he never wears armor. Be careful as a player scav, as if you are at lower scav karma levels Reshala or his guards may shoot you without provocation or will shoot you if you come to close to Reshala. His guards are sometimes known to give warnings to player scavs with low karma before becoming hostile.",
},
{
"name": "sanitar",
"id": "bossSanitar",
"details": "When engaged in combat, he will fight alongside his fellow scavs and guards, but may often break away to heal or inject himself. He has plenty of meds, so a prolonged engagement is possible.",
},
{
"name": "shturman",
"id": "bossKojaniy",
"details": "Shturman and his followers will engage the player at a long range protecting the sawmill area of the woods. They prefer to keep their distance, as they are not suited for close quarters combat.",
},
{
"name": "tagilla",
"id": "bossTagilla",
"details": "He is batshit insane and will attempt to hammer you down. However, if you are in a position that he cannot path-find to, such as the rafters, he will use his secondary weapon (usually a shotgun) to kill you from a distance. He's active immediately at the start of raid. The boss can set ambushes, open suppressive fire, and breach if needed.",
},
{
"name": "zryachiy",
"id": "bossZryachiy",
"details": "Lightkeeper's cultist sniper.",
}
];
Expand All @@ -65,7 +65,7 @@ const defaultFunction = {
const t = getFixedT(lang);

// Get the boss name from the command interaction
const bossName = interaction.options.getString('boss');
const bossId = interaction.options.getString('boss');

const bosses = await gameData.bosses.getAll({lang});

Expand All @@ -80,7 +80,7 @@ const defaultFunction = {
// Construct the embed
const embed = new EmbedBuilder();

const boss = bosses.find(b => b.normalizedName === bossName);
const boss = bosses.find(b => b.id === bossId);

// Add base fields to the embed
// Construct the description with boss details
Expand Down Expand Up @@ -139,7 +139,7 @@ const defaultFunction = {
embed.setURL(`https://tarkov.dev/boss/${boss.normalizedName}`);

for (const bossData of bossDetails) {
if (bossData.name === bossName) {
if (bossData.id === bossId) {
details = bossData.details;
//loot = boss.loot?.map(lootItem => items.find(i => i.id === lootItem.id)?.name).filter(Boolean).join(', ');
break;
Expand All @@ -157,7 +157,7 @@ const defaultFunction = {
const mapEmbeds = [];
for (const map of maps) {
// Only use the data for the boss specified in the command
const bossData = map.bosses.find(boss => boss.normalizedName === bossName);
const bossData = map.bosses.find(boss => boss.id === bossId);
if (!bossData) continue;

embed.setTitle(bossData.name);
Expand Down
89 changes: 4 additions & 85 deletions commands/craft.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { EmbedBuilder, SlashCommandBuilder } from 'discord.js';
import gameData from '../modules/game-data.mjs';
import progress from '../modules/progress-shard.mjs';
import { getFixedT, getCommandLocalizations } from '../modules/translations.mjs';
import createEmbed from '../modules/create-embed.mjs';

const MAX_CRAFTS = 2;

Expand Down Expand Up @@ -39,7 +40,7 @@ const defaultFunction = {

const matchedCrafts = [];

const [items, crafts, stations] = await Promise.all([
const [items, crafts, hideout] = await Promise.all([
gameData.items.getAll({lang, gameMode}),
gameData.crafts.getAll({gameMode}),
gameData.hideout.getAll({lang, gameMode}),
Expand Down Expand Up @@ -76,90 +77,8 @@ const defaultFunction = {

for (let i = 0; i < matchedCrafts.length; i = i + 1) {
const craft = crafts.find(c => c.id === matchedCrafts[i]);
let totalCost = 0;
const embed = new EmbedBuilder();
const toolsEmbed = new EmbedBuilder();
toolsEmbed.setTitle(`${t('Required Tools')} 🛠️`);
let toolCost = 0;

const rewardItem = items.find(it => it.id === craft.rewardItems[0].item.id)
let title = rewardItem.name;

if (craft.rewardItems[0].count > 1) {
title += " (" + craft.rewardItems[0].count + ")";
}

embed.setTitle(title);
embed.setURL(rewardItem.link);

const measuredTime = new Date(null);
let timeDiscount = prog.skills['crafting']*0.0075*craft.duration;
measuredTime.setSeconds(craft.duration - timeDiscount);
const locked = prog.hideout[craft.station.id] < craft.level ? '🔒' : '';
const station = stations.find(st => st.id === craft.station.id);
embed.setAuthor({
name: `${station.name} ${t('level')} ${craft.level} (${measuredTime.toISOString().substring(11, 19)})${locked}`,
iconURL: station.imageLink,
url: `https://tarkov.dev/hideout-profit/?all=true&station=${station.normalizedName}&search=${encodeURIComponent(rewardItem.name)}`,
});

if (rewardItem.iconLink) {
embed.setThumbnail(rewardItem.iconLink);
}

for (const req of craft.requiredItems) {
const reqItem = items.find(it => it.id === req.item.id);
let itemCost = reqItem.avg24hPrice || 0;

if (reqItem.lastLowPrice > itemCost && reqItem.lastLowPrice > 0) {
itemCost = reqItem.lastLowPrice;
}

for (const offer of reqItem.buyFor) {
if (!offer.vendor.trader) {
continue;
}

let traderPrice = offer.priceRUB;

if ((traderPrice < itemCost && prog.traders[offer.vendor.trader.id] >= offer.vendor.minTraderLevel) || itemCost == 0) {
itemCost = traderPrice;
}
}

let isTool = false;
for (let i = 0; i < req.attributes.length; i++) {
if (req.attributes[i].type === 'tool') {
isTool = true;
break;
}
}
if (isTool) {
toolCost += itemCost * req.count;
toolsEmbed.addFields({name: reqItem.name, value: itemCost.toLocaleString(lang) + "₽ x " + req.count, inline: true});
if(!toolsEmbed.thumbnail) {
toolsEmbed.setThumbnail(reqItem.iconLink);
}
continue;
}
let quantity = req.count;
// water filter consumption rate reduction
if (craft.station.id === '5d484fc8654e760065037abf' && reqItem.id === '5d1b385e86f774252167b98a') {
let time = prog.skills['crafting']*0.0075*quantity;
let consumption = prog.skills['hideoutManagement']*0.005*quantity;
quantity = Math.round((quantity - time - consumption) * 100) /100;
}
totalCost += itemCost * quantity;
//totalCost += req.item.avg24hPrice * req.count;
embed.addFields({name: reqItem.name, value: itemCost.toLocaleString(lang) + '₽ x ' + quantity, inline: true});
}
embed.addFields({name: t('Total'), value: totalCost.toLocaleString(lang) + '₽', inline: false});

embeds.push(embed);
if (toolsEmbed.data.fields?.length > 0) {
toolsEmbed.addFields({name: t('Total'), value: toolCost.toLocaleString(lang) + '₽', inline: false});
embeds.push(toolsEmbed);
}
embeds.push(await createEmbed.craft(craft, interaction, {items, hideout, progress: prog, interactionSettings: {lang, gameMode}}));

if (i == MAX_CRAFTS - 1) {
break;
Expand All @@ -177,7 +96,7 @@ const defaultFunction = {
for (let i = MAX_CRAFTS; i < matchedCrafts.length; i = i + 1) {
const craft = crafts.find(c => c.id === matchedCrafts[i]);
const rewardItem = items.find(it => it.id === craft.rewardItems[0].item.id);
const station = stations.find(s => s.id === craft.station.id);
const station = hideout.find(s => s.id === craft.station.id);
const bitemname = `[${rewardItem.name}](${rewardItem.link}) (${station.name} level ${craft.level})`;

if (bitemname.length + 4 + otheritems.length > 2048) {
Expand Down
2 changes: 1 addition & 1 deletion commands/goons.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const defaultFunction = {
gameData.goonReports.get({gameMode})
]);
const reportsEmbed = new EmbedBuilder();
const goons = bosses.find(b => b.normalizedName === 'death-knight');
const goons = bosses.find(b => b.id === 'bossKnight');
if (goons) {
reportsEmbed.setThumbnail(goons.imagePortraitLink);
}
Expand Down
Loading
Loading