Recommended Posts

 

WHAT IS THIS?

Menu Builder is going to be an open source client-side menu builder. It's entirely meant for people who hate having to design menus and try to make them look good. It will act as an out of the box solution to put together menus that have custom functions. All menus you create will have unique text names that you can call from server-side to client-side to open.

MenuBuilder.OpenMenu("Test");

ie. Test being the name of our menu.

All menus can be initialized when a player joins the game and easily loaded by looking through an array of available menus.

It's also built around an easy to use grid system based on simple numbers.

Code:
var thisMenu: MenuBuilder.Menu = new MenuBuilder.Menu("ATM", 16, 16);

Syntax:
var thisMenu: MenuBuilder.Menu = new MenuBuilder.Menu("NameOfMenu", xGridSize, yGridSize);

WHY?

A lot of time spent developing is on stupid resources like nice looking menus. When in reality your code is suffering and you're spending more time on things looking nice. Fuck that. Write the code and write menus in mere minutes that perform basic functionalities that you need.

The amount of times I've refactored menus because they didn't meet my expectations is too damn high.

Opt out of designer issues and opt into great code.

WHERE CAN I GET IT?
https://github.com/Stuyk/OpenRageV/tree/master/menubuilder

You can view the test.js or test.ts to view examples on setting up your project. I expect most of you to have general purpose programming experience. You can figure it out from there.

Otherwise try PMing me if you have any issues. I respond to Discord the fastest.

Stuyk#6645

HOW DO I SEND YOU CRYPTOCURRENCY? (ERC-20 ONLY THO)

Spoiler

0x74a33Fd77fe2AE6348f1240B56AC5316929dc2cc

HOW THE HECK DO I USE IT?

Download the Menu Builder files off of Github. Install them into the 'client_packages/menubuilder' folder.

If you want to play with the Sandbox files create a folder in 'client_packages' called sandbox and place those in there.

Make sure to add the '.js' files to your 'index.js'

require('./menubuilder/menubuilder.js');
require('./sandbox/test.js');

Using Menu Builder for Javascript:

Just add the following to the top of a new file. Then you use 'MenuBuilder.' to access different properties

"use strict";
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
    result["default"] = mod;
    return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const MenuBuilder = __importStar(require("menubuilder/menubuilder")); // Import Menu Builder

Using Menu Builder for Typescript: (Recommended)

Just add the following to the top of a new file. Then you use 'MenuBuilder.' to access different properties

import * as MenuBuilder from "menubuilder/menubuilder"; // Import Menu Builder

Where to Build Your Menus?

Well this is an interesting problem. You mainly want to let them run once through a 'render' event so that they are generated properly. What do I mean by this though?

Well the menu needs to be added to an array or rather. All menus need to be added to an array at least once. We solve this by running all of your menus through a "render" event.

Here's a boilerplate for every file that will contain a menu ever.

var menuCreated: boolean = false;

// Create our menu right as the player joins the server.
mp.events.add("render", () => {
    if (!menuCreated) {
        menuCreated = true;
        createAMenu();
        return true;
    }  
});

function createAMenu() {
    var menuHolder = new MenuBuilder.Menu("Login", 16, 16);
    // Write the rest of your menu code here.
}

KNOWN ISSUES

- Does not currently support symbols for text input. With that comes limitations.

- drawText has limitations on length. Keep in mind that your text will get cut off.

MENU BUILDER RESOURCES:

Boiler Plate Code:

Spoiler
import * as MenuBuilder from "menubuilder/menubuilder"; // Import Menu Builder

// A boolean to cancel the render immediately.
var menusAdded: boolean = false;

// Start by adding a render event.
mp.events.add("render", () => {
    if (menusAdded === false) {
        menusAdded = true;

        // Call our myNewMenu Function to create our menus.
        myNewMenu();

        // Destroy our event.
        return true;
    }
});

var menuHolder = null;

// Build our menu in this function.
function myNewMenu() {
    menuHolder = new MenuBuilder.Menu("TestMenu", 16, 16);

    var panel = new MenuBuilder.Panel(menuHolder, 5, 5, 4, 1, "Hello World");

    var button = new MenuBuilder.Button(menuHolder, 5, 6, 4, 1, "Close");
    button.currentFunction = closeMenu;
}

// We need a way to open the menu. This is how.
function openMenu() {
    MenuBuilder.OpenMenu("TestMenu"); // The unique ID is used to open the menu.
}

