// shitcode will be better in the future // , \u00dc, \u00fc // , \u00c4, \u00e4 // , \u00d6, \u00f6 // \u00df import * as NativeUI from '../libs/NativeUI'; import * as Data from './data'; const Menu = 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; var screenRes = mp.game.graphics.getScreenResolution(0, 0); const creatorCoords = { camera: new mp.Vector3(402.8664, -997.5515, -98.5), cameraLookAt: new mp.Vector3(402.8664, -996.4108, -98.5) }; const surgeryCoords = { camera: new mp.Vector3(265.6026, -1340.2378, 25.000), cameraLookAt: new mp.Vector3(266.472, -1339.1357, 25.000) }; const localPlayer = mp.players.local; export default function charCreator(globalData: IGlobalData) { var creatorHairMenu; function getRandomInt(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; } function colorForOverlayIdx(index) { let color; switch (index) { case 1: color = beardColorItem.Index; break; case 2: color = eyebrowColorItem.Index; break; case 5: color = blushColorItem.Index; break; case 8: color = lipstickColorItem.Index; break; case 10: color = chestHairColorItem.Index; break; default: color = 0; } return color; } function updateParents() { localPlayer.setHeadBlendData( // shape Data.mothers[motherItem.Index], Data.fathers[fatherItem.Index], 0, // skin Data.mothers[motherItem.Index], Data.fathers[fatherItem.Index], 0, // mixes similarityItem.Index * 0.01, skinSimilarityItem.Index * 0.01, 0.0, false ); } function updateFaceFeature(index) { localPlayer.setFaceFeature(index, parseFloat(featureItems[index].SelectedValue)); } function updateAppearance(index) { let overlayID = (appearanceItems[index].Index === 0) ? 255 : appearanceItems[index].Index - 1; localPlayer.setHeadOverlay(index, overlayID, appearanceOpacityItems[index].Index * 0.01, colorForOverlayIdx(index), 0); } function updateHairAndColors() { localPlayer.setComponentVariation(2, Data.hairList[currentGender][hairItem.Index].ID, 0, 2); localPlayer.setHairColor(hairColorItem.Index, hairHighlightItem.Index); localPlayer.setEyeColor(eyeColorItem.Index); localPlayer.setHeadOverlayColor(1, 1, beardColorItem.Index, 0); localPlayer.setHeadOverlayColor(2, 1, eyebrowColorItem.Index, 0); localPlayer.setHeadOverlayColor(5, 2, blushColorItem.Index, 0); localPlayer.setHeadOverlayColor(8, 2, lipstickColorItem.Index, 0); localPlayer.setHeadOverlayColor(10, 1, chestHairColorItem.Index, 0); } function applyCreatorOutfit() { if (currentGender === 0) { localPlayer.setDefaultComponentVariation(); localPlayer.setComponentVariation(3, 15, 0, 2); localPlayer.setComponentVariation(4, 21, 0, 2); localPlayer.setComponentVariation(6, 34, 0, 2); localPlayer.setComponentVariation(8, 15, 0, 2); localPlayer.setComponentVariation(11, 15, 0, 2); } else { localPlayer.setDefaultComponentVariation(); localPlayer.setComponentVariation(3, 15, 0, 2); localPlayer.setComponentVariation(4, 10, 0, 2); localPlayer.setComponentVariation(6, 35, 0, 2); localPlayer.setComponentVariation(8, 15, 0, 2); localPlayer.setComponentVariation(11, 15, 0, 2); } } function fillHairMenu() { hairItem = new UIMenuListItem("Haar", "Deine Haare", new ItemsCollection(Data.hairList[currentGender].map(h => h.Name))); creatorHairMenu.AddItem(hairItem); hairColorItem = new UIMenuListItem("Haarfarbe", "Deine Haarfarbe", new ItemsCollection(hairColors)); creatorHairMenu.AddItem(hairColorItem); hairHighlightItem = new UIMenuListItem("Haarstr\u00e4hnen", "Farbe deiner Haarstr\u00e4hnen", new ItemsCollection(hairColors)); creatorHairMenu.AddItem(hairHighlightItem); eyebrowColorItem = new UIMenuListItem("Augenbrauen Farbe", "Farbe deiner Augenbrauen", new ItemsCollection(hairColors)); creatorHairMenu.AddItem(eyebrowColorItem); beardColorItem = new UIMenuListItem("Farbe der Gesichtsbehaarung", "Farbe deiner Gesichtsbehaarung", new ItemsCollection(hairColors)); creatorHairMenu.AddItem(beardColorItem); eyeColorItem = new UIMenuListItem("Augenfarbe", "Farbe deiner Augen", new ItemsCollection(Data.eyeColors)); creatorHairMenu.AddItem(eyeColorItem); blushColorItem = new UIMenuListItem("Rouge", "Farbe des Rouges.", new ItemsCollection(blushColors)); creatorHairMenu.AddItem(blushColorItem); lipstickColorItem = new UIMenuListItem("Lippenstift Farbe", "Farbe deines Lippenstifts.", new ItemsCollection(lipstickColors)); creatorHairMenu.AddItem(lipstickColorItem); chestHairColorItem = new UIMenuListItem("Farbe der Brustbehaarung", "Farbe deiner Brustbehaarung", new ItemsCollection(hairColors)); creatorHairMenu.AddItem(chestHairColorItem); creatorHairMenu.AddItem(new UIMenuItem("Zuf\u00e4llig", "~r~Zuf\u00e4lliges Haar & Farben")); creatorHairMenu.AddItem(new UIMenuItem("Zur\u00fccksetzen", "~r~Zur\u00fccksetzen von Haar & Farben")); } function resetParentsMenu(refresh = false) { fatherItem.Index = 0; motherItem.Index = 0; similarityItem.Index = (currentGender === 0) ? 100 : 0; skinSimilarityItem.Index = (currentGender === 0) ? 100 : 0; updateParents(); if (refresh) creatorParentsMenu.RefreshIndex(); } function resetFeaturesMenu(refresh = false) { for (let i = 0; i < Data.featureNames.length; i++) { featureItems[i].Index = 100; updateFaceFeature(i); } if (refresh) creatorFeaturesMenu.RefreshIndex(); } function resetAppearanceMenu(refresh = false) { for (let i = 0; i < Data.appearanceNames.length; i++) { appearanceItems[i].Index = 0; appearanceOpacityItems[i].Index = 100; updateAppearance(i); } if (refresh) creatorAppearanceMenu.RefreshIndex(); } function resetHairAndColorsMenu(refresh = false) { hairItem.Index = 0; hairColorItem.Index = 0; hairHighlightItem.Index = 0; eyebrowColorItem.Index = 0; beardColorItem.Index = 0; eyeColorItem.Index = 0; blushColorItem.Index = 0; lipstickColorItem.Index = 0; chestHairColorItem.Index = 0; updateHairAndColors(); if (refresh) creatorHairMenu.RefreshIndex(); } let currentGender = 0; let creatorMenus: NativeUI.Menu[] = []; let creatorCamera: CameraMp; // color arrays let hairColors = []; for (let i = 0; i < Data.maxHairColor; i++) hairColors.push(i.toString()); let blushColors = []; for (let i = 0; i < Data.maxBlushColor; i++) blushColors.push(i.toString()); let lipstickColors = []; for (let i = 0; i < Data.maxLipstickColor; i++) lipstickColors.push(i.toString()); // CREATOR MAIN let creatorMainMenu = new Menu("Charaktererstellung", "", new Point(0, screenRes.y / 3), null, null); let genderItem = new UIMenuListItem("Geschlecht", "~r~Dies setzt deine Einstellungen zur\u00fcck.", new ItemsCollection(["M\u00e4nnlich", "Weiblich"])); creatorMainMenu.AddItem(genderItem); creatorMainMenu.AddItem(new UIMenuItem("Eltern", "Eltern des Charakters.")); creatorMainMenu.AddItem(new UIMenuItem("Gesichtsmerkmale", "Gesichtsmerkmale des Charakters.")); creatorMainMenu.AddItem(new UIMenuItem("Aussehen", "Aussehen des Charakters.")); creatorMainMenu.AddItem(new UIMenuItem("Haar & Farben", "Haare & Farben deines Charakters.")); let angles = []; for (let i = -180.0; i <= 180.0; i += 5.0) angles.push(i.toFixed(1)); let angleItem = new UIMenuListItem("Drehung", "", new ItemsCollection(angles)); creatorMainMenu.AddItem(angleItem); let saveItem = new UIMenuItem("Erstellen", "Erstellt deinen Charakter."); saveItem.BackColor = new Color(13, 71, 161); saveItem.HighlightedBackColor = new Color(25, 118, 210); creatorMainMenu.AddItem(saveItem); //let cancelItem = new UIMenuItem("Abbrechen", "Setzt alle \u00c4nderungen zur\u00fcck."); //cancelItem.BackColor = new Color(213, 0, 0); //cancelItem.HighlightedBackColor = new Color(229, 57, 53); //creatorMainMenu.AddItem(cancelItem); creatorMainMenu.ListChange.on((item, listIndex) => { if (item === genderItem) { currentGender = listIndex; mp.events.callRemote("creator_GenderChange", listIndex); setTimeout(() => { localPlayer.clearTasksImmediately(); applyCreatorOutfit(); angleItem.Index = 0; resetParentsMenu(true); resetFeaturesMenu(true); resetAppearanceMenu(true); creatorHairMenu.Clear(); fillHairMenu(); creatorHairMenu.RefreshIndex(); }, 200); } else if (item === angleItem) { localPlayer.setHeading(parseFloat(angleItem.SelectedValue)); localPlayer.clearTasksImmediately(); } }); creatorMainMenu.ItemSelect.on((item, index) => { switch (index) { case 1: creatorMainMenu.Visible = false; creatorParentsMenu.Visible = true; break; case 2: creatorMainMenu.Visible = false; creatorFeaturesMenu.Visible = true; break; case 3: creatorMainMenu.Visible = false; creatorAppearanceMenu.Visible = true; break; case 4: creatorMainMenu.Visible = false; creatorHairMenu.Visible = true; break; case 6: let parentData = { Father: Data.fathers[fatherItem.Index], Mother: Data.mothers[motherItem.Index], Similarity: similarityItem.Index * 0.01, SkinSimilarity: skinSimilarityItem.Index * 0.01 }; let featureData = []; for (let i = 0; i < featureItems.length; i++) featureData.push(parseFloat(featureItems[i].SelectedValue)); let appearanceData = []; for (let i = 0; i < appearanceItems.length; i++) appearanceData.push({ Value: ((appearanceItems[i].Index === 0) ? 255 : appearanceItems[i].Index - 1), Opacity: appearanceOpacityItems[i].Index * 0.01 }); let hairAndColors = [ Data.hairList[currentGender][hairItem.Index].ID, hairColorItem.Index, hairHighlightItem.Index, eyebrowColorItem.Index, beardColorItem.Index, eyeColorItem.Index, blushColorItem.Index, lipstickColorItem.Index, chestHairColorItem.Index ]; for (let i = 0; i < creatorMenus.length; i++) creatorMenus[i].Visible = false; localPlayer.setDefaultComponentVariation(); localPlayer.setComponentVariation(2, Data.hairList[currentGender][hairItem.Index].ID, 0, 2); mp.game.cam.renderScriptCams(false, false, 0, true, false); mp.events.callRemote("creatorSave", currentGender, JSON.stringify(parentData), JSON.stringify(featureData), JSON.stringify(appearanceData), JSON.stringify(hairAndColors)); leaveCreator(); break; case 7: if (isSurgery) mp.events.callRemote("surgeryLeave"); leaveCreator(); break; } }); creatorMainMenu.MenuClose.on(() => { if (isSurgery) { mp.events.callRemote("surgeryLeave"); leaveCreator(); } else { creatorMainMenu.Open(); } }); creatorMainMenu.Visible = false; creatorMenus.push(creatorMainMenu); // CREATOR MAIN END // CREATOR PARENTS let similarities = []; for (let i = 0; i <= 100; i++) similarities.push(i + "%"); let creatorParentsMenu = new Menu("Eltern", "", new Point(0, screenRes.y / 3), null, null); let fatherItem = new UIMenuListItem("Vater", "Dem Charakter sein Vadda.", new ItemsCollection(Data.fatherNames)); let motherItem = new UIMenuListItem("Mutter", "Dem Charakter seine Mudda.", new ItemsCollection(Data.motherNames)); let similarityItem = new UIMenuListItem("\u00c4hnlichkeit", "\u00c4hnlichkeit zu den Eltern.\n(niedriger = feminin, h\u00f6her = maskulin)", new ItemsCollection(similarities)); let skinSimilarityItem = new UIMenuListItem("Hautfarbe", "Hautfarben \u00c4hnlichkeit zu den Eltern.\n(niedriger = Mutter, h\u00f6her = Vater)", new ItemsCollection(similarities)); creatorParentsMenu.AddItem(fatherItem); creatorParentsMenu.AddItem(motherItem); creatorParentsMenu.AddItem(similarityItem); creatorParentsMenu.AddItem(skinSimilarityItem); creatorParentsMenu.AddItem(new UIMenuItem("Zuf\u00e4llig", "~r~Zuf\u00e4llige Eltern.")); creatorParentsMenu.AddItem(new UIMenuItem("Zur\u00fccksetzen", "~r~Setzt die Eltern zur\u00fcck. :'(")); creatorParentsMenu.ItemSelect.on((item, index) => { switch (item.Text) { case "Zuf\u00e4llig": fatherItem.Index = getRandomInt(0, Data.fathers.length - 1); motherItem.Index = getRandomInt(0, Data.mothers.length - 1); similarityItem.Index = getRandomInt(0, 100); skinSimilarityItem.Index = getRandomInt(0, 100); updateParents(); break; case "Zur\u00fccksetzen": resetParentsMenu(); break; } }); creatorParentsMenu.ListChange.on((item, listIndex) => { updateParents(); }); creatorParentsMenu.ParentMenu = creatorMainMenu; creatorParentsMenu.Visible = false; creatorMenus.push(creatorParentsMenu); // CREATOR PARENTS END // CREATOR FEATURES let featureItems = []; let features = []; for (let i = -1.0; i <= 1.01; i += 0.01) features.push(i.toFixed(2)); let creatorFeaturesMenu = new Menu("Gesichtsmerkmale", "", new Point(0, screenRes.y / 3), null, null); for (let i = 0; i < Data.featureNames.length; i++) { let tempFeatureItem = new UIMenuListItem(Data.featureNames[i], "", new ItemsCollection(features)); tempFeatureItem.Index = 100; featureItems.push(tempFeatureItem); creatorFeaturesMenu.AddItem(tempFeatureItem); } creatorFeaturesMenu.AddItem(new UIMenuItem("Zuf\u00e4llig", "~r~Zuf\u00e4llige Gesichtsz\u00fcge.")); creatorFeaturesMenu.AddItem(new UIMenuItem("Zur\u00fccksetzen", "~r~Setzt Gesichtsmerkmale zurück.")); creatorFeaturesMenu.ItemSelect.on((item, index) => { switch (item.Text) { case "Zuf\u00e4llig": for (let i = 0; i < Data.featureNames.length; i++) { featureItems[i].Index = getRandomInt(0, 200); updateFaceFeature(i); } break; case "Zur\u00fccksetzen": resetFeaturesMenu(); break; } }); creatorFeaturesMenu.ListChange.on((item, listIndex) => { updateFaceFeature(featureItems.indexOf(item)); }); creatorFeaturesMenu.ParentMenu = creatorMainMenu; creatorFeaturesMenu.Visible = false; creatorMenus.push(creatorFeaturesMenu); // CREATOR FEATURES END // CREATOR APPEARANCE let appearanceItems = []; let appearanceOpacityItems = []; let opacities = []; for (let i = 0; i <= 100; i++) opacities.push(i + "%"); let creatorAppearanceMenu = new Menu("Aussehen", "", new Point(0, screenRes.y / 3), null, null); for (let i = 0; i < Data.appearanceNames.length; i++) { let items = []; for (let j = 0, max = mp.game.ped.getNumHeadOverlayValues(i); j <= max; j++) items.push(Data.appearanceItemNames[i][j] === undefined ? j.toString() : Data.appearanceItemNames[i][j]); let tempAppearanceItem = new UIMenuListItem(Data.appearanceNames[i], "", new ItemsCollection(items)); appearanceItems.push(tempAppearanceItem); creatorAppearanceMenu.AddItem(tempAppearanceItem); let tempAppearanceOpacityItem = new UIMenuListItem(Data.appearanceNames[i] + " Transparenz", "", new ItemsCollection(opacities)); tempAppearanceOpacityItem.Index = 100; appearanceOpacityItems.push(tempAppearanceOpacityItem); creatorAppearanceMenu.AddItem(tempAppearanceOpacityItem); } creatorAppearanceMenu.AddItem(new UIMenuItem("Zuf\u00e4llig", "~r~Zuf\u00e4lliges Aussehen.")); creatorAppearanceMenu.AddItem(new UIMenuItem("Zur\u00fccksetzen", "~r~Setzt das Aussehen zur\u00fcck.")); creatorAppearanceMenu.ItemSelect.on((item, index) => { switch (item.Text) { case "Zuf\u00e4llig": for (let i = 0; i < Data.appearanceNames.length; i++) { appearanceItems[i].Index = getRandomInt(0, mp.game.ped.getNumHeadOverlayValues(i) - 1); appearanceOpacityItems[i].Index = getRandomInt(0, 100); updateAppearance(i); } break; case "Zur\u00fccksetzen": resetAppearanceMenu(); break; } }); creatorAppearanceMenu.ListChange.on((item, listIndex) => { let idx = (creatorAppearanceMenu.CurrentSelection % 2 === 0) ? (creatorAppearanceMenu.CurrentSelection / 2) : Math.floor(creatorAppearanceMenu.CurrentSelection / 2); updateAppearance(idx); }); creatorAppearanceMenu.ParentMenu = creatorMainMenu; creatorAppearanceMenu.Visible = false; creatorMenus.push(creatorAppearanceMenu); // CREATOR APPEARANCE END // CREATOR HAIR & COLORS let hairItem; let hairColorItem; let hairHighlightItem; let eyebrowColorItem; let beardColorItem; let eyeColorItem; let blushColorItem; let lipstickColorItem; let chestHairColorItem; creatorHairMenu = new Menu("Haar & Farben", "", new Point(0, screenRes.y / 3), null, null); fillHairMenu(); creatorHairMenu.ItemSelect.on((item, index) => { switch (item.Text) { case "Zuf\u00e4llig": hairItem.Index = getRandomInt(0, Data.hairList[currentGender].length - 1); hairColorItem.Index = getRandomInt(0, Data.maxHairColor); hairHighlightItem.Index = getRandomInt(0, Data.maxHairColor); eyebrowColorItem.Index = getRandomInt(0, Data.maxHairColor); beardColorItem.Index = getRandomInt(0, Data.maxHairColor); eyeColorItem.Index = getRandomInt(0, Data.maxEyeColor); blushColorItem.Index = getRandomInt(0, Data.maxBlushColor); lipstickColorItem.Index = getRandomInt(0, Data.maxLipstickColor); chestHairColorItem.Index = getRandomInt(0, Data.maxHairColor); updateHairAndColors(); break; case "Zur\u00fccksetzen": resetHairAndColorsMenu(); break; } }); creatorHairMenu.ListChange.on((item, listIndex) => { if (item === hairItem) { let hairStyle = Data.hairList[currentGender][listIndex]; localPlayer.setComponentVariation(2, hairStyle.ID, 0, 2); } else { switch (creatorHairMenu.CurrentSelection) { case 1: // hair color localPlayer.setHairColor(listIndex, hairHighlightItem.Index); break; case 2: // hair highlight color localPlayer.setHairColor(hairColorItem.Index, listIndex); break; case 3: // eyebrow color localPlayer.setHeadOverlayColor(2, 1, listIndex, 0); break; case 4: // facial hair color localPlayer.setHeadOverlayColor(1, 1, listIndex, 0); break; case 5: // eye color localPlayer.setEyeColor(listIndex); break; case 6: // blush color localPlayer.setHeadOverlayColor(5, 2, listIndex, 0); break; case 7: // lipstick color localPlayer.setHeadOverlayColor(8, 2, listIndex, 0); break; case 8: // chest hair color localPlayer.setHeadOverlayColor(10, 1, listIndex, 0); break; } } }); creatorHairMenu.ParentMenu = creatorMainMenu; creatorHairMenu.Visible = false; creatorMenus.push(creatorHairMenu); // CREATOR HAIR & COLORS END var isSurgery = false; // EVENTS mp.events.add("toggleCreator", (charExists) => { if (!mp.cameras.exists(creatorCamera)) { if (charExists) { creatorCamera = mp.cameras.new("creatorCamera", surgeryCoords.camera, new mp.Vector3(0, 0, 0), 45); creatorCamera.pointAtCoord(surgeryCoords.cameraLookAt.x, surgeryCoords.cameraLookAt.y, surgeryCoords.cameraLookAt.z); creatorCamera.setActive(true); isSurgery = true; } else { creatorCamera = mp.cameras.new("creatorCamera", creatorCoords.camera, new mp.Vector3(0, 0, 0), 45); creatorCamera.pointAtCoord(creatorCoords.cameraLookAt.x, creatorCoords.cameraLookAt.y, creatorCoords.cameraLookAt.z); creatorCamera.setActive(true); } resetAppearanceMenu(); resetFeaturesMenu(); resetHairAndColorsMenu(); resetParentsMenu(); globalData.InMenu = true; globalData.InMenu = true; creatorMainMenu.Visible = true; mp.gui.chat.show(false); mp.game.ui.displayRadar(false); mp.game.ui.displayHud(false); localPlayer.clearTasksImmediately(); localPlayer.freezePosition(true); mp.game.cam.renderScriptCams(true, false, 0, true, false); applyCreatorOutfit(); } }); mp.events.add("sendToServer", (characterData) => { mp.events.callRemote("creatorSave", characterData); }); creatorMenus.forEach(menu => { menu.Visible = false; }) function leaveCreator() { mp.gui.chat.show(true); mp.game.ui.displayRadar(true); mp.game.ui.displayHud(true); localPlayer.freezePosition(false); mp.game.cam.renderScriptCams(false, false, 0, true, false); creatorCamera.destroy(); globalData.InMenu = false; globalData.InMenu = false; if (isSurgery) isSurgery = false; } }