Code:
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
}
}
}
}
}
}
}
});