function closeMenu() {
    MenuBuilder.CloseMenu();
}

// We're just going to use a player chat option to open this menu.
mp.events.add("playerChat", (msg) => {
    if (msg === "openSaysMe") {
        openMenu();
    }
});

// That's it. Add the .js version of this to our index and we're ready.

 

Login Screen:

j0p4tCv.png

Spoiler
import * as MenuBuilder from "menubuilder/menubuilder"; // Import Menu Builder

var menuHolder: any;
var menuCreated: boolean = false;

// Create our menu right as the player joins the server.
mp.events.add("render", () => {
    if (!menuCreated) {
        menuCreated = true;

        menuHolder = new MenuBuilder.Menu("Login", 16, 16);

        var panel = new MenuBuilder.Panel(menuHolder, 11, 11, 4, 1, "Login");

        var textInput = new MenuBuilder.InputPanel(menuHolder, 11, 12, 4, 1, 25);
        textInput.id = "username";
        textInput.inputText = "";

        var passInput = new MenuBuilder.InputPanel(menuHolder, 11, 13, 4, 1, 25);
        passInput.id = "password";
        passInput.inputMasked = true;
        textInput.inputText = "";

        var login = new MenuBuilder.Button(menuHolder, 11, 14, 2, 1, "Login");
        login.currentFunction = submitLogin;

        var register = new MenuBuilder.Button(menuHolder, 13, 14, 2, 1, "Register");
        register.currentFunction = submitRegister;
        return true; // Destroy this handler.
    }  
});

mp.events.add("playerChat", (msg) => {
    if (msg == "login") {
        openLoginMenu(); 
    }
});

function openLoginMenu() {
    MenuBuilder.OpenMenu("Login");
}

function submitLogin() {
    var username: MenuBuilder.InputPanel = menuHolder.RetrieveByID("username");
    var password: MenuBuilder.InputPanel = menuHolder.RetrieveByID("password");

    MenuBuilder.CloseMenu();

    mp.gui.chat.push(`Username: ${username.inputText} / Password: ${password.inputText}`)
}

function submitRegister() {
    var username: MenuBuilder.InputPanel = menuHolder.RetrieveByID("username");
    var password: MenuBuilder.InputPanel = menuHolder.RetrieveByID("password");

    MenuBuilder.CloseMenu();

    mp.gui.chat.push(`Username: ${username.inputText} / Password: ${password.inputText}`)
}

 

PinPad Code:

bSi4apt.png

Spoiler
var panelDisplay: any = null;

function myCustomPinPad() {
    var thisMenu: MenuBuilder.Menu = new MenuBuilder.Menu("Keycode", 16, 16);

    var panel = new MenuBuilder.Panel(thisMenu, 0, 9, 3, 1, "Keycode");

    panelDisplay = new MenuBuilder.Panel(thisMenu, 0, 10, 3, 1, "");

    var button = new MenuBuilder.Button(thisMenu, 0, 11, 1, 1, "9");
    button.currentFunction = updatePinCode;
    button.currentArgument = "9";

    button = new MenuBuilder.Button(thisMenu, 1, 11, 1, 1, "8");
    button.currentFunction = updatePinCode;
    button.currentArgument = "8";

    button = new MenuBuilder.Button(thisMenu, 2, 11, 1, 1, "7");
    button.currentFunction = updatePinCode;
    button.currentArgument = "7";

    button = new MenuBuilder.Button(thisMenu, 0, 12, 1, 1, "6");
    button.currentFunction = updatePinCode;
    button.currentArgument = "6";

    button = new MenuBuilder.Button(thisMenu, 1, 12, 1, 1, "5");
    button.currentFunction = updatePinCode;
    button.currentArgument = "5";

    button = new MenuBuilder.Button(thisMenu, 2, 12, 1, 1, "4");
    button.currentFunction = updatePinCode;
    button.currentArgument = "4";

    button = new MenuBuilder.Button(thisMenu, 0, 13, 1, 1, "3");
    button.currentFunction = updatePinCode;
    button.currentArgument = "3";

    button = new MenuBuilder.Button(thisMenu, 1, 13, 1, 1, "2");
    button.currentFunction = updatePinCode;
    button.currentArgument = "2";

    button = new MenuBuilder.Button(thisMenu, 2, 13, 1, 1, "1");
    button.currentFunction = updatePinCode;
    button.currentArgument = "1";

    button = new MenuBuilder.Button(thisMenu, 0, 14, 2, 1, "0");
    button.currentFunction = updatePinCode;
    button.currentArgument = "0";

    button = new MenuBuilder.Button(thisMenu, 2, 14, 1, 1, "X");
    button.currentFunction = removeFromEnd;

    button = new MenuBuilder.Button(thisMenu, 2, 15, 1, 1, "SUBMIT");
    button.currentFunction = pushPinCode;

    MenuBuilder.OpenMenu("Keycode");
}

