1
0
Fork 0
forked from Simnation/Main
This commit is contained in:
Nordi98 2025-08-13 18:02:58 +02:00
parent 3fa969a62c
commit b31336d080
19 changed files with 3844 additions and 85 deletions

Binary file not shown.

View 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.

Binary file not shown.

View 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
},
}

View 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'

View 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);

File diff suppressed because it is too large Load diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 757 B

View 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({}));
}
}
};
});
})

View 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;
}
}

View 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>

View file

@ -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")

View 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

View file

@ -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'

View file

@ -20,6 +20,7 @@ shared_scripts {
client_scripts {
'client.lua',
'train_interaction.lua'
}
server_scripts {

View 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)