Skip to content

Instantly share code, notes, and snippets.

@Pruxis
Last active August 5, 2023 21:57
Show Gist options
  • Save Pruxis/f73bbfd179eadc691efbaf42296818cf to your computer and use it in GitHub Desktop.
Save Pruxis/f73bbfd179eadc691efbaf42296818cf to your computer and use it in GitHub Desktop.
Prompt Manager for RedM
export interface PromptAttributes {
text: string;
// Use the native key hash to set the control
control: number;
mode?: "standard" | "hold" | "mash" | "mash_infinite";
mashAmount?: number;
// When using mash mode this function is called indefinitely, make sure to either handle this properly
// Or to utilise "once" from Lodash for example to make sure the function is only called once.
onSuccess: Function;
// Only called during mash mode.
onFail?: Function;
}
export type Prompt = PromptAttributes & {
id: number;
};
interface PromptGroup {
id: number;
name: string;
}
class PromptManager {
private tick: number = null;
private promptsInTick: Prompt[] = [];
protected static instance: PromptManager;
static getInstance(): PromptManager {
if (!PromptManager.instance) {
PromptManager.instance = new PromptManager();
}
return PromptManager.instance;
}
public createGroup(groupText: string): PromptGroup {
return {
id: GetRandomIntInRange(0, 0xffffff),
name: CreateVarString(10, "LITERAL_STRING", groupText),
};
}
public createPrompt(attributes: PromptAttributes): Prompt {
const str = CreateVarString(10, "LITERAL_STRING", attributes.text);
const prompt: any = PromptRegisterBegin();
PromptSetControlAction(prompt, attributes.control);
PromptSetText(prompt, str);
if (!attributes.mode || attributes.mode === "standard") PromptSetStandardMode(prompt, 1);
if (attributes.mode === "hold") PromptSetStandardizedHoldMode(prompt, 1);
if (attributes.mode === "mash") {
if (!attributes.mashAmount) throw new TypeError("mashAmount is required when using mash mode");
PromptSetMashAutoFillMode(prompt, 0, attributes.mashAmount);
}
if (attributes.mode === "mash_infinite") PromptSetMashIndefinitelyMode(prompt);
PromptRegisterEnd(prompt);
return { id: prompt, ...attributes };
}
public show(prompts: Prompt[], group?: PromptGroup) {
for (const prompt of prompts) {
PromptSetVisible(prompt.id, true);
PromptSetEnabled(prompt.id, true);
if (group) PromptSetGroup(prompt.id, group.id, null);
this.promptsInTick.push(prompt);
}
this.tick = setTick(() => {
if (group) PromptSetActiveGroupThisFrame(group.id, group.name as any, null, null, null, null);
for (const { id, mode = "standard", onSuccess, onFail } of this.promptsInTick) {
if (mode === "standard" && PromptHasStandardModeCompleted(id, 0)) onSuccess();
if (mode === "hold" && PromptHasHoldModeCompleted(id)) onSuccess();
if (mode === "mash" && PromptHasMashModeCompleted(id)) onSuccess();
if (mode === "mash" && PromptHasMashModeFailed(id) && onFail) onFail();
}
});
}
public hide(prompts: Prompt[]) {
for (const { id } of prompts) {
PromptSetVisible(id, false);
PromptSetEnabled(id, false);
const index = this.promptsInTick.findIndex((p) => p.id === id);
this.promptsInTick.splice(index, 1);
}
if (!this.promptsInTick.length) clearTick(this.tick);
}
public destroy(prompts: Prompt[]) {
prompts.forEach(({ id }) => {
const index = this.promptsInTick.findIndex((p) => p.id === id);
this.promptsInTick.splice(index, 1);
PromptDelete(id);
});
if (!!this.tick && this.promptsInTick.length) clearTick(this.tick);
}
}
export const promptManager = PromptManager.getInstance();
import { promptManager } from "@packages/shared/managers";
RegisterCommand(
"setPrompts",
async () => {
const promptGroup = promptManager.createGroup("test");
const eatPrompt = promptManager.createPrompt({
text: "eat",
control: 0x41ac83d1,
mode: "hold",
onSuccess: () => console.log("pressed eat"),
onFail: () => console.log("failed"),
});
const exit = promptManager.createPrompt({
text: "exit",
control: 0xadeaf48c,
mode: "hold",
onSuccess: () => console.log("pressed hold"),
onFail: () => console.log("failed"),
});
promptManager.show([eatPrompt, exit], promptGroup);
setTimeout(() => {
console.log("Hiding eat");
promptManager.hide([eatPrompt]);
}, 5000);
setTimeout(() => {
console.log("Showing eat");
promptManager.show([eatPrompt]);
}, 10000);
setTimeout(() => {
console.log("Hiding exit");
promptManager.hide([exit]);
}, 15000);
setTimeout(() => {
console.log("Destroy, never to use again");
promptManager.destroy([eatPrompt, exit]);
}, 20000);
},
false
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment