Jump to content

Introducing Scripter's Rift API: Unlock Limitless Possibilities for Game Development


lucyx

Recommended Posts

Dear Developers,

We are thrilled to announce the release of our much-anticipated TypeScript/SR Lua API, now available to the public! With Scripter's Rift API, developers gain access to a powerful suite of tools designed to enhance game development and unleash their creativity.

Developer-Friendly Integration
Our API suite has been meticulously crafted with developers in mind, ensuring seamless integration with supported games and frameworks. Whether you're looking to create stunning graphical effects, control game mechanics, or implement custom behavior trees for characters, Scripter's Rift API empowers you to take your game development to new heights.

Sell your Scripts
Script Marketplace – a dedicated platform for developers to showcase and sell their scripts. It's never been easier to turn your passion for coding into a passive income stream.

Privacy
We prioritize the security and privacy of our sellers. That's why we offer comprehensive payment protection and full anonymity, ensuring your personal and financial information remains safe and secure.

Documentation
Ready to revolutionize your game development process? Dive into our comprehensive API documentation available at docs.scriptersrift.gg. It's a valuable resource that will guide you through every step of your development journey. (80% finished)

Moreover, we're excited to share our Core Framework, available at https://git.scriptersrift.gg/SRIFT/Core. Although it's not fully documented yet, we are actively working on providing complete documentation to further assist you in leveraging its power.

For a head start, check out our example repository at: https://git.scriptersrift.gg/lucyx/demo

Join us on this incredible adventure as we reshape game development together. Visit our developer panel at https://dev.scriptersrift.gg to get started.

Spoiler

1.png2.png


Scripter's Rift API – Where Imagination Meets Possibility.

Link to comment
Share on other sites

  • 3 months later...

Hello, dear developers!

We offer you a rich API to create custom scripts for our community that can be used in current and future games. With TypeScript and our own SR Lua implementation, we provide you with powerful tools. Let's dive together into the exciting world of game development and learn more about our capabilities!

Here is your chance to earn some extra income with small projects. We offer free access to all games, support you in acquiring games, and provide resources and technical support. Let's bring creative ideas to life together and be successful!

You can host your scripts either as Closed Source or share them as Open Source on our GitTea. In the future, we also plan to sell scripts to the community.

Our API supports TypeScript with CI builds and our own implementation (syntax) of Lua called SR Lua. You can find documentation on our website here. It's important to note that the entire Scripter's Rift Framework is open source, continually evolving, and we welcome new team members.

Now, apart from money and anonymity, what else can we offer you? Scripter's Rift aims to become one of the leading P2C providers. We invest a lot of time, money, and passion into our project and have learned from the mistakes of other providers (even though we are mistakenly associated with many idiots). We are aware of the risks of game hacking but also the fun of building an active community and the joy of contributing to something great. Our hope is to continue gaining your trust in the future and building a cool community together.

Today, I'd like to introduce you to three small community scripts that can give you insight into development with Scripters Rift.

GTA-Quick Finder

https://streamable.com/vc65y8

  • Just yesterday, we added a GTA-like Quick Picker that is currently only used to change the Item ESP. However, we are looking for more feedback from our community to expand this great feature (TargetSelector in Overwatch, Aimbot modes, what ideas do you have?)!

Source: Scripter's Rift Open-Source-Framework (GitTea)
Code:

Spoiler
import { Configurable, type ConfigPartial } from './configurable';


const MOUSE_THRESHOLD = 15;

const MOUSE_FRAME_MEMORY = 0.9;

const BUTTON_SPACING = 3;

const BUTTON_FADE_TIME = 250 * MS;

const BACKGROUND_FADE_TIME = 150 * MS;


export class GTACtrlOptions extends Configurable<GTACtrlOptions> {

    title: string = 'GTA Control';

    radius: number = 0;

    iconRadius: number = 0.025;

    titleSize: number = 26;

    descriptionSize: number = 22;

    alpha: number = 0.45;

    blurColor: Color = Color.WHITE.darken(0.45).alpha(0.35);

    blurDispersion: number = 2;

}


export interface GTACtrlButton {

    id: string;

    description: string;

    icon: number;

    color: Color;

    selected: boolean;

    changed: number;

}


export default class GTACtrl extends GTACtrlOptions {

    #buttons: GTACtrlButton[] = [];

    #value?: string;

    #inputStack: vec2 = vec2();

    #fn: number = 0;

    #started: number = 0;


    constructor(cfg?: ConfigPartial<GTACtrlOptions>) {

        super(KeysOf<GTACtrlOptions>());

        this.configure(cfg);

    }


    protected onConfigure(): void {

        this.title = Phrase.Translate(this.title);

    }


    /**

     * @param id returning value string

     * @param description description to display when selected

     * @param icon icon texture to show

     * @param color highlighting color

     */

    addButton(id: string, description: string, icon: number, color: Color) {

        this.#buttons.push({

            id,

            description: Phrase.Translate(description),

            icon,

            color,

            selected: false,

            changed: 0,

        });

        return this;

    }


    /**

     * remove all buttons

     */

    clear() {

        this.#value = undefined;

        this.#buttons = [];

    }


    /**

     *

     * @returns returns the selected button id if any

     */

    value(): string | undefined {

        return this.#value;

    }


    /**

     * @param gfx active Command Buffer

     * @returns returns true if the value has changed

     */

    render(gfx: CommandBuffer) {

        if (this.#buttons.length == 0) return false;


        // Compute activation animation.

        //

        const fn = Engine.GetFrameCount();

        if (fn != this.#fn + 1) {

            this.#started = Engine.Time();

            this.#inputStack = vec2();

        }

        this.#fn = fn;


        const fade = math.min(Engine.Time() - this.#started, BACKGROUND_FADE_TIME) / BACKGROUND_FADE_TIME;


        // Compute mouse input and get move direction.

        //

        Input.BlockMouse();

        this.#inputStack = this.#inputStack.mul(MOUSE_FRAME_MEMORY).add(Input.GetMouse(false).xy);

        const activationDir = this.#inputStack.length > MOUSE_THRESHOLD ? this.#inputStack.normal : undefined;


        // Initialize positioning.

        //

        const res = Graphics.GetResolution();

        const center = res.mul(0.5);

        const iconRadius = res.y * this.iconRadius;

        const numButtons = this.#buttons.length;

        const rotShift = (2 * math.pi) / numButtons;

        const minRadius = ((BUTTON_SPACING + iconRadius) * numButtons) / math.pi;

        const radius = math.max(res.y * (this.radius == 0 ? this.iconRadius * 3 : this.radius), minRadius);


        // Blur the background.

        //

        gfx.blurRect2D(

            vec2(),

            res,

            0.5,

            this.blurColor.alpha(this.blurColor.a * fade),

            math.lerp(6, 1, fade) * this.blurDispersion

        );


        // Compute buttons and return change.

        //

        let changed = false;

        let dir = vec2(0, 1);

        let count = 0;


        for (const button of this.#buttons) {

            // Compare button position with mouse move direction.

            //

            if (activationDir) {

                const selected = activationDir.fovTo(dir) < rotShift / 2;

                if (selected != button.selected) {

                    if (selected) this.#value = button.id;

                    button.selected = selected;

                    button.changed = Engine.Time();

                    changed = true;

                }

            }


            // Display text for selected button.

            //

            if (button.selected) {

                let p = center.sub(vec2(0, (this.titleSize + this.descriptionSize + 10) / 2));

                const cx = gfx.text2D(p, 0, this.title, this.titleSize, Color.WHITE, Text.BOLD | Text.VCENTER);

                p = p.add(vec2(0, cx.y + 10));

                gfx.text2D(p, 0, button.description, this.descriptionSize, Color.WHITE, Text.VCENTER);

            }


            // Button Animation.

            //

            let renderReady = true;

            if (fade != 1.0) {

                if (++count / numButtons > fade) renderReady = false;

            }


            // Render button.

            //

            if (renderReady) {

                this.#renderButton(gfx, this.alpha, iconRadius, button, center.add(dir.mul(radius)));

            }

            dir = dir.rotateBy(rotShift);

        }

        return changed;

    }


    #renderButton(gfx: CommandBuffer, alpha: number, radius: number, button: GTACtrlButton, pos: vec2) {

        const fade = math.min(Engine.Time() - button.changed, BUTTON_FADE_TIME) / BUTTON_FADE_TIME;

        gfx.circle2D(pos, 0.2, radius, button.color.alpha(button.selected ? fade : 1.0 - fade), 3);

        gfx.fillCircle2D(pos, 0.1, radius, Color.BLACK.alpha(alpha));


        const iconColor = Color.WHITE.alpha(0.25 + (button.selected ? fade * 0.75 : 0.75 - fade * 0.75));

        if (button.icon != Graphics.NULL_TEXTURE) {

            const sqr = math.sqrt(2 * radius * radius);

            gfx.fillRectRounded2D(pos.sub(vec2(sqr / 2, sqr / 2)), vec2(sqr, sqr), 0, radius / 2, iconColor, button.icon);

        } else {

            gfx.text2D(pos, 0, button.id, radius * 0.25, iconColor, Text.BOLD | Text.VCENTER | Text.HCENTER);

        }

    }

}

 

MakeFriends

  • Another example I'd like to introduce is our straightforward 'MakeFriends' script. With this, you can easily add other players or entities to the whitelist to prevent them from being recognized as enemies or targeted.

Source

Spoiler
import { Each } from '@SRift/Core/Aimbot';

import { OnCreate } from '@SRift/Core/Aimbot/service';

import * as TS from '@SRift/Core/Util/target-selector';

import { SetDefaultController, EspController, RenderTeamId } from '@SRift/Core/Visuals/Player/player-esp';


// Config

//

declare namespace Config {

    const MakeFriends: {

        Hotkey: VKey[];

    };

}


// Entity data.

//

interface MakeFriendData {

    isFriend: boolean;

}

export function GetMakeFriendData(e: Entity) {

    return e.data as MakeFriendData;

}


// States.

//

let lbuttonState: boolean = false;


// Target selector.

//

const FriendSelector = TS.Players().dead(false).team(Team.ENEMY).sortByFov();


// Select friends.

//

