-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Nathaniel Moschkin
committed
Nov 1, 2023
1 parent
5353e81
commit 8d6342b
Showing
9 changed files
with
360 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,217 @@ | ||
import { Message, EmbedBuilder, ApplicationCommandOptionType } from 'discord.js'; | ||
import yargs from 'yargs'; | ||
|
||
import { DCData } from '../data/DCData'; | ||
import { formatSources, formatRecipe, appelate, getItemBonuses } from '../utils/items'; | ||
import { colorFromRarity, formatCollectionName, formatCurrentStatLine, formatSkillsStatsWithEmotes, formatStatLine } from '../utils/crew'; | ||
import { getEmoteOrString, sendAndCache } from '../utils/discord'; | ||
import CONFIG from '../utils/config'; | ||
import { applyCrewBuffs, loadFullProfile, loadProfile, toTimestamp, userFromMessage } from '../utils/profile'; | ||
import { getNeededItems } from '../utils/equipment'; | ||
import { PlayerCrew } from '../datacore/player'; | ||
import { EquipmentItem } from '../datacore/equipment'; | ||
import { rarityLabels } from '../datacore/game-elements'; | ||
|
||
function bonusName(bonus: string) { | ||
let cfg = CONFIG.STATS_CONFIG[Number.parseInt(bonus)]; | ||
if (cfg) { | ||
return `${CONFIG.SKILLS[cfg.skill as Definitions.SkillName]} ${cfg.stat}`; | ||
} else { | ||
return `*unknown (${bonus})*`; | ||
} | ||
} | ||
|
||
async function asyncHandler( | ||
message: Message, | ||
crewman?: string | ||
) { | ||
// This is just to break up the flow and make sure any exceptions end up in the .catch, not thrown during yargs command execution | ||
await new Promise<void>(resolve => setImmediate(() => resolve())); | ||
|
||
let user = await userFromMessage(message); | ||
let settings = user?.profiles[0] ? await loadProfile(user.profiles[0].dbid) : null; | ||
let profile = user?.profiles[0] ? loadFullProfile(user.profiles[0].dbid) : null; | ||
if (!user || !profile) { | ||
sendAndCache(message, "Sorry, I couldn't find an associated profile for your user.") | ||
return; | ||
} | ||
if (crewman?.length) { | ||
crewman = crewman.toLowerCase().trim(); | ||
} | ||
|
||
let botCrew = DCData.getBotCrew(); | ||
let quipment = DCData.getItems().filter((item: Definitions.Item) => item.type === 15 || item.type === 14); | ||
|
||
let profileCrew = profile.player.character.crew; | ||
let profileItems = profile.player.character.items; | ||
let quippedCrew = profileCrew.filter((c: PlayerCrew) => { | ||
if (!!c.kwipment?.length) { | ||
if (crewman?.length) { | ||
let bcrew = botCrew.find(f => f.symbol===c.symbol); | ||
if (!bcrew) return false; | ||
if (!bcrew?.name.toLowerCase().trim().includes(crewman)) return false; | ||
} | ||
c.kwipment_items = (c.kwipment.map(kw => quipment.find(q => q.kwipment_id?.toString() === kw[1].toString()))?.filter(chk => !!chk) ?? []) as Definitions.Item[]; | ||
return true; | ||
} | ||
else { | ||
return false; | ||
} | ||
}) | ||
.map((crew: PlayerCrew) => { | ||
let matched = botCrew.find((crew) => { | ||
return crew.symbol === crew.symbol | ||
}) as Definitions.BotCrew; | ||
crew = JSON.parse(JSON.stringify(crew)); | ||
crew.name = matched?.name ?? crew.name; | ||
crew.bigbook_tier = matched?.bigbook_tier; | ||
crew.date_added = new Date(crew.date_added); | ||
if (settings) crew.base_skills = applyCrewBuffs(crew.base_skills, settings.buffConfig); | ||
return crew; | ||
}) | ||
.sort((a: PlayerCrew, b: PlayerCrew) => { | ||
let r = 0; | ||
if (!r) r = (b.kwipment_items?.length ?? 0) - (a.kwipment_items?.length ?? 0); | ||
if (!r) r = (b.max_rarity - a.max_rarity); | ||
if (!r) r = (a.bigbook_tier - b.bigbook_tier); | ||
if (!r) r = a.symbol.localeCompare(b.symbol); | ||
return r; | ||
}); | ||
if (!quippedCrew?.length) { | ||
if (crewman){ | ||
sendAndCache(message, `Couldn't find any quipped crew in your profile that matches '${crewman}'. If you think this is a mistake, please update your profile, and try again.`) | ||
return; | ||
} | ||
else { | ||
sendAndCache(message, "Couldn't find any quipped crew in your profile. If you think this is a mistake, please update your profile, and try again.") | ||
return; | ||
} | ||
} | ||
const embeds = [] as EmbedBuilder[]; | ||
quippedCrew.slice(0, 5).forEach((can: PlayerCrew) => { | ||
const matched = botCrew.find((crew) => { | ||
return crew.symbol === can.symbol | ||
}) as Definitions.BotCrew; | ||
|
||
if (!matched) { | ||
return; | ||
} | ||
|
||
let embed = new EmbedBuilder() | ||
.setTitle(`${matched.name}`) | ||
.setDescription(`Current Quipment`) | ||
.setThumbnail(`${CONFIG.ASSETS_URL}${matched.imageUrlPortrait}`) | ||
.setColor(colorFromRarity(matched.max_rarity)) | ||
.addFields( | ||
// { | ||
// name: 'Rarity', | ||
// value: '⭐'.repeat(can.rarity) + '🌑'.repeat(matched.max_rarity - can.rarity), | ||
// inline: false | ||
// }, | ||
{ | ||
name: `Immortalized Stats`, | ||
value: formatCurrentStatLine(message, { ... matched, ...can }), | ||
inline: false | ||
}, | ||
{ | ||
name: `Quipped Stats`, | ||
value: formatSkillsStatsWithEmotes(message, can.skills), | ||
inline: false | ||
} | ||
) | ||
|
||
if (can.kwipment_items?.length) { | ||
if (!!crewman) { | ||
embeds.push(embed); | ||
for (let quip of can.kwipment_items) { | ||
let b = getItemBonuses(quip as EquipmentItem).bonuses as Definitions.Skills; | ||
|
||
embed = new EmbedBuilder() | ||
.setTitle(`${quip.name}`) | ||
.setDescription(quip.flavor) | ||
.setThumbnail(`${CONFIG.ASSETS_URL}${quip.imageUrl}`) | ||
.setColor(colorFromRarity(quip.rarity)) | ||
|
||
embed = embed.addFields( { | ||
name: `Buffs`, | ||
value: formatSkillsStatsWithEmotes(message, b), | ||
inline: false | ||
}, | ||
{ | ||
name: "Rarity", | ||
value: ((quip.rarity ? '⭐'.repeat(quip.rarity ?? 0) : '')), | ||
inline: true | ||
}, | ||
{ | ||
name: "Duration", | ||
value: `${quip.duration} h`, | ||
inline: true | ||
}, | ||
{ | ||
name: "Equippable By", | ||
value: `${rarityLabels[(quip.max_rarity_requirement ?? 1) - 1]} crew`, | ||
inline: true | ||
}); | ||
if (quip.traits_requirement?.length) { | ||
embed = embed.addFields({ | ||
name: 'Required Traits', | ||
value: `${quip.traits_requirement?.map(t => appelate(t)).join(` ${quip.traits_requirement_operator} `)}`, | ||
inline: false | ||
}); | ||
} | ||
embeds.push(embed); | ||
} | ||
} | ||
else { | ||
for (let quip of can.kwipment_items) { | ||
let b = getItemBonuses(quip as EquipmentItem).bonuses as Definitions.Skills; | ||
|
||
embed = embed.addFields({ | ||
name: quip.name, | ||
value: ((quip.rarity ? '⭐'.repeat(quip.rarity ?? 0) : '')) + formatSkillsStatsWithEmotes(message, b) + `\nDuration: ${quip.duration} h` + | ||
((!!quip.traits_requirement?.length) ? `\nTraits: ${quip.traits_requirement?.map(t => appelate(t)).join(` ${quip.traits_requirement_operator} `)}` : '') + | ||
`\nEquippable by ${rarityLabels[(quip.max_rarity_requirement ?? 1) - 1]} crew` | ||
|
||
}) | ||
} | ||
embeds.push(embed); | ||
} | ||
} | ||
|
||
|
||
}); | ||
|
||
sendAndCache(message, | ||
`Currently quipped crew in **${user.profiles[0].captainName}**'s roster (last updated ${toTimestamp(profile.lastModified ?? user.profiles[0].lastUpdate)})`, | ||
{ embeds } | ||
); | ||
|
||
} | ||
|
||
class Quipment implements Definitions.Command { | ||
name = 'quip'; | ||
command = 'quip [crew]'; | ||
aliases = []; | ||
describe = 'Shows currently quipped crew'; | ||
options = [{ | ||
name: 'crew', | ||
type: ApplicationCommandOptionType.String, | ||
description: 'show quipment stats for the specified crew', | ||
required: false | ||
}] | ||
|
||
builder(yp: yargs.Argv): yargs.Argv { | ||
return yp.option('crew', { | ||
alias: 'c', | ||
desc: 'show quipment stats for the specified crew' | ||
}); | ||
} | ||
|
||
handler(args: yargs.Arguments) { | ||
let message = <Message>args.message; | ||
let crew = args.crew as string; | ||
args.promisedResult = asyncHandler(message, crew); | ||
} | ||
} | ||
|
||
export let QuipmentCommand = new Quipment(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.