function updatePinCode(input: string) {
    panelDisplay.text = panelDisplay.text + input;
}

function pushPinCode() {
    mp.gui.chat.push(`You put: ${panelDisplay.text}`);
    panelDisplay.text = "";
    MenuBuilder.CloseMenu();
}

function removeFromEnd() {
    panelDisplay.text = panelDisplay.text.slice(0, -1);
}

 

 

Edited by Stuyk
  • Like 5
  • Mask 1

Share this post


Link to post
Share on other sites

Updated with a double send issue. Fixed that and here's some PinPadCode

var panelDisplay: any = null;

function myCustomPinPad() {
    var thisMenu: MenuBuilder.Menu = new MenuBuilder.Menu("Keycode", 16, 16);

    var panel = new MenuBuilder.Panel(thisMenu, 0, 9, 3, 1, "Keycode");

    panelDisplay = new MenuBuilder.Panel(thisMenu, 0, 10, 3, 1, "");

    var button = new MenuBuilder.Button(thisMenu, 0, 11, 1, 1, "9");
    button.currentFunction = updatePinCode;
    button.currentArgument = "9";

    button = new MenuBuilder.Button(thisMenu, 1, 11, 1, 1, "8");
    button.currentFunction = updatePinCode;
    button.currentArgument = "8";

    button = new MenuBuilder.Button(thisMenu, 2, 11, 1, 1, "7");
    button.currentFunction = updatePinCode;
    button.currentArgument = "7";

    button = new MenuBuilder.Button(thisMenu, 0, 12, 1, 1, "6");
    button.currentFunction = updatePinCode;
    button.currentArgument = "6";

    button = new MenuBuilder.Button(thisMenu, 1, 12, 1, 1, "5");
    button.currentFunction = updatePinCode;
    button.currentArgument = "5";

    button = new MenuBuilder.Button(thisMenu, 2, 12, 1, 1, "4");
    button.currentFunction = updatePinCode;
    button.currentArgument = "4";

    button = new MenuBuilder.Button(thisMenu, 0, 13, 1, 1, "3");
    button.currentFunction = updatePinCode;
    button.currentArgument = "3";

    button = new MenuBuilder.Button(thisMenu, 1, 13, 1, 1, "2");
    button.currentFunction = updatePinCode;
    button.currentArgument = "2";

    button = new MenuBuilder.Button(thisMenu, 2, 13, 1, 1, "1");
    button.currentFunction = updatePinCode;
    button.currentArgument = "1";

    button = new MenuBuilder.Button(thisMenu, 0, 14, 2, 1, "0");
    button.currentFunction = updatePinCode;
    button.currentArgument = "0";

    button = new MenuBuilder.Button(thisMenu, 2, 14, 1, 1, "X");
    button.currentFunction = removeFromEnd;

    button = new MenuBuilder.Button(thisMenu, 2, 15, 1, 1, "SUBMIT");
    button.currentFunction = pushPinCode;

    MenuBuilder.OpenMenu("Keycode");
}

function updatePinCode(input: string) {
    panelDisplay.text = panelDisplay.text + input;
}

function pushPinCode() {
    mp.gui.chat.push(`You put: ${panelDisplay.text}`);
    panelDisplay.text = "";
    MenuBuilder.CloseMenu();
}

function removeFromEnd() {
    panelDisplay.text = panelDisplay.text.slice(0, -1);
}

Looks like this in-game:
bSi4apt.png

Share this post


Link to post
Share on other sites

New version out with debug options.

menu.debugMode = true

uKzr0Pn.png

Will help you figure out the position of your menus if you're struggling with it.

There is also a disable option for input boxes and buttons now.

myButton.disabled = true;

You can also assign and retrieve different panels / buttons / etc. by a unique id.

panel.id = "MyID";

var myItem = menu.RetrieveByID("MyID");

 

Share this post


Link to post
Share on other sites

just made a simple vehiclemod menu for development with it.

since i'm no real programmer it took me four hours, but it works.

love your menubuilder!

❤️

thanks for sharing

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.