Event.OnRender(gfx => {

    // If hotkeys are pressed.

    //

    if (Input.TestKeys(Config.MakeFriends.Hotkey, false)) {

        // Block LButton.

        //

        Input.BlockKey(VKey.LBUTTON);


        // Pick closest player.

        //

        const target = FriendSelector.best();

        if (target) {

            // Get current friendship state.

            //

            const isFriend = GetMakeFriendData(target).isFriend;


            // Mark it.

            //

            gfx.drawIndicatorFor(

                target,

                isFriend ? (lbuttonState ? Color.RED : Color.RED.darken(0.1)) : lbuttonState ? Color.GREEN : Color.GREEN.darken(0.1)

            );


            // Ckeck for Lbutton click.

            //

            if (lbuttonState) {

                if (!Input.GetKey(VKey.LBUTTON, false)) {

                    lbuttonState = false;

                    GetMakeFriendData(target).isFriend = !isFriend;

                    if (!isFriend) {

                        Each(service => {

                            if (service.currentTarget == target) {

                                service.currentTarget = service.lockedTarget = undefined;

                            }

                        });

                    }

                }

            } else {

                if (Input.GetKey(VKey.LBUTTON, false)) {

                    lbuttonState = true;

                }

            }

        }

    }

});


// On aimbot setup extend the target selector to ignore friends.

//

OnCreate(service => {

    service.onServiceFinalize(service => {

        service.targetSelector.where('friend', e => !GetMakeFriendData(e).isFriend);

        service.targetRenderSelector.where('friend', e => !GetMakeFriendData(e).isFriend);

    });

}, Event.MAX_PRIORITY);


// Override player esp.

//

class FriendController extends EspController {

    getTeamId(e: Entity): RenderTeamId {

        const ores = super.getTeamId(e);

        if (ores != 'ALLY') {

            if (GetMakeFriendData(e).isFriend) return 'ALLY';

        }

        return ores;

    }

}

SetDefaultController(new FriendController());

 

Loot Finder

  • Another community script was released by a new user and aspiring developer. With this script, users can search for custom items and select them. It may not be perfect code, but it shows that everyone is capable of developing great things with our API. Image

da21ci64f07ee83dde13b4dacdd5be-135006.pn

Code:

Spoiler
import * as UI from "@SRift/Core/UI";

import * as BOX from "@SRift/Core/Util/boxlayout";

import * as MC from '@SRift/Core/UI/menu/constants';

import * as menumain from '@SRift/Core/UI/menu/main';

import * as pickupesp from '@SRift/Core/Visuals/Loot/pickup-esp';

import * as Console from '@SRift/Core/UI/util/console';

import {QueueConfigUpdate, Entries, FindConfigElement, InjectConfig, GetRawConfig, InjectDefaultConfig, ConfigContext } from '@SRift/Core/UI/util/config-manager';

import Radio from '@SRift/Core/UI/elements/radio';

import { HitTest, ConsumeClick, GetCursor } from '@SRift/Core/UI/menu/main';

import Button from '@SRift/Core/UI/util/button';

import * as CfgMgr from '@SRift/Core/UI/util/config-manager';

import Phrase2D from '@SRift/Core/Util/phrase';

/*

let keywords: string[] = [

    "breach", "C4", "key", "blackjack", "HDSN", "awm", "gevar", "mh6", "cover",

    "m24a3", "chey", "nbc", "filter", "gas", "m200", "m300", "seachest", "barrel",

    "mine", "torch", "hacksaw", "pick", "respirator", "m240", "nvg", "riflebag",

    "barbed", "remote", "m32", "m203", "m79", "LAW", "rocket", "rpg", "striker",

    "pipe", "screw", "nail"

]; // Array of keywords

*/

const TX_MyPanel = File.LoadTexture('Panel.png')[0];

let versionNumber: string = "\u{e024} Loot+ v0.73.9";

const defaultTextDepth = 0.5;

const pointerLineColor = Color.RED;

const textSize = 20;

const textSizelist = 14;

const textXpos = 20;

const excludedKeywords: string[] = ["bldr", "land", "staticobj", "base", "hat"]; // Array of keywords to exclude

let chosenValue : string  = "";

let shownonkeywords = true;

let shownonkeywordstext = shownonkeywords ? "true" : "false";

let focusMode: string = "false";

let focusModeWord: string;

let camViewProj: matrix;

let camInvViewProj: matrix;

let camPos: vec3 | undefined;


camPos = MC.CAM_DEF_POS.clone;

camViewProj = Matrix.LookAt(camPos, MC.CAM_LOOK).mul(MC.CAM_PROJ);

const UI_TO_WORLD_MAT = mat3x3(0, 1, 0, 0, 0, -1, 1, 0, 0);

let newItem = '';

let keyAvailable: { [key: number]: boolean } = {}; // Specify the type explicitly

let cooldown: { [key: number]: number } = {}; // Specify the type explicitly

const FrameBuffer = Graphics.CreateCommandBuffer();


let Position = vec2(-0.6, 0.6).toScreen();

let Scale = (Graphics.GetResolution().y * 0.75) / MC.CAM_ASPECT;

let Size = vec2(Scale, Scale * MC.CAM_ASPECT);

