Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit c0d44b4

Browse files
committedJul 3, 2024·
Rework the auto complete and fix the set knockback for all characters
1 parent ff5ae61 commit c0d44b4

File tree

6 files changed

+117
-36
lines changed

6 files changed

+117
-36
lines changed
 

‎src/commands/character-command.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { injectable } from 'inversify';
22
import { Command } from './command';
33
import { SlashCommandBuilder, CommandInteraction, CacheType } from 'discord.js';
4-
import { charactersChoices } from './utils/character-options';
54
import { Search } from '../data/search';
65
import { CharacterEmbedCreator } from '../embeds/character-embed-creator';
76

@@ -17,11 +16,7 @@ export class CharacterCommand implements Command {
1716
.setName('character')
1817
.setDescription('Get the information about a specific character.')
1918
.addStringOption((option) =>
20-
option
21-
.setName('character')
22-
.setDescription('The character to look for')
23-
.setRequired(true)
24-
.addChoices(...charactersChoices)
19+
option.setName('character').setDescription('The character to look for').setRequired(true).setAutocomplete(true)
2520
);
2621
return [builder];
2722
}

‎src/commands/frame-data-command.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ export class FrameDataCommand implements Command {
3131
.addStringOption((option) =>
3232
option.setName('character').setDescription('The character to get the move for').setRequired(true).setAutocomplete(true)
3333
)
34-
.addStringOption((option) => option.setName('move').setDescription('The move to look for').setRequired(true));
34+
.addStringOption((option) =>
35+
option.setName('move').setDescription('The move to look for').setRequired(true).setAutocomplete(true)
36+
);
3537
return [builder];
3638
}
3739
async handleCommand(interaction: CommandInteraction<CacheType>): Promise<void> {

‎src/commands/knockback-command.ts

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { SlashCommandBuilder, CommandInteraction, CacheType, InteractionResponse } from 'discord.js';
22
import { Command } from './command';
3-
import { charactersChoices } from './utils/character-options';
43
import { inject, injectable } from 'inversify';
54
import { Logger } from 'winston';
65
import { Symbols } from '../config/symbols';
@@ -26,18 +25,13 @@ export abstract class KnockbackCommand implements Command {
2625
.setName(name)
2726
.setDescription('Get the crouch cancel info for a move')
2827
.addStringOption((option) =>
29-
option
30-
.setName('character')
31-
.setDescription('The character executing the move')
32-
.setRequired(true)
33-
.addChoices(...charactersChoices)
28+
option.setName('character').setDescription('The character executing the move').setRequired(true).setAutocomplete(true)
3429
)
35-
.addStringOption((option) => option.setName('move').setDescription('The move to look for').setRequired(true))
3630
.addStringOption((option) =>
37-
option
38-
.setName('target')
39-
.setDescription('The character being attacked')
40-
.addChoices(...charactersChoices)
31+
option.setName('move').setDescription('The move to look for').setRequired(true).setAutocomplete(true)
32+
)
33+
.addStringOption((option) =>
34+
option.setName('target').setDescription('The character being attacked').setAutocomplete(true)
4135
);
4236
return builder;
4337
});

‎src/data/search.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,10 @@ export class Search {
108108
foundMoves.push({ move: move, distance: distance });
109109
}
110110

111+
console.log(foundMoves);
112+
113+
foundMoves.sort(this.sortDistanceResults);
114+
111115
if (foundMoves.length === 0) {
112116
return new SearchResult(SearchResultType.MoveNotFound, foundAlias.record.character);
113117
}

‎src/embeds/knockback-embed-creator.ts

