import * as NativeUI from '../../libs/NativeUI'; import maleTops from "./male_tops.json"; import maleShoes from "./male_shoes.json"; import maleLegs from "./male_legs.json"; import maleUndershirts from "./male_undershirts.json"; import maleAccessoires from "./male_accessories.json"; import male_combination from "./male_torso_top_combination.json"; import femaleTops from "./female_tops.json"; import femaleShoes from "./female_shoes.json"; import femaleLegs from "./female_legs.json"; import femaleUndershirts from "./female_undershirts.json"; import femaleAccessoires from "./female_accessories.json"; import female_combination from "./female_torso_top_combination.json"; const UIMenu = NativeUI.Menu; const UIMenuItem = NativeUI.UIMenuItem; const UIMenuListItem = NativeUI.UIMenuListItem; const UIMenuCheckboxItem = NativeUI.UIMenuCheckboxItem; const BadgeStyle = NativeUI.BadgeStyle; const Point = NativeUI.Point; const ItemsCollection = NativeUI.ItemsCollection; const Color = NativeUI.Color; export default function clotheShopList(globalData: GlobalData) { const categoryTitles = { clothes: { 1: "Masks", 2: "Hair Styles", 3: "Torsos", 4: "Legs", 5: "Bags and Parachutes", 6: "Shoes", 7: "Accessories", 8: "Undershirts", 9: "Body Armors", 10: "Decals", 11: "Tops" }, props: { 0: "Hats", 1: "Glasses", 2: "Ears", 6: "Watches", 7: "Bracelets" } }; const localPlayer = mp.players.local; var playerPos; var myVar; let mainMenu = null; let categoryMenus = []; let clothingData = []; let currentMenuIdx = -1; let menuTransition = false; // workaround for ItemSelect event being called twice between menu transitions let lastClothing = null; function getClothingName(key, ClotheId, gender) { var textures = [] var comb; var tops; var undersh; var shoes; var legs; var acces; if (!gender) { comb = male_combination; tops = maleTops; undersh = maleUndershirts; shoes = maleShoes; legs = maleLegs; acces = maleAccessoires; } else { comb = female_combination; tops = femaleTops; undersh = femaleUndershirts; shoes = femaleShoes; legs = femaleLegs; acces = femaleAccessoires; } switch (key) { case 11: for (var i = 0; i < Object.keys(tops[ClotheId]).length; i++) { if (tops[ClotheId][i].Localized != "NULL") { for (var x = 0; x < Object.keys(comb.combination).length; x++) { if (comb.combination[x].Top == ClotheId) { for (var y = 0; y < Object.keys(undersh[comb.combination[x].Undershirt]).length; y++) { if (undersh[comb.combination[x].Undershirt][y].Localized != "NULL") { const newData = { id: i, data: [tops[ClotheId][i]], torso: [comb.combination[x].Torso], undershirt: [comb.combination[x].Undershirt, undersh[comb.combination[x].Undershirt][y], y] } textures.push(newData); } } } } } } break; case 6: for (var i = 0; i < Object.keys(shoes[ClotheId]).length; i++) { if (shoes[ClotheId][i].Localized != "NULL") { const newData = { id: i, data: [shoes[ClotheId][i]] } textures.push(newData); } } break; case 4: for (var i = 0; i < Object.keys(legs[ClotheId]).length; i++) { if (legs[ClotheId][i].Localized != "NULL") { const newData = { id: i, data: [legs[ClotheId][i]] } textures.push(newData); } } break; case 7: for (var i = 0; i < Object.keys(acces[ClotheId]).length; i++) { if (acces[ClotheId][i].Localized != "NULL") { const newData = { id: i, data: [acces[ClotheId][i]] } textures.push(newData); } } break; } return textures; } function addClothingItems(type, bannerSprite, key, value, gender) { var categoryMenu; var cloth = []; var tx = []; if (Object.keys(categoryMenus).length > 0) { for (var i = 0; i < categoryMenus.length; i++) { if (categoryMenus[i].slotIdx == key) { return; } } mainMenu.AddItem(new UIMenuItem(categoryTitles[type][key], `${type === "props" ? "Prop category." : "Clothing category."}`)); // Create category menu categoryMenu = new UIMenu("", categoryTitles[type][key].toUpperCase(), new Point(0, 0), bannerSprite.library, bannerSprite.texture); categoryMenu.Visible = false; } else { mainMenu.AddItem(new UIMenuItem(categoryTitles[type][key], `${type === "props" ? "Prop category." : "Clothing category."}`)); // Create category menu categoryMenu = new UIMenu("", categoryTitles[type][key].toUpperCase(), new Point(0, 0), bannerSprite.library, bannerSprite.texture); categoryMenu.Visible = false; } mainMenu.Item // Fill it for (const item of value) { if (item.ComponentId == key) { var txData = getClothingName(key, item.ClotheId, gender); for (const x of txData) { var itemDescription = (key === 11 ? mp.game.ui.getLabelText(x.undershirt[1].GXT) : "Clothing item."); if (itemDescription == "NULL") { itemDescription = "Clothing item."; } const tempItem = new UIMenuItem(mp.game.ui.getLabelText(x.data[0].GXT), itemDescription); tempItem.SetRightLabel(`${item.Price > 0 ? `$${item.Price}` : "FREE"}`); categoryMenu.AddItem(tempItem); cloth.push(item); tx.push(x); } } } categoryMenus.push({ menu: categoryMenu, type: type, slotIdx: Number(key), item: cloth, texture: tx }); } function submenuItemChangeHandler(newIndex) { const currentMenu = categoryMenus[currentMenuIdx]; const currentItem = currentMenu.item[newIndex]; const currentTexture = currentMenu.texture[newIndex].id; //const currentItem = clothingData[currentMenu.type][currentMenu.slotIdx][newIndex]; if (currentMenu.slotIdx == 11) { const currentTorso = currentMenu.texture[newIndex].torso[0]; const currentUndershirt = currentMenu.texture[newIndex].undershirt; mp.players.local.setComponentVariation(3, currentTorso, 0, 2); //set Torso mp.players.local.setComponentVariation(8, currentUndershirt[0], currentUndershirt[2], 2); //set Undershirt mp.players.local.setComponentVariation(currentMenu.slotIdx, currentItem.ClotheId, currentTexture, 2); //set Top } else { mp.players.local.setComponentVariation(currentMenu.slotIdx, currentItem.ClotheId, currentTexture, 2); } /* case "props": if (currentItem.drawable === -1) { localPlayer.clearProp(currentMenu.slotIdx); } else { localPlayer.setPropIndex(currentMenu.slotIdx, currentItem.drawable, currentItem.texture, true); } break; */ } function resetPreview() { if (lastClothing) { switch (lastClothing.type) { case "clothes": if (lastClothing.slotIdx == 11) { localPlayer.setComponentVariation(3, lastClothing.torso, 0, 2); localPlayer.setComponentVariation(8, lastClothing.undershirt[0], lastClothing.undershirt[1], 2); localPlayer.setComponentVariation(lastClothing.slotIdx, lastClothing.drawable, lastClothing.texture, 2); } else { localPlayer.setComponentVariation(lastClothing.slotIdx, lastClothing.drawable, lastClothing.texture, 2); } break; case "props": if (lastClothing.drawable === -1) { localPlayer.clearProp(lastClothing.slotIdx); } else { localPlayer.setPropIndex(lastClothing.slotIdx, lastClothing.drawable, lastClothing.texture, true); } break; } lastClothing = null; } } function myTimer() { let dist = mp.game.gameplay.getDistanceBetweenCoords(localPlayer.position.x, localPlayer.position.y, 0, playerPos.x, playerPos.y, 0, false); if (dist > 3) { clearInterval(myVar); resetPreview(); if (currentMenuIdx !== -1) categoryMenus[currentMenuIdx].menu.Close(); if (mainMenu && mainMenu.Visible) mainMenu.Close(); } } mp.events.add("clothesMenu:updateData", (jsonBannerSprite, jsonData, gender) => { if (!globalData.InMenu) { globalData.InMenu = true; playerPos = localPlayer.position; var bannerSprite = JSON.parse(jsonBannerSprite); var data = JSON.parse(jsonData); // Default menu banner if (bannerSprite == null) { bannerSprite = { library: "commonmenu", texture: "interaction_bgd" }; } else if (bannerSprite == 1) { bannerSprite = { library: "shopui_title_lowendfashion", texture: "shopui_title_lowendfashion" }; } else if (bannerSprite == 2) { bannerSprite = { library: "shopui_title_midfashion", texture: "shopui_title_midfashion" }; } else if (bannerSprite == 3) { bannerSprite = { library: "shopui_title_highendfashion", texture: "shopui_title_highendfashion" }; } // Hide the chat mp.gui.chat.show(false); // Reset some variables categoryMenus = []; currentMenuIdx = -1; menuTransition = false; lastClothing = null; // Create a new main menu mainMenu = new UIMenu("", "SELECT A CATEGORY", new Point(0, 0), bannerSprite.library, bannerSprite.texture); mainMenu.Visible = true; // Update clothingData clothingData = data; // Add clothes addClothingItems("clothes", bannerSprite, 11, data[0], gender); addClothingItems("clothes", bannerSprite, 4, data[1], gender); addClothingItems("clothes", bannerSprite, 6, data[2], gender); addClothingItems("clothes", bannerSprite, 7, data[3], gender); myVar = setInterval(myTimer, 100); // Add props // for (const [key, value] of Object.entries(clothingData.props)) addClothingItems("props", bannerSprite, key, value); // Submenu events for (const item of categoryMenus) { // Preview hovering item item.menu.IndexChange.on(submenuItemChangeHandler); // Buy hovering item item.menu.ItemSelect.on((selectedItem, itemIndex) => { if (menuTransition) { menuTransition = false; return; } const currentMenu = categoryMenus[currentMenuIdx]; const currentItem = currentMenu.item[itemIndex]; const currentTexture = currentMenu.texture[itemIndex].id; if (currentMenu.slotIdx == 11) { const currentTorso = currentMenu.texture[itemIndex].torso[0]; const currentUndershirt = currentMenu.texture[itemIndex].undershirt; var serverData = [currentMenu.slotIdx, currentTexture, currentItem.ClotheId, currentTorso, currentUndershirt[0], currentUndershirt[2], currentItem.Price]; if (lastClothing.drawable == currentItem.ClotheId && lastClothing.texture == currentTexture && lastClothing.undershirt[0] == currentUndershirt[0] && lastClothing.undershirt[1] == currentUndershirt[2]) { mp.game.audio.playSoundFrontend(1, "Hack_Failed", "DLC_HEIST_BIOLAB_PREP_HACKING_SOUNDS", true); } else { mp.events.callRemote("SERVER:BuyCharacterClothes", "clothe", JSON.stringify(serverData)); } } else { var serverData = [currentMenu.slotIdx, currentTexture, currentItem.ClotheId, -1, -1, -1, currentItem.Price]; if (lastClothing.drawable == currentItem.ClotheId && lastClothing.texture == currentTexture) { mp.game.audio.playSoundFrontend(1, "Hack_Failed", "DLC_HEIST_BIOLAB_PREP_HACKING_SOUNDS", true); } else { mp.events.callRemote("SERVER:BuyCharacterClothes", "clothe", JSON.stringify(serverData)); } } }); // Reset preview when player backs out of category menu item.menu.MenuClose.on(() => { resetPreview(); currentMenuIdx = -1; mainMenu.Visible = true; }); } // Main menu events mainMenu.ItemSelect.on((selectedItem, itemIndex) => { const nextMenu = categoryMenus[itemIndex]; const slot = Number(nextMenu.slotIdx); lastClothing = { type: nextMenu.type, slotIdx: slot, drawable: (nextMenu.type === "props" ? localPlayer.getPropIndex(slot) : localPlayer.getDrawableVariation(slot)), texture: (nextMenu.type === "props" ? localPlayer.getPropTextureIndex(slot) : localPlayer.getTextureVariation(slot)), undershirt: [localPlayer.getDrawableVariation(8), localPlayer.getTextureVariation(8)], torso: localPlayer.getDrawableVariation(3) }; currentMenuIdx = itemIndex; mainMenu.Visible = false; nextMenu.menu.Visible = true; menuTransition = true; submenuItemChangeHandler(nextMenu.menu.CurrentSelection); }); mainMenu.MenuClose.on(() => { globalData.InMenu = false; mp.gui.chat.show(true); currentMenuIdx = -1; lastClothing = null; }); } }); mp.events.add("clothesMenu:updateLast", (drawable, texture, undershirt, undershirtTexture, torso) => { if (lastClothing) { lastClothing.drawable = drawable; lastClothing.texture = texture; lastClothing.undershirt[0] = undershirt; lastClothing.undershirt[1] = undershirtTexture; lastClothing.torso = torso; } }); mp.events.add("clothesMenu:close", () => { if (currentMenuIdx !== -1) categoryMenus[currentMenuIdx].menu.Close(); if (mainMenu && mainMenu.Visible) mainMenu.Close(); }); mp.events.add("clothesMenu:Error", () => { mp.game.audio.playSoundFrontend(1, "Hack_Failed", "DLC_HEIST_BIOLAB_PREP_HACKING_SOUNDS", true); }); }