let cursorWorldDir: vec3;


let tooltipVisible = false;

let tooltipStartTime = Engine.Time();

let tooltipStartY = -50;

let tooltipCurrentY = 0;

let tooltipEndY = 250;

let tooltipDuration = 5000;

const hintFs = 19;

let TipPhrase: Phrase2D | undefined;


const hintPadding = vec2(10, 5);

const menuText = "\b \u{e3dd} Usage:\f \n - Hold \rFF0[Left Alt]\f to display loot. \n - Open menu to start typing a keyword. \n - After typing a keyword, press \rFF0[Enter]\f to add or \rFF0[shift]+[Enter]\f to remove. \n - When menu is open use \rFF0[Left Ctrl]\f to toggle between showing and hiding nonkeywords in list on left. \n - Press \rFF0[Right Ctrl]\f + \rFF0[Enter]\f after typing a word to make it the focus word. \n - Press \rFF0[UP Arrow]\f when menu is open to toggle focus mode. \n\n\u{f05a} Showing non keywords can be usefull because the display name is not always the same as entity name. \n\u{f05a} The keyword filter uses entity names.\n\u{f05a} Use numpad to input numbers. \n\u{f05a} Focus mode allows you to hide everything else and just search a single keyword while keeping your normal list in tact. \n When you're desperately searching for batteries for example.";

let CursorPosition: vec3;

let ShowTipUntil = Engine.Time() + 6000;

const menuKey: VKey[] = Config?.UI?.Hotkey ?? [];

const tooltiptext:string = `\u{e024} Open the menu to see Lootpicker options as well! \u{e024}`;

let LootPlusConfigData = {

    "keywords": "Default, values",

};

InjectDefaultConfig(LootPlusConfigData);


let config = GetRawConfig();

if (config.hasOwnProperty("keywords")) {

    chosenValue = config["keywords"];

} else {

    if(chosenValue == ""){

    chosenValue = "itwas, empty";

}

}

let configData: Array<{ name: string, value: string }> = [

    { name: "keywords", value: chosenValue },

];

function loadConfigNow(){

    config = GetRawConfig();

    if (config.hasOwnProperty("keywords")) {

        chosenValue = config["keywords"];

    }else {

        if(chosenValue == ""){

        chosenValue = "noconfig, found";

    }

    }

    return chosenValue;

}

function loadCustomNow(){

    config = GetRawConfig();

    if (config.hasOwnProperty("focusModeWord")) {

        focusModeWord = config["focusModeWord"];

    }


}

function loadCustomFocus(){

    let focusModeEnabled;

if (config.hasOwnProperty("Loot.LootPlus.Focus")) {

    focusModeEnabled = config["Loot.LootPlus.Focus"];

}else{focusModeEnabled = "false";}

return focusModeEnabled;

}

function loadAllConfigNow(gfx: CommandBuffer): string {

    const config = GetRawConfig();

    let arrayValues = "";

    let posY = 100; // Initial Y position


    if (config !== null && config !== undefined) {

        const keys = Object.keys(config);

        if (keys.length > 0) {

            arrayValues = "Config keys and values:\n";

            const textSize = 12; // Adjust textSize as needed


            for (const key of keys) {

                const value = config[key];

                arrayValues += `${key}: ${value}\n`;


                // Display key and value using text2D

                gfx.text2D(vec2(100, posY), 0, `${key}: ${value}`, textSize, Color.RED);

                posY += 12; // Adjust spacing between text elements

            }

        } else {

            arrayValues = "Config is empty";


            // Display message using text2D

            gfx.text2D(vec2(100, 100), 0, arrayValues, textSize, Color.RED);

        }

    } else {

        arrayValues = "Config not found";


        // Display message using text2D

        gfx.text2D(vec2(100, 100), 0, arrayValues, textSize, Color.RED);

    }


    return arrayValues;

}

function setFocusKeyword(keywordToAdd: string) {

    QueueConfigUpdate("focusModeWord", keywordToAdd);

 


}

function addKeyword(keywordToAdd: string) {

    const keywordsSetting = configData.find(setting => setting.name === "keywords");


    if (keywordsSetting) {

        const trimmedKeywordToAdd = keywordToAdd; // Remove leading and trailing spaces and commas

        const currentKeywords = keywordsSetting.value.split(', ');


        // Check if the updatedKeywords string is empty

        const updatedKeywords = currentKeywords.length > 0

            ? currentKeywords.join(', ') + ', ' + trimmedKeywordToAdd

            : trimmedKeywordToAdd;


        keywordsSetting.value = updatedKeywords;

        let LootPlusConfigData = {

            "keywords": keywordsSetting.value,

        };

        InjectDefaultConfig(LootPlusConfigData);

        QueueConfigUpdate("keywords", keywordsSetting.value);

        chosenValue = loadConfigNow();

    }

    return chosenValue;

}

