You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
88 lines
3.1 KiB
88 lines
3.1 KiB
import {
|
|
AbstractCharacterStatusCommand,
|
|
CharacterOptionTemplate,
|
|
type CharacterStatusOptions,
|
|
type GameCharacterData,
|
|
type LoadedCharacterData
|
|
} from './base.js';
|
|
import { ApplicationCommandType, type CommandContext, CommandOptionType, type SlashCreator } from 'slash-create';
|
|
import {type GameParty, saveParty} from '../character.js';
|
|
|
|
export class PartyCommand extends AbstractCharacterStatusCommand {
|
|
constructor(creator: SlashCreator, opts: CharacterStatusOptions) {
|
|
super(creator, {
|
|
...opts,
|
|
name: 'party',
|
|
description: 'Gets or sets the current party list.',
|
|
type: ApplicationCommandType.CHAT_INPUT,
|
|
guildIDs: process.env.DEVELOPMENT_GUILD_ID,
|
|
options: [
|
|
{
|
|
...CharacterOptionTemplate,
|
|
name: 'characters',
|
|
description: 'The name of the character(s) to become the current party. If not set, shows the party instead.',
|
|
required: false
|
|
},
|
|
{
|
|
type: CommandOptionType.BOOLEAN,
|
|
name: 'replace',
|
|
description:
|
|
'If true, the party is being entirely replaced, so show the character list instead of the delta.',
|
|
required: false
|
|
}
|
|
]
|
|
});
|
|
}
|
|
|
|
async process(
|
|
ctx: CommandContext,
|
|
{ characters, party }: { characters: Map<string, readonly GameCharacterData[]>; party: GameParty }
|
|
): Promise<
|
|
| readonly [string, LoadedCharacterData[]]
|
|
| readonly [string, LoadedCharacterData]
|
|
| readonly LoadedCharacterData[]
|
|
| LoadedCharacterData
|
|
| string
|
|
> {
|
|
const replace: boolean | undefined = ctx.options.replace;
|
|
const oldPartyMemberNames = party.activeParty;
|
|
const newPartyMemberData = characters.get('characters');
|
|
if (!newPartyMemberData || newPartyMemberData.length === 0) {
|
|
return [
|
|
`The current active party is:\n **${oldPartyMemberNames.join('**\n **')}**`,
|
|
(await this.loadCharacters(oldPartyMemberNames)).flatMap((c) => (c.success ? [c] : []))
|
|
];
|
|
}
|
|
const newPartyMemberNames = newPartyMemberData.map(c => c.name)
|
|
await saveParty(this.dataDir, {
|
|
...party,
|
|
activeParty: newPartyMemberNames,
|
|
})
|
|
const oldPartySet = new Set(oldPartyMemberNames);
|
|
const newPartySet = new Set(newPartyMemberNames);
|
|
const leftSet = new Set<string>();
|
|
for (const member of oldPartySet) {
|
|
if (!newPartySet.has(member)) {
|
|
leftSet.add(member);
|
|
}
|
|
}
|
|
const joinedSet = new Set<string>();
|
|
for (const member of newPartySet) {
|
|
if (!oldPartySet.has(member)) {
|
|
joinedSet.add(member);
|
|
}
|
|
}
|
|
const deltas = [
|
|
...Array.from(joinedSet).map((c) => `**${c}** joined the party.`),
|
|
...Array.from(leftSet).map((c) => `**${c}** left the party.`)
|
|
];
|
|
if (replace || deltas.length === 0 || (replace === false && deltas.length > newPartyMemberNames.length)) {
|
|
return [
|
|
`The active party is now:\n **${newPartyMemberData.map((c) => c.name).join('**\n **')}**`,
|
|
newPartyMemberData.flatMap((c) => (c.success ? [c] : []))
|
|
];
|
|
} else {
|
|
return [deltas.join('\n'), newPartyMemberData.flatMap((c) => (c.success ? [c] : []))];
|
|
}
|
|
}
|
|
}
|
|
|