forked from Simnation/Main
ed
This commit is contained in:
parent
3fa969a62c
commit
b31336d080
19 changed files with 3844 additions and 85 deletions
BIN
resources/[notify]/rtx_notify/.fxap
Normal file
BIN
resources/[notify]/rtx_notify/.fxap
Normal file
Binary file not shown.
24
resources/[notify]/rtx_notify/Readme.txt
Normal file
24
resources/[notify]/rtx_notify/Readme.txt
Normal file
|
@ -0,0 +1,24 @@
|
|||
Thank you for purchasing rtx_notify we're grateful for your support. If you'd ever have a question and / or need our help, please reach out to us by sending an email or go ahead and create a ticket on our discord: https://discord.gg/P6KdaDpgAk
|
||||
|
||||
|
||||
Install instructions:
|
||||
1. Put rtx_notify folder to your resources
|
||||
2. Configure your config.lua to your preferences
|
||||
3. Put rtx_notify to the server.cfg
|
||||
|
||||
Notify Examples:
|
||||
|
||||
Client Side Notify TriggerEvent("rtx_notify:Notify", "Title", "text", time, "type")
|
||||
Client Side Notify Function exports["rtx_notify"]:Notify("Title", "text", time, "type")
|
||||
|
||||
Example Client Side Notify TriggerEvent("rtx_notify:Notify", "Info", "This is info notify", 2500, "info") - time 1000 = 1 seconds
|
||||
Example Client Side Notify exports["rtx_notify"]:Notify("Info", "This is info notify", 2500, "info") - time 1000 = 1 seconds
|
||||
|
||||
Server Side Notify TriggerClientEvent("rtx_notify:Notify", source, "Title", "text", time, "type")
|
||||
|
||||
Example Server Side Notify TriggerClientEvent("rtx_notify:Notify", source, "Info", "This is info notify", 2500, "info") - time 1000 = 1 seconds
|
||||
|
||||
2. Each product is to be used on a singular server, with the exception of a test server.
|
||||
3. Any form of redistribution of our content is considered copyright infringement.
|
||||
4. If any of these rules are broken, legal actions can be taken.
|
||||
© 2025 RTX Development, all rights reserved.
|
BIN
resources/[notify]/rtx_notify/client/main.lua
Normal file
BIN
resources/[notify]/rtx_notify/client/main.lua
Normal file
Binary file not shown.
67
resources/[notify]/rtx_notify/config.lua
Normal file
67
resources/[notify]/rtx_notify/config.lua
Normal file
|
@ -0,0 +1,67 @@
|
|||
Config = {}
|
||||
|
||||
Config.NotifySoundsEnabled = true -- true sound enabled -- false sound disabled
|
||||
|
||||
Config.NotifyLocation = "right" -- left or right or middle
|
||||
|
||||
Config.NotifySettings = true -- enable notify settings for players
|
||||
|
||||
Config.NotifySettingsCommand = "notifysettings" -- you can also open notifysettings menu via TriggerEvent("rtx_notify:NotifySettings)
|
||||
|
||||
Config.NotifySettingsInterfaceColor = "#ff66ff" -- change interface color, color must be in hex
|
||||
|
||||
Config.DefaultNotifyStyle = {
|
||||
defaultcolor = "#ff66ff", -- color for notify
|
||||
defaulttime = 5000, -- time 1000 = 1 second
|
||||
defaultnotifysoundenabled = true, -- true sound enabled -- false sound disabled
|
||||
defaultnotifysound = "sounds/soundnotify.mp3", -- you can import sounds to html/sounds/ folder,
|
||||
}
|
||||
|
||||
--[[
|
||||
|
||||
Client Side Notify TriggerEvent("rtx_notify:Notify", "Title", "text", time, "type")
|
||||
Client Side Notify Function exports["rtx_notify"]:Notify("Title", "text", time, "type")
|
||||
|
||||
Example Client Side Notify TriggerEvent("rtx_notify:Notify", "Info", "This is info notify", 2500, "info") -- time 1000 = 1 seconds
|
||||
Example Client Side Notify exports["rtx_notify"]:Notify("Info", "This is info notify", 2500, "info") -- time 1000 = 1 seconds
|
||||
|
||||
-----
|
||||
|
||||
Server Side Notify TriggerClientEvent("rtx_notify:Notify", source, "Title", "text", time, "type")
|
||||
|
||||
Example Server Side Notify TriggerClientEvent("rtx_notify:Notify", source, "Info", "This is info notify", 2500, "info") -- time 1000 = 1 seconds
|
||||
|
||||
]]--
|
||||
|
||||
Config.NotifyStyles = {
|
||||
["info"] = {
|
||||
notifycolor = "#1aa7ec", -- color for notify
|
||||
notifytime = 5000, -- time 1000 = 1 second (default time when time is not defined in trigger)
|
||||
notifysoundenabled = true, -- true sound enabled -- false sound disabled
|
||||
notifysound = "sounds/soundnotify.mp3", -- you can import sounds to html/sounds/ folder
|
||||
},
|
||||
["success"] = {
|
||||
notifycolor = "#07da63", -- color for notify
|
||||
notifytime = 5000, -- time 1000 = 1 second (default time when time is not defined in trigger)
|
||||
notifysoundenabled = true, -- true sound enabled -- false sound disabled
|
||||
notifysound = "sounds/soundnotify.mp3", -- you can import sounds to html/sounds/ folder
|
||||
},
|
||||
["warning"] = {
|
||||
notifycolor = "#ffe338", -- color for notify
|
||||
notifytime = 5000, -- time 1000 = 1 second (default time when time is not defined in trigger)
|
||||
notifysoundenabled = true, -- true sound enabled -- false sound disabled
|
||||
notifysound = "sounds/soundnotify.mp3", -- you can import sounds to html/sounds/ folder
|
||||
},
|
||||
["error"] = {
|
||||
notifycolor = "#ff0000", -- color for notify
|
||||
notifytime = 5000, -- time 1000 = 1 second (default time when time is not defined in trigger)
|
||||
notifysoundenabled = true, -- true sound enabled -- false sound disabled
|
||||
notifysound = "sounds/soundnotify.mp3", -- you can import sounds to html/sounds/ folder
|
||||
},
|
||||
["custom"] = {
|
||||
notifycolor = "#ff66ff", -- color for notify
|
||||
notifytime = 5000, -- time 1000 = 1 second (default time when time is not defined in trigger)
|
||||
notifysoundenabled = true, -- true sound enabled -- false sound disabled
|
||||
notifysound = "sounds/soundnotify.mp3", -- you can import sounds to html/sounds/ folder
|
||||
},
|
||||
}
|
36
resources/[notify]/rtx_notify/fxmanifest.lua
Normal file
36
resources/[notify]/rtx_notify/fxmanifest.lua
Normal file
|
@ -0,0 +1,36 @@
|
|||
fx_version 'adamant'
|
||||
|
||||
game 'gta5'
|
||||
|
||||
description 'RTX NOTIFY'
|
||||
|
||||
version '10.0'
|
||||
|
||||
client_scripts {
|
||||
'config.lua',
|
||||
'client/main.lua'
|
||||
}
|
||||
|
||||
files {
|
||||
'html/ui.html',
|
||||
'html/styles.css',
|
||||
'html/scripts.js',
|
||||
'html/howler.core.js',
|
||||
'html/debounce.min.js',
|
||||
'html/BebasNeuePro-Bold.ttf',
|
||||
'html/img/*.png',
|
||||
'html/sounds/*.mp3'
|
||||
}
|
||||
|
||||
ui_page 'html/ui.html'
|
||||
|
||||
exports {
|
||||
'Notify',
|
||||
}
|
||||
|
||||
lua54 'yes'
|
||||
|
||||
escrow_ignore {
|
||||
'config.lua'
|
||||
}
|
||||
dependency '/assetpacks'
|
BIN
resources/[notify]/rtx_notify/html/BebasNeuePro-Bold.ttf
Normal file
BIN
resources/[notify]/rtx_notify/html/BebasNeuePro-Bold.ttf
Normal file
Binary file not shown.
9
resources/[notify]/rtx_notify/html/debounce.min.js
vendored
Normal file
9
resources/[notify]/rtx_notify/html/debounce.min.js
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
* jQuery throttle / debounce - v1.1 - 3/7/2010
|
||||
* http://benalman.com/projects/jquery-throttle-debounce-plugin/
|
||||
*
|
||||
* Copyright (c) 2010 "Cowboy" Ben Alman
|
||||
* Dual licensed under the MIT and GPL licenses.
|
||||
* http://benalman.com/about/license/
|
||||
*/
|
||||
(function(b,c){var $=b.jQuery||b.Cowboy||(b.Cowboy={}),a;$.throttle=a=function(e,f,j,i){var h,d=0;if(typeof f!=="boolean"){i=j;j=f;f=c}function g(){var o=this,m=+new Date()-d,n=arguments;function l(){d=+new Date();j.apply(o,n)}function k(){h=c}if(i&&!h){l()}h&&clearTimeout(h);if(i===c&&m>e){l()}else{if(f!==true){h=setTimeout(i?k:l,i===c?e-m:e)}}}if($.guid){g.guid=j.guid=j.guid||$.guid++}return g};$.debounce=function(d,e,f){return f===c?a(d,e,false):a(d,f,e!==false)}})(this);
|
2583
resources/[notify]/rtx_notify/html/howler.core.js
Normal file
2583
resources/[notify]/rtx_notify/html/howler.core.js
Normal file
File diff suppressed because it is too large
Load diff
BIN
resources/[notify]/rtx_notify/html/img/close.png
Normal file
BIN
resources/[notify]/rtx_notify/html/img/close.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 757 B |
306
resources/[notify]/rtx_notify/html/scripts.js
Normal file
306
resources/[notify]/rtx_notify/html/scripts.js
Normal file
|
@ -0,0 +1,306 @@
|
|||
$(function () {
|
||||
var notifyresourcename = "rtx_notify";
|
||||
var soundhandler = new Howl({
|
||||
src: "sounds/soundnotify.mp3",
|
||||
volume: 0.2,
|
||||
});
|
||||
|
||||
var currentscale = 1.0;
|
||||
var currentvolume = 1;
|
||||
var currenthide = 0;
|
||||
if (localStorage.default == "false") {
|
||||
} else {
|
||||
localStorage.scale = 1.0;
|
||||
localStorage.soundactivated = 1;
|
||||
localStorage.hideactivated = 0;
|
||||
}
|
||||
|
||||
let defaultValues = {notifytop: "2", notifyleft: "82", scale: "1.0",};
|
||||
|
||||
var scaleslider = document.getElementById("scalesliderdata");
|
||||
|
||||
function openMain() {
|
||||
$("body").css("display", "block");
|
||||
}
|
||||
|
||||
function NotifyDrag() {
|
||||
$(".notify-container").css("background-color", "rgba(0, 0, 0, 1.0)");
|
||||
$(".notify-container ").draggable({
|
||||
scroll: false,
|
||||
axis: "x, y",
|
||||
cursor: "move"
|
||||
});
|
||||
};
|
||||
|
||||
function currentsliderdata() {
|
||||
if (localStorage.default === "true") {
|
||||
if (defaultValues.scale == 0.5) {
|
||||
return 5;
|
||||
} else if (defaultValues.scale == 0.6) {
|
||||
return 6;
|
||||
} else if (defaultValues.scale == 0.7) {
|
||||
return 7;
|
||||
} else if (defaultValues.scale == 0.8) {
|
||||
return 8;
|
||||
} else if (defaultValues.scale == 0.9) {
|
||||
return 9;
|
||||
} else if (defaultValues.scale == 1.0) {
|
||||
return 10;
|
||||
} else if (defaultValues.scale == 1.0) {
|
||||
return 10;
|
||||
} else if (defaultValues.scale == 1.1) {
|
||||
return 11;
|
||||
} else if (defaultValues.scale == 1.2) {
|
||||
return 12;
|
||||
} else if (defaultValues.scale == 1.3) {
|
||||
return 13;
|
||||
} else if (defaultValues.scale == 1.4) {
|
||||
return 14;
|
||||
} else if (defaultValues.scale == 1.5) {
|
||||
return 15;
|
||||
}
|
||||
} else {
|
||||
if (localStorage.scale == 0.5) {
|
||||
return 5;
|
||||
} else if (localStorage.scale == 0.6) {
|
||||
return 6;
|
||||
} else if (localStorage.scale == 0.7) {
|
||||
return 7;
|
||||
} else if (localStorage.scale == 0.8) {
|
||||
return 8;
|
||||
} else if (localStorage.scale == 0.9) {
|
||||
return 9;
|
||||
} else if (localStorage.scale == 1.0) {
|
||||
return 10;
|
||||
} else if (localStorage.scale == 1.0) {
|
||||
return 10;
|
||||
} else if (localStorage.scale == 1.1) {
|
||||
return 11;
|
||||
} else if (localStorage.scale == 1.2) {
|
||||
return 12;
|
||||
} else if (localStorage.scale == 1.3) {
|
||||
return 13;
|
||||
} else if (localStorage.scale == 1.4) {
|
||||
return 14;
|
||||
} else if (localStorage.scale == 1.5) {
|
||||
return 15;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function ChangeNotify() {
|
||||
if (localStorage.default === "true") {
|
||||
var notifytop = defaultValues.notifytop + "%";
|
||||
var notifyleft = defaultValues.notifyleft + '%';
|
||||
$('.notify-container').css({
|
||||
position:'absolute',
|
||||
top:notifytop,
|
||||
left:notifyleft
|
||||
});
|
||||
localStorage.soundactivated = 1;
|
||||
localStorage.hideactivated = 0;
|
||||
currentvolume = 1;
|
||||
currenthide = 0;
|
||||
localStorage.scale = defaultValues.scale;
|
||||
scaleslider.value = currentsliderdata();
|
||||
currentscale = defaultValues.scale;
|
||||
$(".notify-container").css("transform", "scale(" + defaultValues.scale + ")");
|
||||
document.getElementById("notifyvolumeswitchdata").checked = true;
|
||||
document.getElementById("notifyhideswitchdata").checked = false;
|
||||
} else {
|
||||
var notifytop = localStorage.notifytop + 'px';
|
||||
var notifyleft = localStorage.notifyleft + 'px';
|
||||
var scaledata = localStorage.scale;
|
||||
var volumedata = localStorage.soundactivated;
|
||||
var hidedata = localStorage.hideactivated;
|
||||
$('.notify-container').css({
|
||||
position:'absolute',
|
||||
top:notifytop,
|
||||
left:notifyleft
|
||||
});
|
||||
scaleslider.value = currentsliderdata();
|
||||
$(".notify-container").css("transform", "scale(" + scaledata + ")");
|
||||
if (volumedata == 1){
|
||||
document.getElementById("notifyvolumeswitchdata").checked = true;
|
||||
}
|
||||
else {
|
||||
document.getElementById("notifyvolumeswitchdata").checked = false;
|
||||
}
|
||||
if (hidedata == 1){
|
||||
document.getElementById("notifyhideswitchdata").checked = true;
|
||||
}
|
||||
else {
|
||||
document.getElementById("notifyhideswitchdata").checked = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
$("#notifyvolumeswitchdata").click(function(){
|
||||
if (document.getElementById("notifyvolumeswitchdata").checked == false){
|
||||
document.getElementById("notifyvolumeswitchdata").checked = false;
|
||||
currentvolume = 0;
|
||||
}
|
||||
else {
|
||||
document.getElementById("notifyvolumeswitchdata").checked = true;
|
||||
currentvolume = 1;
|
||||
}
|
||||
})
|
||||
|
||||
$("#notifyhideswitchdata").click(function(){
|
||||
if (document.getElementById("notifyhideswitchdata").checked == false){
|
||||
document.getElementById("notifyhideswitchdata").checked = false;
|
||||
currenthide = 0;
|
||||
}
|
||||
else {
|
||||
document.getElementById("notifyhideswitchdata").checked = true;
|
||||
currenthide = 1;
|
||||
}
|
||||
})
|
||||
|
||||
$(".closenotifyedit").click(function(){
|
||||
ChangeNotify();
|
||||
$(".notify-container").draggable("destroy");
|
||||
$(".notify-container").css("background-color", "rgba(0, 0, 0, 0.0)");
|
||||
$("#notifysettingsshow").hide();
|
||||
$.post('http://'+notifyresourcename+'/closesettingsnotify', JSON.stringify({}));
|
||||
});
|
||||
|
||||
$(".buttonsettingsreset").click(function(){
|
||||
localStorage.default = "true";
|
||||
ChangeNotify();
|
||||
});
|
||||
|
||||
$(".buttonsettingssave").click(function(){
|
||||
$(".notify-container").draggable("disable")
|
||||
localStorage.default = "false";
|
||||
var notifypos = $(".notify-container").position();
|
||||
localStorage.notifytop = notifypos.top;
|
||||
localStorage.notifyleft = notifypos.left;
|
||||
localStorage.scale = currentscale;
|
||||
localStorage.soundactivated = currentvolume;
|
||||
localStorage.hideactivated = currenthide;
|
||||
ChangeNotify();
|
||||
$(".notify-container").draggable("destroy");
|
||||
$(".notify-container").css("background-color", "rgba(0, 0, 0, 0.0)");
|
||||
$("#notifysettingsshow").hide();
|
||||
$.post('http://'+notifyresourcename+'/closesettingsnotify', JSON.stringify({}));
|
||||
});
|
||||
|
||||
scaleslider.oninput = function() {
|
||||
if (this.value == 5) {
|
||||
$(".notify-container").css("transform", "scale(0.5)");
|
||||
currentscale = 0.5;
|
||||
} else if (this.value == 6) {
|
||||
$(".notify-container").css("transform", "scale(0.6)");
|
||||
currentscale = 0.6;
|
||||
} else if (this.value == 7) {
|
||||
$(".notify-container").css("transform", "scale(0.7)");
|
||||
currentscale = 0.7;
|
||||
} else if (this.value == 8) {
|
||||
$(".notify-container").css("transform", "scale(0.8)");
|
||||
currentscale = 0.8;
|
||||
} else if (this.value == 9) {
|
||||
$(".notify-container").css("transform", "scale(0.9)");
|
||||
currentscale = 0.9;
|
||||
} else if (this.value == 10) {
|
||||
$(".notify-container").css("transform", "scale(1.0)");
|
||||
currentscale = 1.0;
|
||||
} else if (this.value == 11) {
|
||||
$(".notify-container").css("transform", "scale(1.1)");
|
||||
currentscale = 1.1;
|
||||
} else if (this.value == 12) {
|
||||
$(".notify-container").css("transform", "scale(1.2)");
|
||||
currentscale = 1.2;
|
||||
} else if (this.value == 13) {
|
||||
$(".notify-container").css("transform", "scale(1.3)");
|
||||
currentscale = 1.3;
|
||||
} else if (this.value == 14) {
|
||||
$(".notify-container").css("transform", "scale(1.4)");
|
||||
currentscale = 1.4;
|
||||
} else if (this.value == 15) {
|
||||
$(".notify-container").css("transform", "scale(1.5)");
|
||||
currentscale = 1.5;
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener('message', function (event) {
|
||||
|
||||
var item = event.data;
|
||||
|
||||
if (item.message == "addnotify"){
|
||||
if (localStorage.hideactivated == 0) {
|
||||
openMain();
|
||||
$( ".notifications" ).append('<div class="notify" id = "' + item.notifyrandomid + '">' +
|
||||
'<div class="notifytitle" style="color: ' + item.notifycolor + ';"><span style="font-size: 30px;">' + item.notifytitle + '<span></div>' +
|
||||
'<div class="notifytext">' + item.notifytext + '</div>' +
|
||||
'<div class="notifyprogressmain">' +
|
||||
'<div class="notifyprogress" style="background-color: ' + item.notifycolor + '; animation: progressanim ' + item.notifytimedata + 's;;"></div>' +
|
||||
'</div>' +
|
||||
|
||||
'</div>');
|
||||
}
|
||||
}
|
||||
if (item.message == "removenotify"){
|
||||
$("#" + item.notifyrandomid + "").fadeOut("slow");
|
||||
}
|
||||
if (item.message == "playsound") {
|
||||
if (localStorage.hideactivated == 0) {
|
||||
if (localStorage.soundactivated == 1) {
|
||||
soundhandler._src = item.soundsrc;
|
||||
soundhandler.load();
|
||||
soundhandler.play();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (item.message == "notifysettingsload"){
|
||||
notifyresourcename = item.notifyresouredata;
|
||||
let root = document.documentElement;
|
||||
root.style.setProperty('--color', item.notifysettingsinterfacecolor);
|
||||
if (localStorage.default == "true") {
|
||||
if (item.defaultposition == "left") {
|
||||
defaultValues.notifyleft = "18";
|
||||
$(".notify-container").css("left", "18%");
|
||||
} else if (item.defaultposition == "right") {
|
||||
defaultValues.notifyleft = "82";
|
||||
$(".notify-container").css("left", "18%");
|
||||
} else if (item.defaultposition == "middle") {
|
||||
defaultValues.notifyleft = "42";
|
||||
$(".notify-container").css("left", "42%");
|
||||
}
|
||||
} else {
|
||||
ChangeNotify();
|
||||
}
|
||||
}
|
||||
if (item.message == "notifysettingsshow"){
|
||||
var volumedata = localStorage.soundactivated;
|
||||
var hidedata = localStorage.hideactivated;
|
||||
if (volumedata == 1){
|
||||
document.getElementById("notifyvolumeswitchdata").checked = true;
|
||||
}
|
||||
else {
|
||||
document.getElementById("notifyvolumeswitchdata").checked = false;
|
||||
}
|
||||
if (hidedata == 1){
|
||||
document.getElementById("notifyhideswitchdata").checked = true;
|
||||
}
|
||||
else {
|
||||
document.getElementById("notifyhideswitchdata").checked = false;
|
||||
}
|
||||
openMain();
|
||||
$("#notifysettingsshow").show();
|
||||
NotifyDrag();
|
||||
}
|
||||
document.onkeyup = function (data) {
|
||||
if (open) {
|
||||
if (data.which == 27) {
|
||||
ChangeNotify();
|
||||
$(".notify-container").draggable("destroy");
|
||||
$(".notify-container").css("background-color", "rgba(0, 0, 0, 0.0)");
|
||||
$("#notifysettingsshow").hide();
|
||||
$.post('http://'+notifyresourcename+'/closesettingsnotify', JSON.stringify({}));
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
})
|
BIN
resources/[notify]/rtx_notify/html/sounds/soundnotify.mp3
Normal file
BIN
resources/[notify]/rtx_notify/html/sounds/soundnotify.mp3
Normal file
Binary file not shown.
479
resources/[notify]/rtx_notify/html/styles.css
Normal file
479
resources/[notify]/rtx_notify/html/styles.css
Normal file
|
@ -0,0 +1,479 @@
|
|||
:root {
|
||||
--color: var(--color);
|
||||
}
|
||||
|
||||
*{
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: BebasNeuePro-Bold;
|
||||
src: url(BebasNeuePro-Bold.ttf);
|
||||
}
|
||||
|
||||
html {
|
||||
overflow: hidden;
|
||||
font-family: 'Open Sans', sans-serif;
|
||||
}
|
||||
|
||||
body{
|
||||
display: none;
|
||||
color: #a8a8aa;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar
|
||||
{
|
||||
width: 4px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb
|
||||
{
|
||||
background-color: rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
.notify-container {
|
||||
width: 16%;
|
||||
height: 95%;
|
||||
background-color: rgba(0, 0, 0, 0.0);
|
||||
margin: 0;
|
||||
position: absolute;
|
||||
top: 2%;
|
||||
left: 82%;
|
||||
overflow: hidden;
|
||||
z-index: 9999999;
|
||||
display: block;
|
||||
transform: scale(1.0);
|
||||
transform-origin: 0 0;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.notify {
|
||||
display: block;
|
||||
border-radius: 5px;
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
z-index: 9999999;
|
||||
width: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.70);
|
||||
color: #fff;
|
||||
margin-bottom: 3%;
|
||||
-moz-animation: fadein 1s;
|
||||
-webkit-animation: fadein 1s;
|
||||
-o-animation: fadein 1s;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.notifytitle {
|
||||
padding-top: 10px;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
font-size: 30px;
|
||||
font-family: BebasNeuePro-Bold;
|
||||
}
|
||||
|
||||
.notifytext {
|
||||
padding-top: 2px;
|
||||
padding-bottom: 15px;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
font-size: 20px;
|
||||
padding-left: 15px;
|
||||
padding-right: 15px;
|
||||
font-family: BebasNeuePro-Bold;
|
||||
}
|
||||
|
||||
.notifyprogress {
|
||||
display: block;
|
||||
height: 3px;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
background-color: var(--color);
|
||||
vertical-align: bottom;
|
||||
transform: rotate(180deg);
|
||||
float: right;
|
||||
}
|
||||
|
||||
.notifysettings-container {
|
||||
width: 20%;
|
||||
height: 30%;
|
||||
background-color: rgba(0, 0, 0, 0.70);
|
||||
border-bottom: 3px solid var(--color);
|
||||
border-radius: 10px;
|
||||
margin: 0;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
margin-right: -50%;
|
||||
transform: translate(-50%, -50%);
|
||||
overflow: hidden;
|
||||
z-index: 99999999;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.closenotifyedit {
|
||||
position: absolute;
|
||||
margin: 0;
|
||||
top: 10%;
|
||||
left: 92%;
|
||||
margin-right: -50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.notifysettingsmaintext {
|
||||
position: absolute;
|
||||
margin: 0;
|
||||
text-decoration: none;
|
||||
text-align: center;
|
||||
top: 10%;
|
||||
left: 50%;
|
||||
margin-right: -50%;
|
||||
transform: translate(-50%, -50%);
|
||||
font-size: 35px;
|
||||
color: var(--color);
|
||||
text-align:center;
|
||||
font-family: BebasNeuePro-Bold;
|
||||
}
|
||||
|
||||
.notifysettingsscale {
|
||||
position: absolute;
|
||||
margin: 0;
|
||||
text-decoration: none;
|
||||
text-align: center;
|
||||
top: 25%;
|
||||
left: 50%;
|
||||
margin-right: -50%;
|
||||
transform: translate(-50%, -50%);
|
||||
font-size: 25px;
|
||||
color: #ffffff;
|
||||
text-align:center;
|
||||
font-family: BebasNeuePro-Bold;
|
||||
}
|
||||
|
||||
.scaleslidercontainer {
|
||||
position: absolute;
|
||||
margin: 0;
|
||||
background-color: rgba(0, 0, 0, 1);
|
||||
border-bottom: 3px solid var(--color);
|
||||
color: #ffffff;
|
||||
font-size: 35px;
|
||||
text-decoration: none;
|
||||
text-align: center;
|
||||
top: 37%;
|
||||
left: 50%;
|
||||
margin-right: -50%;
|
||||
transform: translate(-50%, -50%);
|
||||
overflow: hidden;
|
||||
z-index: 9999999;
|
||||
width: 80%;
|
||||
height: 11%;
|
||||
border-radius: 5px;
|
||||
font-family: BebasNeueBold;
|
||||
}
|
||||
|
||||
.scaleslider {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
position: absolute;
|
||||
margin: 0;
|
||||
background-color: rgba(255, 255, 255, 0.0);
|
||||
color: #ffffff;
|
||||
font-size: 35px;
|
||||
text-decoration: none;
|
||||
text-align: center;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
margin-right: -50%;
|
||||
transform: translate(-50%, -50%);
|
||||
overflow: hidden;
|
||||
z-index: 9999999;
|
||||
width: 90%;
|
||||
height: 80%;
|
||||
border-radius: 5px;
|
||||
font-family: BebasNeueBold;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.scalesliderline {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
position: absolute;
|
||||
margin: 0;
|
||||
background-color: rgba(255, 255, 255, 1.0);
|
||||
color: #ffffff;
|
||||
font-size: 35px;
|
||||
text-decoration: none;
|
||||
text-align: center;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
margin-right: -50%;
|
||||
transform: translate(-50%, -50%);
|
||||
overflow: hidden;
|
||||
z-index: 9999999;
|
||||
width: 90%;
|
||||
height: 8%;
|
||||
border-radius: 5px;
|
||||
font-family: BebasNeueBold;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.scaleslider::-webkit-slider-thumb {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
width: 17px;
|
||||
height: 17px;
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
background-color: var(--color);
|
||||
}
|
||||
|
||||
.scaleslider::-moz-range-thumb {
|
||||
width: 17px;
|
||||
height: 17px;
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
background-color: var(--color);
|
||||
}
|
||||
|
||||
input[type=range]:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.notifysettingssound {
|
||||
position: absolute;
|
||||
margin: 0;
|
||||
text-decoration: none;
|
||||
text-align: center;
|
||||
top: 52%;
|
||||
left: 25%;
|
||||
margin-right: -50%;
|
||||
transform: translate(-50%, -50%);
|
||||
font-size: 25px;
|
||||
color: #ffffff;
|
||||
text-align:center;
|
||||
font-family: BebasNeuePro-Bold;
|
||||
}
|
||||
|
||||
.notifysettingshide {
|
||||
position: absolute;
|
||||
margin: 0;
|
||||
text-decoration: none;
|
||||
text-align: center;
|
||||
top: 52%;
|
||||
left: 75%;
|
||||
margin-right: -50%;
|
||||
transform: translate(-50%, -50%);
|
||||
font-size: 25px;
|
||||
color: #ffffff;
|
||||
text-align:center;
|
||||
font-family: BebasNeuePro-Bold;
|
||||
}
|
||||
|
||||
.notifyvolumeswitch {
|
||||
display: inline-block;
|
||||
width: 30%;
|
||||
height: 11%;
|
||||
position: absolute;
|
||||
margin: 0;
|
||||
text-decoration: none;
|
||||
text-align: center;
|
||||
top: 64%;
|
||||
left: 25%;
|
||||
margin-right: -50%;
|
||||
transform: translate(-50%, -50%);
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
.notifyvolumeswitch input {
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.slidervolumeswitch {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0, 0, 0, 1);
|
||||
border-bottom: 3px solid var(--color);
|
||||
border-radius: 5px;
|
||||
-webkit-transition: .4s;
|
||||
transition: .4s;
|
||||
}
|
||||
|
||||
.slidervolumeswitch:before {
|
||||
position: absolute;
|
||||
content: "";
|
||||
width: 25%;
|
||||
height: 70%;
|
||||
top: 50%;
|
||||
left: 25%;
|
||||
margin-right: -50%;
|
||||
transform: translate(-50%, -50%);
|
||||
background-color: #ffffff;
|
||||
border-radius: 5px;
|
||||
-webkit-transition: .4s;
|
||||
transition: .4s;
|
||||
}
|
||||
|
||||
input:checked + .slidervolumeswitch:before {
|
||||
top: 50%;
|
||||
left: 75%;
|
||||
margin-right: -50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.notifyhideswitch {
|
||||
display: inline-block;
|
||||
width: 30%;
|
||||
height: 11%;
|
||||
position: absolute;
|
||||
margin: 0;
|
||||
text-decoration: none;
|
||||
text-align: center;
|
||||
top: 64%;
|
||||
left: 75%;
|
||||
margin-right: -50%;
|
||||
transform: translate(-50%, -50%);
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
.notifyhideswitch input {
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.sliderhideswitch {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0, 0, 0, 1);
|
||||
border-bottom: 3px solid var(--color);
|
||||
border-radius: 5px;
|
||||
-webkit-transition: .4s;
|
||||
transition: .4s;
|
||||
}
|
||||
|
||||
.sliderhideswitch:before {
|
||||
position: absolute;
|
||||
content: "";
|
||||
width: 25%;
|
||||
height: 70%;
|
||||
top: 50%;
|
||||
left: 25%;
|
||||
margin-right: -50%;
|
||||
transform: translate(-50%, -50%);
|
||||
background-color: #ffffff;
|
||||
border-radius: 5px;
|
||||
-webkit-transition: .4s;
|
||||
transition: .4s;
|
||||
}
|
||||
|
||||
input:checked + .sliderhideswitch:before {
|
||||
top: 50%;
|
||||
left: 75%;
|
||||
margin-right: -50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.buttonsettingsreset {
|
||||
position: absolute;
|
||||
margin: 0;
|
||||
background-color: rgba(0, 0, 0, 1);
|
||||
border-bottom: 3px solid var(--color);
|
||||
color: #ffffff;
|
||||
font-size: 27px;
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
text-decoration: none;
|
||||
text-align: center;
|
||||
top: 85%;
|
||||
left: 25%;
|
||||
margin-right: -50%;
|
||||
transform: translate(-50%, -50%);
|
||||
overflow: hidden;
|
||||
z-index: 99999999;
|
||||
width: 30%;
|
||||
border-radius: 8px;
|
||||
font-family: BebasNeuePro-Bold;
|
||||
}
|
||||
|
||||
.buttonsettingsreset:hover {
|
||||
background: var(--color);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.buttonsettingssave {
|
||||
position: absolute;
|
||||
margin: 0;
|
||||
background-color: rgba(0, 0, 0, 1);
|
||||
border-bottom: 3px solid var(--color);
|
||||
color: #ffffff;
|
||||
font-size: 27px;
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
text-decoration: none;
|
||||
text-align: center;
|
||||
top: 85%;
|
||||
left: 75%;
|
||||
margin-right: -50%;
|
||||
transform: translate(-50%, -50%);
|
||||
overflow: hidden;
|
||||
z-index: 99999999;
|
||||
width: 30%;
|
||||
border-radius: 8px;
|
||||
font-family: BebasNeuePro-Bold;
|
||||
}
|
||||
|
||||
.buttonsettingssave:hover {
|
||||
background: var(--color);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.full-screen {
|
||||
width: 100%;
|
||||
height:100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.notifications {
|
||||
width: 100%;
|
||||
left: 50%;
|
||||
overflow: auto;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
@keyframes progressanim {
|
||||
from {
|
||||
width 100%;
|
||||
}
|
||||
to {
|
||||
width:0%;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fadein {
|
||||
from {
|
||||
opacity:0;
|
||||
}
|
||||
to {
|
||||
opacity:1;
|
||||
}
|
||||
}
|
41
resources/[notify]/rtx_notify/html/ui.html
Normal file
41
resources/[notify]/rtx_notify/html/ui.html
Normal file
|
@ -0,0 +1,41 @@
|
|||
<head>
|
||||
<link rel="stylesheet" href="styles.css" type="text/css">
|
||||
<link rel="stylesheet" href="https://kit-pro.fontawesome.com/releases/v6.2.0/css/pro.min.css">
|
||||
<script src="nui://game/ui/jquery.js" type="text/javascript"></script>
|
||||
<script src="howler.core.js"></script>
|
||||
<script src="scripts.js" type="text/javascript"></script>
|
||||
<script src="debounce.min.js" type="text/javascript"></script>
|
||||
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
|
||||
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="full-screen">
|
||||
<div class="notify-container">
|
||||
<div class="body notifications">
|
||||
</div>
|
||||
</div>
|
||||
<div class="notifysettings-container" id="notifysettingsshow">
|
||||
<img class="closenotifyedit" src="img/close.png" style="width:26px;height:24px" alt="CloseNotifyEdit"/>
|
||||
<div class="notifysettingsmaintext">NOTIFY SETTINGS</div>
|
||||
<div class="notifysettingsscale">SCALE</div>
|
||||
<div class="scaleslidercontainer">
|
||||
<div class="scalesliderline">
|
||||
</div>
|
||||
<input type="range" min="5" max="15" value="10" class="scaleslider" id="scalesliderdata">
|
||||
</div>
|
||||
<div class="notifysettingssound">SOUND</div>
|
||||
<div class="notifysettingshide">HIDE</div>
|
||||
<label class="notifyvolumeswitch">
|
||||
<input type="checkbox" id="notifyvolumeswitchdata">
|
||||
<span class="slidervolumeswitch"></span>
|
||||
</label>
|
||||
<label class="notifyhideswitch">
|
||||
<input type="checkbox" id="notifyhideswitchdata">
|
||||
<span class="sliderhideswitch"></span>
|
||||
</label>
|
||||
<div class="buttonsettingsreset">RESET</div>
|
||||
<div class="buttonsettingssave">SAVE</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
|
@ -1,78 +0,0 @@
|
|||
local QBCore = exports['qb-core']:GetCoreObject()
|
||||
|
||||
print("^2[TRAIN-TRIGGER]^7 Client Script wird geladen...")
|
||||
|
||||
-- Test ob QBCore funktioniert
|
||||
CreateThread(function()
|
||||
Wait(2000)
|
||||
if QBCore then
|
||||
print("^2[TRAIN-TRIGGER]^7 QBCore erfolgreich geladen auf Client")
|
||||
else
|
||||
print("^1[TRAIN-TRIGGER]^7 FEHLER: QBCore nicht gefunden auf Client!")
|
||||
end
|
||||
end)
|
||||
|
||||
-- Einfache Locations (gleiche wie Server)
|
||||
local trainLocations = {
|
||||
{x = 215.3, y = -810.1, z = 30.7, name = "Legion Square"},
|
||||
{x = -265.0, y = -957.3, z = 31.2, name = "Pillbox Hospital"},
|
||||
}
|
||||
|
||||
local showMarkers = false
|
||||
|
||||
-- Test Command
|
||||
RegisterCommand('togglemarkers', function()
|
||||
showMarkers = not showMarkers
|
||||
print("^3[TRAIN-TRIGGER]^7 Markers: " .. tostring(showMarkers))
|
||||
|
||||
if QBCore and QBCore.Functions and QBCore.Functions.Notify then
|
||||
QBCore.Functions.Notify('Markers: ' .. tostring(showMarkers), 'primary')
|
||||
else
|
||||
TriggerEvent('chatMessage', "SYSTEM", "normal", "Markers: " .. tostring(showMarkers))
|
||||
end
|
||||
end, false)
|
||||
|
||||
-- Marker Loop
|
||||
CreateThread(function()
|
||||
while true do
|
||||
local sleep = 1000
|
||||
|
||||
if showMarkers then
|
||||
local playerCoords = GetEntityCoords(PlayerPedId())
|
||||
|
||||
for i, location in ipairs(trainLocations) do
|
||||
local distance = #(playerCoords - vector3(location.x, location.y, location.z))
|
||||
|
||||
if distance < 200.0 then
|
||||
sleep = 0
|
||||
-- Grüner Marker
|
||||
DrawMarker(1, location.x, location.y, location.z - 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 3.0, 3.0, 2.0, 0, 255, 0, 150, false, true, 2, nil, nil, false)
|
||||
|
||||
if distance < 20.0 then
|
||||
-- 3D Text
|
||||
local onScreen, _x, _y = World3dToScreen2d(location.x, location.y, location.z + 2.0)
|
||||
if onScreen then
|
||||
SetTextScale(0.4, 0.4)
|
||||
SetTextFont(4)
|
||||
SetTextProportional(1)
|
||||
SetTextColour(255, 255, 255, 215)
|
||||
SetTextEntry("STRING")
|
||||
SetTextCentre(1)
|
||||
AddTextComponentString("[E] " .. location.name .. "\nDistanz: " .. math.floor(distance) .. "m")
|
||||
DrawText(_x, _y)
|
||||
end
|
||||
|
||||
if IsControlJustPressed(0, 38) then -- E
|
||||
print("^3[TRAIN-TRIGGER]^7 E gedrückt bei " .. location.name)
|
||||
TriggerServerEvent('train:requestStart')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Wait(sleep)
|
||||
end
|
||||
end)
|
||||
|
||||
print("^2[TRAIN-TRIGGER]^7 Client Script geladen! Commands: /togglemarkers")
|
142
resources/[standalone]/start_train/client/client.lua
Normal file
142
resources/[standalone]/start_train/client/client.lua
Normal file
|
@ -0,0 +1,142 @@
|
|||
local QBCore = exports['qb-core']:GetCoreObject()
|
||||
local PlayerData = {}
|
||||
local isInTrainingZone = false
|
||||
local currentZone = nil
|
||||
local isInScenario = false
|
||||
|
||||
-- Events
|
||||
RegisterNetEvent('QBCore:Client:OnPlayerLoaded', function()
|
||||
PlayerData = QBCore.Functions.GetPlayerData()
|
||||
CreateTrainingZones()
|
||||
end)
|
||||
|
||||
RegisterNetEvent('QBCore:Client:OnPlayerUnload', function()
|
||||
PlayerData = {}
|
||||
end)
|
||||
|
||||
-- Erstelle Training Zones
|
||||
function CreateTrainingZones()
|
||||
for k, v in pairs(Config.TrainingZones) do
|
||||
local blip = AddBlipForCoord(v.coords.x, v.coords.y, v.coords.z)
|
||||
SetBlipSprite(blip, v.blip.sprite)
|
||||
SetBlipDisplay(blip, 4)
|
||||
SetBlipScale(blip, v.blip.scale)
|
||||
SetBlipColour(blip, v.blip.color)
|
||||
SetBlipAsShortRange(blip, true)
|
||||
BeginTextCommandSetBlipName("STRING")
|
||||
AddTextComponentSubstringPlayerName(v.blip.label)
|
||||
EndTextCommandSetBlipName(blip)
|
||||
end
|
||||
end
|
||||
|
||||
-- Main Thread für Zone Detection
|
||||
CreateThread(function()
|
||||
while true do
|
||||
local sleep = 1000
|
||||
local ped = PlayerPedId()
|
||||
local coords = GetEntityCoords(ped)
|
||||
|
||||
for k, v in pairs(Config.TrainingZones) do
|
||||
local distance = #(coords - vector3(v.coords.x, v.coords.y, v.coords.z))
|
||||
|
||||
if distance < v.radius then
|
||||
sleep = 0
|
||||
if not isInTrainingZone then
|
||||
isInTrainingZone = true
|
||||
currentZone = k
|
||||
ShowHelpText()
|
||||
end
|
||||
|
||||
if IsControlJustReleased(0, 38) then -- E Key
|
||||
StartTrainingScenario(v.scenario)
|
||||
end
|
||||
elseif isInTrainingZone and currentZone == k then
|
||||
isInTrainingZone = false
|
||||
currentZone = nil
|
||||
end
|
||||
end
|
||||
|
||||
Wait(sleep)
|
||||
end
|
||||
end)
|
||||
|
||||
-- Zeige Help Text
|
||||
function ShowHelpText()
|
||||
CreateThread(function()
|
||||
while isInTrainingZone do
|
||||
local zoneData = Config.TrainingZones[currentZone]
|
||||
QBCore.Functions.DrawText3D(zoneData.coords.x, zoneData.coords.y, zoneData.coords.z + 1.0,
|
||||
'[E] - ' .. zoneData.label)
|
||||
Wait(0)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
-- Starte Training Scenario
|
||||
function StartTrainingScenario(scenario)
|
||||
if isInScenario then
|
||||
QBCore.Functions.Notify('Du bist bereits in einem Szenario!', 'error')
|
||||
return
|
||||
end
|
||||
|
||||
local ped = PlayerPedId()
|
||||
|
||||
-- Prüfe ob Szenario existiert
|
||||
if not DoesScenarioExist(scenario) then
|
||||
QBCore.Functions.Notify('Szenario existiert nicht!', 'error')
|
||||
return
|
||||
end
|
||||
|
||||
isInScenario = true
|
||||
TaskStartScenarioInPlace(ped, scenario, 0, true)
|
||||
|
||||
QBCore.Functions.Notify('Szenario gestartet! Drücke [X] zum Beenden', 'success')
|
||||
|
||||
-- Thread zum Beenden des Szenarios
|
||||
CreateThread(function()
|
||||
while isInScenario do
|
||||
if IsControlJustReleased(0, 73) then -- X Key
|
||||
StopTrainingScenario()
|
||||
break
|
||||
end
|
||||
Wait(0)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
-- Stoppe Training Scenario
|
||||
function StopTrainingScenario()
|
||||
if not isInScenario then return end
|
||||
|
||||
local ped = PlayerPedId()
|
||||
ClearPedTasks(ped)
|
||||
isInScenario = false
|
||||
|
||||
QBCore.Functions.Notify('Szenario beendet!', 'primary')
|
||||
end
|
||||
|
||||
-- Event Handler für externe Triggers
|
||||
RegisterNetEvent('train:startscenario', function(scenario)
|
||||
if not scenario then
|
||||
QBCore.Functions.Notify('Kein Szenario angegeben!', 'error')
|
||||
return
|
||||
end
|
||||
|
||||
StartTrainingScenario(scenario)
|
||||
end)
|
||||
|
||||
-- Utility Functions
|
||||
QBCore.Functions.DrawText3D = function(x, y, z, text)
|
||||
SetTextScale(0.35, 0.35)
|
||||
SetTextFont(4)
|
||||
SetTextProportional(1)
|
||||
SetTextColour(255, 255, 255, 215)
|
||||
SetTextEntry("STRING")
|
||||
SetTextCentre(true)
|
||||
AddTextComponentString(text)
|
||||
SetDrawOrigin(x, y, z, 0)
|
||||
DrawText(0.0, 0.0)
|
||||
local factor = (string.len(text)) / 370
|
||||
DrawRect(0.0, 0.0+0.0125, 0.017+ factor, 0.03, 0, 0, 0, 75)
|
||||
ClearDrawOrigin()
|
||||
end
|
|
@ -1,20 +1,17 @@
|
|||
fx_version 'cerulean'
|
||||
game 'gta5'
|
||||
|
||||
author 'Dein Name'
|
||||
description 'QBCore Train Scenario Trigger Script'
|
||||
description 'QB-TrainingScenarios'
|
||||
version '1.0.0'
|
||||
|
||||
server_scripts {
|
||||
'server.lua'
|
||||
shared_scripts {
|
||||
'shared/config.lua'
|
||||
}
|
||||
|
||||
client_scripts {
|
||||
'client.lua'
|
||||
'client/main.lua'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
'qb-core'
|
||||
}
|
||||
|
||||
lua54 'yes'
|
||||
|
|
|
@ -20,6 +20,7 @@ shared_scripts {
|
|||
|
||||
client_scripts {
|
||||
'client.lua',
|
||||
'train_interaction.lua'
|
||||
}
|
||||
|
||||
server_scripts {
|
||||
|
|
152
resources/[tools]/cfx_nteam_train_scenario/train_interaction.lua
Normal file
152
resources/[tools]/cfx_nteam_train_scenario/train_interaction.lua
Normal file
|
@ -0,0 +1,152 @@
|
|||
-- train_interaction.lua
|
||||
|
||||
-- Configuration for the interaction point
|
||||
local interactionPoint = {
|
||||
coords = vector3(126.0, -1037.0, 29.3), -- Change to your desired location
|
||||
radius = 2.0,
|
||||
text = "Press ~INPUT_CONTEXT~ to use train transportation"
|
||||
}
|
||||
|
||||
-- Available scenarios
|
||||
local scenarios = {
|
||||
{name = "Welcome", label = "City Center"},
|
||||
{name = "Jail", label = "Prison"},
|
||||
{name = "Paleto", label = "Paleto Bay"}
|
||||
}
|
||||
|
||||
-- Variables
|
||||
local isInMarker = false
|
||||
local menuOpen = false
|
||||
|
||||
-- Function to draw 3D text
|
||||
function Draw3DText(x, y, z, text)
|
||||
local onScreen, _x, _y = World3dToScreen2d(x, y, z)
|
||||
local px, py, pz = table.unpack(GetGameplayCamCoords())
|
||||
|
||||
SetTextScale(0.35, 0.35)
|
||||
SetTextFont(4)
|
||||
SetTextProportional(1)
|
||||
SetTextColour(255, 255, 255, 215)
|
||||
SetTextEntry("STRING")
|
||||
SetTextCentre(1)
|
||||
AddTextComponentString(text)
|
||||
DrawText(_x, _y)
|
||||
local factor = (string.len(text)) / 370
|
||||
DrawRect(_x, _y + 0.0125, 0.015 + factor, 0.03, 41, 11, 41, 68)
|
||||
end
|
||||
|
||||
-- Function to open scenario selection menu
|
||||
function OpenScenarioMenu()
|
||||
menuOpen = true
|
||||
|
||||
-- Simple menu display
|
||||
Citizen.CreateThread(function()
|
||||
local selected = 1
|
||||
|
||||
while menuOpen do
|
||||
Citizen.Wait(0)
|
||||
|
||||
-- Draw background
|
||||
DrawRect(0.5, 0.5, 0.3, 0.5, 0, 0, 0, 200)
|
||||
|
||||
-- Draw title
|
||||
SetTextFont(4)
|
||||
SetTextScale(0.5, 0.5)
|
||||
SetTextColour(255, 255, 255, 255)
|
||||
SetTextCentre(true)
|
||||
SetTextEntry("STRING")
|
||||
AddTextComponentString("Train Transportation")
|
||||
DrawText(0.5, 0.3)
|
||||
|
||||
-- Draw options
|
||||
for i, scenario in ipairs(scenarios) do
|
||||
local y = 0.35 + (i * 0.05)
|
||||
local color = {r = 255, g = 255, b = 255}
|
||||
|
||||
if selected == i then
|
||||
color = {r = 255, g = 255, b = 0}
|
||||
DrawRect(0.5, y, 0.28, 0.04, 41, 41, 41, 200)
|
||||
end
|
||||
|
||||
SetTextFont(4)
|
||||
SetTextScale(0.35, 0.35)
|
||||
SetTextColour(color.r, color.g, color.b, 255)
|
||||
SetTextCentre(true)
|
||||
SetTextEntry("STRING")
|
||||
AddTextComponentString(scenario.label)
|
||||
DrawText(0.5, y - 0.015)
|
||||
end
|
||||
|
||||
-- Instructions
|
||||
SetTextFont(4)
|
||||
SetTextScale(0.3, 0.3)
|
||||
SetTextColour(255, 255, 255, 255)
|
||||
SetTextCentre(true)
|
||||
SetTextEntry("STRING")
|
||||
AddTextComponentString("↑/↓: Navigate | ENTER: Select | BACKSPACE: Cancel")
|
||||
DrawText(0.5, 0.65)
|
||||
|
||||
-- Handle controls
|
||||
DisableControlAction(0, 172, true) -- UP
|
||||
DisableControlAction(0, 173, true) -- DOWN
|
||||
DisableControlAction(0, 176, true) -- ENTER
|
||||
DisableControlAction(0, 177, true) -- BACKSPACE
|
||||
|
||||
if IsDisabledControlJustPressed(0, 172) then -- UP
|
||||
selected = selected - 1
|
||||
if selected < 1 then selected = #scenarios end
|
||||
PlaySoundFrontend(-1, "NAV_UP_DOWN", "HUD_FRONTEND_DEFAULT_SOUNDSET", true)
|
||||
elseif IsDisabledControlJustPressed(0, 173) then -- DOWN
|
||||
selected = selected + 1
|
||||
if selected > #scenarios then selected = 1 end
|
||||
PlaySoundFrontend(-1, "NAV_UP_DOWN", "HUD_FRONTEND_DEFAULT_SOUNDSET", true)
|
||||
elseif IsDisabledControlJustPressed(0, 176) then -- ENTER
|
||||
menuOpen = false
|
||||
PlaySoundFrontend(-1, "SELECT", "HUD_FRONTEND_DEFAULT_SOUNDSET", true)
|
||||
TriggerEvent('train:startscenario', scenarios[selected].name)
|
||||
elseif IsDisabledControlJustPressed(0, 177) then -- BACKSPACE
|
||||
menuOpen = false
|
||||
PlaySoundFrontend(-1, "CANCEL", "HUD_FRONTEND_DEFAULT_SOUNDSET", true)
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
-- Main thread for checking player position
|
||||
Citizen.CreateThread(function()
|
||||
while true do
|
||||
Citizen.Wait(0)
|
||||
|
||||
local playerPed = PlayerPedId()
|
||||
local coords = GetEntityCoords(playerPed)
|
||||
local dist = #(coords - interactionPoint.coords)
|
||||
|
||||
if dist < interactionPoint.radius then
|
||||
isInMarker = true
|
||||
Draw3DText(interactionPoint.coords.x, interactionPoint.coords.y, interactionPoint.coords.z + 1.0, interactionPoint.text)
|
||||
|
||||
-- Check for E press
|
||||
if IsControlJustReleased(0, 38) and not menuOpen then -- 38 is E
|
||||
OpenScenarioMenu()
|
||||
end
|
||||
else
|
||||
isInMarker = false
|
||||
if menuOpen then
|
||||
menuOpen = false
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
-- Create a blip on the map (optional)
|
||||
Citizen.CreateThread(function()
|
||||
local blip = AddBlipForCoord(interactionPoint.coords)
|
||||
SetBlipSprite(blip, 513) -- Train sprite
|
||||
SetBlipDisplay(blip, 4)
|
||||
SetBlipScale(blip, 0.8)
|
||||
SetBlipColour(blip, 2)
|
||||
SetBlipAsShortRange(blip, true)
|
||||
BeginTextCommandSetBlipName("STRING")
|
||||
AddTextComponentString("Train Transportation")
|
||||
EndTextCommandSetBlipName(blip)
|
||||
end)
|
Loading…
Add table
Add a link
Reference in a new issue