function removeKeyword(keywordToRemove: string) {

    const keywordsSetting = configData.find(setting => setting.name === "keywords");


    if (keywordsSetting) {

        //const trimmedKeywordToRemove = keywordToRemove.replace(new RegExp("^[ ,]*(.*?)[ ,]*$"), '$1'); // Remove leading and trailing spaces and commas

        const trimmedKeywordToRemove = keywordToRemove;

        const currentKeywords = keywordsSetting.value.split(', ');

        const updatedKeywords = currentKeywords.filter(keyword => keyword !== trimmedKeywordToRemove).join(', ');

        const RightupdatedKeywords = updatedKeywords;

        keywordsSetting.value = RightupdatedKeywords;

        let LootPlusConfigData = {

            "keywords": keywordsSetting.value,

        };

   

        QueueConfigUpdate("keywords", keywordsSetting.value);

        chosenValue = loadConfigNow();

    }

    return chosenValue;

}

function ToWorld(x: number, y: number, z: number) {

    return vec3(z, x, -y);

}

function FromWorld(x: number, y: number, z: number) {

    return vec3(y, -z, x);

}

function WorldToScreen(vec: any): LuaMultiReturn<[vec2, number]> {

    vec = vec.product(camViewProj);

    vec *= 1 / vec.w;

    return $multi(Position.add(vec2(0.5 + vec.x * 0.5, 0.5 + vec.y * -0.5).mul(Size)), vec.z);

}

function UIToScreen(vec: vec3) {

    return WorldToScreen(ToWorld(vec.x, vec.y, vec.z));

}

function displayKeywordsOnScreen(gfx: CommandBuffer, keywords: string[], position: vec2, textSize: number) {

    let concatenatedKeywords = keywords.join(", ");

    gfx.text2D(position, 0.5, concatenatedKeywords, textSize, Color.WHITE);

}

/*

// Define a custom event emitter for console input


class ConsoleInputEventEmitter {

    private handlers: ((input: string) => void)[] = [];

 

    // Add a listener function to the event

    on(handler: (input: string) => void) {

      this.handlers.push(handler);

    }

 

    // Emit the event with the provided input

    emit(input: string) {

      for (const handler of this.handlers) {

        handler(input);

      }

    }

  }

 

  // Create an instance of the custom event emitter

  const onConsoleInput = new ConsoleInputEventEmitter();

 

  // Example usage

  onConsoleInput.on((input) => {


    //console.log(`Received console input: ${input}`);

  });

 

  // Simulate console input

  const userInput = "explosives";

  onConsoleInput.emit(userInput);

*/

function showTooltip() {

    tooltipVisible = true;

    tooltipStartTime = Engine.Time();

}

for (let keyCode = VKey.KB_A; keyCode <= VKey.KB_Z; keyCode++) {

    keyAvailable[keyCode] = true;

    cooldown[keyCode] = 0;

}

for (let i = VKey.NP_0; i <= VKey.NP_9; i++) {

    keyAvailable[i] = true;

    cooldown[i] = 0; // Set default cooldown value to 0

}


Event.OnKeyDown(t => {

    if (t == VKey.UP) {

        if(menumain.IsOpen()){

            if(focusMode === "true"){

                focusMode = "false";

                QueueConfigUpdate("Loot.LootPlus.Focus", "false");

                CfgMgr.Update("Loot.LootPlus.Focus","false");

            }else{

                focusMode = "true";

                QueueConfigUpdate("Loot.LootPlus.Focus", "true");

                CfgMgr.Update("Loot.LootPlus.Focus","true");

            }

   

        }


    }

    if (t == VKey.L_CTRL) {

        if(menumain.IsOpen()){

            if(shownonkeywords == true){

                shownonkeywords = false;

                //QueueConfigUpdate("Loot.LootPlus.Focus", "false");

                //CfgMgr.Update("Loot.LootPlus.Focus","false");

            }else{

                shownonkeywords = true;

                //QueueConfigUpdate("Loot.LootPlus.Focus", "true");

                //CfgMgr.Update("Loot.LootPlus.Focus","true");

            }

   

        }


    }

});

if(config.hasOwnProperty("focusModeWord")){

    focusModeWord = config["focusModeWord"];

}else{

    focusModeWord = "notsetyet";

}

if (config.hasOwnProperty("Loot.LootPlus.Focus")) {

    focusMode = config["Loot.LootPlus.Focus"]; // Retrieve value based on key

}

/// RENDER EVENT STARTS HERE RENDER EVENT STARTS HERE RENDER EVENT STARTS HERE RENDER EVENT STARTS HERE RENDER EVENT STARTS HERE RENDER EVENT STARTS HERE RENDER EVENT STARTS HERE RENDER EVENT STARTS HERE

// RENDER EVENT STARTS HERE RENDER EVENT STARTS HERE RENDER EVENT STARTS HERE RENDER EVENT STARTS HERE RENDER EVENT STARTS HERE RENDER EVENT STARTS HERE RENDER EVENT STARTS HERE RENDER EVENT STARTS HERE

// RENDER EVENT STARTS HERE RENDER EVENT STARTS HERE RENDER EVENT STARTS HERE RENDER EVENT STARTS HERE RENDER EVENT STARTS HERE RENDER EVENT STARTS HERE RENDER EVENT STARTS HERE RENDER EVENT STARTS HERE