Lines changed: 46 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export abstract class KnockbackEmbedCreator extends BaseEmbedCreator {
4141
const characterEmote = CharacterEmoji.getEmoteId(character.normalizedName);
4242
const targetEmote = CharacterEmoji.getEmoteId(target.normalizedName);
4343
embedBuilder.setTitle(`${characterEmote} ${character.name} - ${move.name} vs ${target.name} ${targetEmote} `);
44-
for (const hitbox of move.hitboxes) {
44+
for (const hitbox of move.hitboxes.sort(this.orderHitboxes)) {
4545
if (hitbox.angle > 179 && hitbox.angle != 361) {
4646
hitboxMap.set(hitbox.name, `Can not be ${this.shortTerm} due to angle being higher than 179 (${hitbox.angle})`);
4747
} else if (hitbox.angle === 0) {
@@ -65,8 +65,7 @@ export abstract class KnockbackEmbedCreator extends BaseEmbedCreator {
6565
private createForAll(character: Character, move: Move, embedBuilder: EmbedBuilder, dataLoader: Loader): EmbedBuilder[] {
6666
const characterEmote = CharacterEmoji.getEmoteId(character.normalizedName);
6767
embedBuilder.setTitle(`${characterEmote} ${character.name} - ${move.name}`);
68-
69-
for (const hitbox of move.hitboxes) {
68+
for (const hitbox of move.hitboxes.sort(this.orderHitboxes)) {
7069
if (hitbox.angle > 179 && hitbox.angle != 361) {
7170
embedBuilder.addFields({
7271
name: hitbox.name,
@@ -76,17 +75,8 @@ export abstract class KnockbackEmbedCreator extends BaseEmbedCreator {
7675
} else if (hitbox.angle === 0) {
7776
embedBuilder.addFields({ name: hitbox.name, value: `Can not be ${this.shortTerm} due to angle being 0` });
7877
continue;
79-
} else if (hitbox.setKnockback && hitbox.setKnockback < this.knockbackTarget) {
80-
embedBuilder.addFields({
81-
name: hitbox.name,
82-
value: `Can not break ${this.longTerm} due to the hitbox having low set knockback`,
83-
});
84-
continue;
8578
} else if (hitbox.setKnockback) {
86-
embedBuilder.addFields({
87-
name: hitbox.name,
88-
value: `Can not be ${this.shortTerm} due to the hitbox having high set knockback`,
89-
});
79+
this.addSetKnockbackField(embedBuilder, hitbox, dataLoader);
9080
continue;
9181
}
9282

@@ -141,4 +131,47 @@ export abstract class KnockbackEmbedCreator extends BaseEmbedCreator {
141131
private orderCharacters(characterOne: Character, characterTwo: Character): number {
142132
return characterOne.name.localeCompare(characterTwo.name);
143133
}
134+
135+
private orderHitboxes(hitboxOne: Hitbox, hitboxTwo: Hitbox): number {
136+
return hitboxOne.name.localeCompare(hitboxTwo.name, undefined, { numeric: true, sensitivity: 'base' });
137+
}
138+
139+
private addSetKnockbackField(embedBuilder: EmbedBuilder, hitbox: Hitbox, dataLoader: Loader): void {
140+
const succeedsArray: Character[][] = [[], []];
141+
for (const character of dataLoader.data
142+
.filter((character) => character.characterStatistics.weight > 0)
143+
.sort(this.orderCharacters)) {
144+
if (!CrouchCancelCalculator.meetsKnockbackTarget(hitbox, character, this.knockbackTarget)) {
145+
succeedsArray[0].push(character);
146+
} else {
147+
succeedsArray[1].push(character);
148+
}
149+
}
150+
151+
if (succeedsArray[0].length == 0) {
152+
embedBuilder.addFields({
153+
name: hitbox.name,
154+
value: `Can never be ${this.shortTerm} by all characters.`,
155+
});
156+
return;
157+
} else if (succeedsArray[1].length == 0) {
158+
embedBuilder.addFields({
159+
name: hitbox.name,
160+
value: `Can always be ${this.shortTerm} by all characters.`,
161+
});
162+
return;
163+
}
164+
165+
const canText =
166+
`**Can always be ${this.shortTerm} by:**\n` +
167+
succeedsArray[0].map((character) => CharacterEmoji.getEmoteId(character.normalizedName)).join(' ');
168+
const canNotText =
169+
`**Can never be ${this.shortTerm} by:**\n` +
170+
succeedsArray[1].map((character) => CharacterEmoji.getEmoteId(character.normalizedName)).join(' ');
171+
172+
embedBuilder.addFields({
173+
name: hitbox.name,
174+
value: canText + '\n' + canNotText,
175+
});
176+
}
144177
}
Lines changed: 58 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,80 @@
11
import { inject, injectable } from 'inversify';
22
import { BaseInteractionHandler } from './base-interaction-handler';
3-
import { AutocompleteInteraction, Client } from 'discord.js';
3+
import { ApplicationCommandOptionChoiceData, AutocompleteInteraction, Client } from 'discord.js';
44
import { Logger } from 'winston';
55
import { Symbols } from '../config/symbols';
66
import { FailureStore } from '../data/failure-store';
77
import { Search } from '../data/search';
8+
import { Loader } from '../data/loader';
9+
import { SearchResultType } from '../models/search/search-result-type';
10+
import { Move } from '../models/move';
11+
import { ReadableStreamDefaultController } from 'stream/web';
812

913
@injectable()
1014
export class AutoCompleteInteractionHandler extends BaseInteractionHandler {
1115
constructor(
1216
search: Search,
1317
@inject(Symbols.Logger) logger: Logger,
1418
failureStore: FailureStore,
15-
@inject(Symbols.Client) private client: Client
19+
@inject(Symbols.Client) private client: Client,
20+
private loader: Loader
1621
) {
1722
super(search, logger, failureStore);
1823
}
1924

2025
async handle(autoCompleteInteraction: AutocompleteInteraction): Promise<void> {
21-
const focusedValue = autoCompleteInteraction.options.getFocused();
22-
const characters = this.search.searchForCharacter(focusedValue.split(' '));
23-
await autoCompleteInteraction.respond(
26+
const focusedValue = autoCompleteInteraction.options.getFocused(true);
27+
if (focusedValue.name === 'move') {
28+
await this.handleMoveInteraction(autoCompleteInteraction);
29+
return;
30+
}
31+
32+
await this.handleCharacterInteraction(autoCompleteInteraction);
33+
}
34+
35+
private async handleMoveInteraction(autoCompleteInteraction: AutocompleteInteraction): Promise<void> {
36+
const focusedValue = autoCompleteInteraction.options.getFocused(true);
37+
const characterText = autoCompleteInteraction.options.getString('character', true);
38+
const result = this.search.search(characterText + ' ' + focusedValue.value);
39+
40+
if (result.type === SearchResultType.Move) {
41+
let moves: Move[];
42+
if (result.possibleMoves && result.possibleMoves.length > 0) {
43+
moves = result.possibleMoves;
44+
} else {
45+
moves = [result.move];
46+
}
47+
await this.respond(
48+
autoCompleteInteraction,
49+
moves.map((move) => ({
50+
name: move.name,
51+
value: move.normalizedName,
52+
}))
53+
);
54+
55+
return;
56+
}
57+
58+
await this.respond(autoCompleteInteraction, []);
59+
}
60+
61+
private async handleCharacterInteraction(autoCompleteInteraction: AutocompleteInteraction): Promise<void> {
62+
const focusedValue = autoCompleteInteraction.options.getFocused(true);
63+
const characters = this.search.searchForCharacter(focusedValue.value.split(' '));
64+
await this.respond(
65+
autoCompleteInteraction,
2466
characters.map((character) => ({ name: character.name, value: character.normalizedName }))
2567
);
2668
}
69+
70+
private async respond(
71+
autoCompleteInteraction: AutocompleteInteraction,
72+
options: ApplicationCommandOptionChoiceData<string>[]
73+
): Promise<void> {
74+
if (options.length > 25) {
75+
options = options.slice(0, 25);
76+
}
77+
78+
await autoCompleteInteraction.respond(options);
79+
}
2780
}

0 commit comments

Comments
 (0)
Please sign in to comment.