Event.OnRender(gfx => {


shownonkeywordstext = shownonkeywords ? "true" : "false";


camPos = MC.CAM_DEF_POS.clone;

    const tipTimeLeft = ShowTipUntil - Engine.Time();

    if (tipTimeLeft > 0) {

        const hintFs = 19;

        const hintPos = vec2(0, 1).toScreen();

        const hintPadding = vec2(15, 5);

        const hintBgCol = [Color.SR_RED, Color.SR_RED, Color.SR_RED.darken(0.25), Color.SR_RED.darken(0.25)].map(c => c.alpha(0.85));


        if (!TipPhrase) {

            TipPhrase = Phrase2D.Create(tooltiptext,hintFs,Color.WHITE,Text.BOLD);

            TipPhrase.buff.fillRectRounded2D(hintPadding.neg(), TipPhrase.size.add(hintPadding.mul(2)), MC.PAGE_DEPTH, 3, hintBgCol);

        }

        const pos = hintPos.add(vec2(((-TipPhrase.size.x / 2)*3)-32, 15));

        pos.y -= 50 * (1 - Math.min(tipTimeLeft / 1000, 1));

        TipPhrase.draw(gfx, pos);

    }

    if (!camPos) {

        camPos = MC.CAM_DEF_POS.clone;

        CursorPosition = Position.add(Size.mul(0.5)).xyz;

    }


    const currentTime = Engine.Time();


    for (let keyCode = VKey.KB_A; keyCode <= VKey.KB_Z; keyCode++) {

        let tipTimeLeft = cooldown[keyCode] - Engine.Time();

        if (keyAvailable[keyCode] === false) {

            if (tipTimeLeft > 0) {

                // Handle any action during the cooldown period, if needed

            } else {

                keyAvailable[keyCode] = true;

            }

        }

        if (Input.GetKey(keyCode) && keyAvailable[keyCode] === true && menumain.IsOpen()) {

            newItem += String.fromCharCode('a'.charCodeAt(0) + (keyCode - VKey.KB_A));

            keyAvailable[keyCode] = false;

            cooldown[keyCode] = Engine.Time() + 500;

        }

    }

    for (let keyCode = VKey.NP_0; keyCode <= VKey.NP_9; keyCode++) {

        let tipTimeLeft = cooldown[keyCode] - Engine.Time();

        if (keyAvailable[keyCode] === false) {

            if (tipTimeLeft > 0) {

                // Handle any action during the cooldown period, if needed

            } else {

                keyAvailable[keyCode] = true;

            }

        }

        if (Input.GetKey(keyCode) && keyAvailable[keyCode] === true && menumain.IsOpen()) {

            newItem += String.fromCharCode('0'.charCodeAt(0) + (keyCode - VKey.NP_0));

            keyAvailable[keyCode] = false;

            cooldown[keyCode] = Engine.Time() + 500;

        }

    }

    if (Input.GetKey(VKey.ENTER)&& menumain.IsOpen() &&(!Input.GetKey(VKey.R_SHIFT)) && (!Input.GetKey(VKey.R_CTRL))) {

        if(newItem != ""){

        chosenValue += newItem;

        chosenValue = addKeyword(newItem);

        newItem = ''; // Clear the newItem string

        }

    }

    if (Input.GetKey(VKey.ENTER)&& menumain.IsOpen() &&(Input.GetKey(VKey.R_SHIFT)) && (!Input.GetKey(VKey.R_CTRL))) {

        if(newItem != ""){

        chosenValue += newItem;

        chosenValue = removeKeyword(newItem);

        newItem = ''; // Clear the newItem string

        }

    }

    if (Input.GetKey(VKey.BACKSPACE)&& menumain.IsOpen()) {

        if(newItem != ""){

            newItem = newItem.slice(0, -1);

        }


    }

    if (Input.GetKey(VKey.ENTER)&& menumain.IsOpen() &&(!Input.GetKey(VKey.R_SHIFT))&&(Input.GetKey(VKey.R_CTRL))) {

        if(newItem != ""){

        setFocusKeyword(newItem);

        focusModeWord = newItem;

        newItem = ''; // Clear the newItem string

        }

    }

    let realConfig = loadConfigNow()


    config = GetRawConfig();

    if (config.hasOwnProperty("keywords")) {

        chosenValue = config["keywords"]; // Retrieve value based on key

    }else {

        if(chosenValue == ""){

           // chosenValue = "breach, C4, key, blackjack, HDSN, awm, gevar, mh6, cover, m24a3, chey, nbc, filter, gas, m200, m300, seachest, barrel, mine, torch, hacksaw, pick, respirator, m240, nvg, riflebag, barbed, remote, m32, m203, m79, LAW, rocket, rpg, striker, pipe, screw, nail";

        chosenValue = "itwas, empty"

        }

    }

 

let keywordsSetting = configData.find(setting => setting.name === "keywords");

let DisplayWords: string = keywordsSetting?.value?.toString() || "";


let keywords: string[] =  DisplayWords.split(', ');

if(menumain.IsOpen()){

    showTooltip();


    if(shownonkeywords){shownonkeywordstext = "\b\r0F0\venabled\f";}else{shownonkeywordstext = "\b\rF00\vdisabled\f";}


    if (tooltipVisible && TipPhrase) { // Check if TipPhrase is defined

        if (tooltipCurrentY < tooltipEndY) {

            tooltipCurrentY += 8;

            //TipPhrase.draw(gfx, vec2(300, tooltipCurrentY)); // Adjust Y position based on animation

            gfx.text2D(vec2(450, ((40)-tooltipEndY)+tooltipCurrentY), 0, versionNumber, 22);

            gfx.text2D(vec2(750, ((40)-tooltipEndY)+tooltipCurrentY), 0,  "Show non keywords: "+shownonkeywordstext+" | FocusMode word is: \b\r0F0\v"+focusModeWord+"\f | activated: \b\r0F0\v"+focusMode+"\f", 15);

            gfx.text2D(vec2(450, ((140)-tooltipEndY)+tooltipCurrentY), 0, "\u{f11c} input: [ "+newItem+" ]", 24, Color.CORAL);

            gfx.fillRect2D(vec2(440, ((175)-tooltipEndY)+tooltipCurrentY), vec2(900,100), 0.7,Color.GRAY.alpha(0.9));

            gfx.fillRect2D(vec2(440, ((30)-tooltipEndY)+tooltipCurrentY), vec2(900,400), 0.8,Color.BLACK.alpha(0.9));

            gfx.fillRect2D(vec2(440, ((27)-tooltipEndY)+tooltipCurrentY), vec2(900,3), 0.9,Color.from('#e81542'));

            gfx.text2D(vec2(450, ((70)-tooltipEndY)+tooltipCurrentY), 0, "\u{f03a} Keywords: \r0F0\v"+DisplayWords+"\f", 15, Color.WHITE,0,105);

            gfx.text2D(vec2(450, ((185)-tooltipEndY)+tooltipCurrentY), 0, menuText, 14, Color.LIGHTGREY);


            if(tooltipCurrentY > tooltipEndY){


            }

        } else {

            //TipPhrase.draw(gfx, vec2(300, tooltipCurrentY)); // Adjust Y position based on animation

            gfx.text2D(vec2(450, 40), 0, versionNumber, 22);

            gfx.text2D(vec2(750, 40), 0, "Show non keywords: "+shownonkeywordstext+" | FocusMode word is: \b\r0F0\v"+focusModeWord+"\f | activated: \b\r0F0\v"+focusMode+"\f", 15);

            gfx.text2D(vec2(450, 140), 0, "\u{f11c} input: [ "+newItem+" ]", 24, Color.CORAL);

            gfx.fillRect2D(vec2(440, 175), vec2(900,100), 0.7,Color.GRAY.alpha(0.9));

            gfx.fillRect2D(vec2(440, 30), vec2(900,400), 0.8,Color.BLACK.alpha(0.9));

            gfx.fillRect2D(vec2(440, 27), vec2(900,3), 0.9,Color.from('#e81542'));

            gfx.text2D(vec2(450, 70), 0, "\u{f03a} Keywords: \r0F0\v"+DisplayWords+"\f", 15, Color.WHITE,0,105);

            gfx.text2D(vec2(450, 185), 0, menuText, 14, Color.LIGHTGREY);  


        }

    }

}

if((!menumain.IsOpen()) && tooltipCurrentY > 5){

    tooltipCurrentY = 0;

}

/*

if (Input.GetKey(VKey.R_ALT)) {

    Engine.Info("Right Alt Pressed!");

    const inventoryQuery: EntityFilter = { type: Entity.PLAYER };

    for (const entity of Entity.Query(inventoryQuery)) {

        Engine.Info("looping entities!");

        const name = entity.name;

        if (entity.isOnScreen) {

            Engine.Info("Entity is on screen!");


}



        }

    }

*/

    if (Input.GetKey(VKey.L_ALT)) {

        const itemNames: Set<string> = new Set();

        const query: EntityFilter = { type: Entity.PICKUP };

        let yPosition = 100; // Initial Y position


        for (const entity of Entity.Query(query)) {

            const name = entity.name; // Use entity.name instead of Entity.name

            if (entity.isOnScreen) {

                if (name && !itemNames.has(name)) {

                    if (

                        entity.subtype == Entity.PICKUP_ITEM && (!excludedKeywords.some(keyword => entity.name.toLowerCase().includes(keyword.toLowerCase())|| entity.name.toLowerCase().includes("baseitem"))

                        )

                    ) {

                        itemNames.add(name);

                        let textColor = Color.WHITE; // Default color

                        if (focusMode === "true") {


                            if(name.toLowerCase().includes(focusModeWord.toLowerCase())){

                                textColor = Color.RED; // Change color if name contains a keyword

           

                                let currentTextCoords = vec2(textXpos, yPosition);

                                let currentName = name.toString();

                                let curentTextSize = 17;

                                let currentDepth = defaultTextDepth;

                                let boxColor = Color.AQUA;


                                //gfx.text2D(currentTextCoords, currentDepth, currentName, curentTextSize, outlineColor);


                                let startPoint = entity.position.add(vec3(0, 0, 800));

                                gfx.line3D(startPoint, entity.position , pointerLineColor);


                                let screenPosition = WorldToScreen(entity.position);

                                let screenPositionB = UIToScreen(entity.position);


                                let legend = BOX.CreateBoxLayout(entity);

                           

                                // Calculate the size of the text

                                let textContentSize = Text.Calc(currentName, 18, 0, 0);


                                let textWidth = textContentSize.x;

                                let textHeight = textContentSize.y;


                                let rectPosition = currentTextCoords;

                                // Calculate the corner points of the rounded rectangle

                                let p1 = rectPosition;

                                let p2 = rectPosition.add(vec2(textWidth - 120, -150));

                                let p3 = rectPosition.add(vec2(textWidth + 40, textHeight + 40));

                                let p4 = rectPosition.add(vec2(0, textHeight + 40));


                                let boxYpos = yPosition-17;

                                let lineStartFrom = currentTextCoords.add(vec2(textWidth+20, 8));

                                let boxStartFrom = currentTextCoords.add(vec2(-15, -7));

                                // Draw the rounded rectangle

                           

                                //gfx.rect2D(p1, p3, 0.5, Color.RED);


                                let TrueDistance = Me.Entity?.position.distanceSq(entity.position)||0;

                                let shouldBeDistance = (Me.Entity?.position ?? Me.ViewOrigin).distanceSq(entity.position);

                           


                                let distanceContentSize = Text.Calc(`${(math.sqrt(TrueDistance) / M).toFixed(0)}`,17,0,0);

                                gfx.fillRectRounded2D(boxStartFrom, vec2(textWidth+40+distanceContentSize.x,textHeight+10), 0.4, 3,Color.BLACK);

                                gfx.text2D(vec2(textXpos+textWidth+10, yPosition), 0.2, `${(math.sqrt(TrueDistance) / M).toFixed(0)}`, 18, Color.AQUA);

                                gfx.line2D(lineStartFrom,vec2(legend.xm,legend.ym),currentDepth,boxColor,2)

                           

                            }

                           // textColor = Color.WHITE;

                        } else{

                        for (const keyword of keywords) {

                            if (name.toLowerCase().includes(keyword.toLowerCase())) {

                                textColor = Color.RED; // Change color if name contains a keyword

           

                                let currentTextCoords = vec2(textXpos, yPosition);

                                let currentName = name.toString();

                                let curentTextSize = 17;

                                let currentDepth = defaultTextDepth;

                                let boxColor = Color.AQUA;


                                //gfx.text2D(currentTextCoords, currentDepth, currentName, curentTextSize, outlineColor);


                                let startPoint = entity.position.add(vec3(0, 0, 800));

                                gfx.line3D(startPoint, entity.position , pointerLineColor);


                                let screenPosition = WorldToScreen(entity.position);

                                let screenPositionB = UIToScreen(entity.position);


                                let legend = BOX.CreateBoxLayout(entity);

                           

                                // Calculate the size of the text

                                let textContentSize = Text.Calc(currentName, 18, 0, 0);


                                let textWidth = textContentSize.x;

                                let textHeight = textContentSize.y;


                                let rectPosition = currentTextCoords;

                                // Calculate the corner points of the rounded rectangle

                                let p1 = rectPosition;

                                let p2 = rectPosition.add(vec2(textWidth - 120, -150));

                                let p3 = rectPosition.add(vec2(textWidth + 40, textHeight + 40));

                                let p4 = rectPosition.add(vec2(0, textHeight + 40));


                                let boxYpos = yPosition-17;

                                let lineStartFrom = currentTextCoords.add(vec2(textWidth+20, 8));

                                let boxStartFrom = currentTextCoords.add(vec2(-15, -7));

                                // Draw the rounded rectangle

                           

                                //gfx.rect2D(p1, p3, 0.5, Color.RED);


                                let TrueDistance = Me.Entity?.position.distanceSq(entity.position)||0;

                                let shouldBeDistance = (Me.Entity?.position ?? Me.ViewOrigin).distanceSq(entity.position);

                           


                                let distanceContentSize = Text.Calc(`${(math.sqrt(TrueDistance) / M).toFixed(0)}`,17,0,0);

                                gfx.fillRectRounded2D(boxStartFrom, vec2(textWidth+40+distanceContentSize.x,textHeight+10), 0.4, 3,Color.BLACK);

                                gfx.text2D(vec2(textXpos+textWidth+10, yPosition), 0.2, `${(math.sqrt(TrueDistance) / M).toFixed(0)}`, 18, Color.AQUA);

                                gfx.line2D(lineStartFrom,vec2(legend.xm,legend.ym),currentDepth,boxColor,2)


                                break; // Exit the loop as soon as a keyword is found

                            }

                        }

                    }

                        if(shownonkeywords){

                            gfx.text2D(vec2(textXpos, yPosition), 0.2, name.toString(), 18, textColor);

                            yPosition += 30; // Increment Y position by 15 pixels

                        }else{

                            if( textColor == Color.RED){

                                gfx.text2D(vec2(textXpos, yPosition), 0.2, name.toString(), 18, textColor);

                                yPosition += 50; // Increment Y position by 15 pixels

                            }

                       

                        }

                   

                   

                    }

                }

            }

        }

    }

});

 

Link to comment
Share on other sites

×
×
  • Create New...