forked from Simnation/Main
ed
This commit is contained in:
parent
8955836c2c
commit
7b079c6109
4 changed files with 704 additions and 0 deletions
446
resources/[freizeit]/nordi_ai_train/client.lua
Normal file
446
resources/[freizeit]/nordi_ai_train/client.lua
Normal file
|
@ -0,0 +1,446 @@
|
|||
local QBCore = exports['qb-core']:GetCoreObject()
|
||||
local lib = exports.ox_lib
|
||||
local PlayerData = {}
|
||||
local nearbyTrains = {}
|
||||
local currentTrain = nil
|
||||
local isRiding = false
|
||||
local cinemaCam = nil
|
||||
|
||||
RegisterNetEvent('QBCore:Client:OnPlayerLoaded', function()
|
||||
PlayerData = QBCore.Functions.GetPlayerData()
|
||||
CreateStationBlips()
|
||||
end)
|
||||
|
||||
-- Bahnhof Blips erstellen
|
||||
function CreateStationBlips()
|
||||
for _, station in pairs(Config.TrainStations) do
|
||||
local blip = AddBlipForCoord(station.coords.x, station.coords.y, station.coords.z)
|
||||
SetBlipSprite(blip, station.blip.sprite)
|
||||
SetBlipDisplay(blip, 4)
|
||||
SetBlipScale(blip, station.blip.scale)
|
||||
SetBlipColour(blip, station.blip.color)
|
||||
BeginTextCommandSetBlipName("STRING")
|
||||
AddTextComponentString("🚂 " .. station.name)
|
||||
EndTextCommandSetBlipName(blip)
|
||||
end
|
||||
end
|
||||
|
||||
-- Zug spawnen
|
||||
function SpawnTrainAtLocation(station)
|
||||
local model = GetHashKey(Config.TrainCars.main)
|
||||
|
||||
RequestModel(model)
|
||||
while not HasModelLoaded(model) do
|
||||
Wait(500)
|
||||
end
|
||||
|
||||
local train = CreateMissionTrain(24, station.coords.x, station.coords.y, station.coords.z, true)
|
||||
|
||||
if DoesEntityExist(train) then
|
||||
SetEntityHeading(train, station.coords.w)
|
||||
SetTrainSpeed(train, 0.0)
|
||||
SetTrainCruiseSpeed(train, 0.0)
|
||||
|
||||
-- Waggons hinzufügen
|
||||
Wait(1000)
|
||||
for _, carModel in pairs(Config.TrainCars.cars) do
|
||||
local carHash = GetHashKey(carModel)
|
||||
RequestModel(carHash)
|
||||
while not HasModelLoaded(carHash) do
|
||||
Wait(500)
|
||||
end
|
||||
CreateMissionTrainCar(train, carHash, false, false, false)
|
||||
end
|
||||
|
||||
if Config.Debug then
|
||||
print("Zug gespawnt bei: " .. station.name)
|
||||
end
|
||||
|
||||
return train
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
-- Züge in der Nähe finden
|
||||
function FindNearbyTrains()
|
||||
local playerPed = PlayerPedId()
|
||||
local playerCoords = GetEntityCoords(playerPed)
|
||||
local trains = {}
|
||||
|
||||
local vehicles = GetGamePool('CVehicle')
|
||||
for _, vehicle in pairs(vehicles) do
|
||||
if DoesEntityExist(vehicle) then
|
||||
local model = GetEntityModel(vehicle)
|
||||
|
||||
if IsThisModelATrain(model) then
|
||||
local trainCoords = GetEntityCoords(vehicle)
|
||||
local distance = #(playerCoords - trainCoords)
|
||||
|
||||
if distance <= Config.InteractionDistance then
|
||||
table.insert(trains, {
|
||||
entity = vehicle,
|
||||
coords = trainCoords,
|
||||
distance = distance
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return trains
|
||||
end
|
||||
|
||||
-- ox_lib Zielmenü öffnen
|
||||
function OpenDestinationMenu(train)
|
||||
local playerCoords = GetEntityCoords(PlayerPedId())
|
||||
local currentStation = GetNearestStation(playerCoords)
|
||||
|
||||
local options = {}
|
||||
|
||||
for _, station in pairs(Config.TrainStations) do
|
||||
if station.name ~= currentStation then
|
||||
local icon = Config.Menu.stationIcons.city -- Standard Icon
|
||||
|
||||
-- Icon basierend auf Station wählen
|
||||
if string.find(station.name:lower(), "depot") then
|
||||
icon = Config.Menu.stationIcons.depot
|
||||
elseif string.find(station.name:lower(), "island") or string.find(station.name:lower(), "terminal") then
|
||||
icon = Config.Menu.stationIcons.port
|
||||
elseif string.find(station.name:lower(), "industrial") then
|
||||
icon = Config.Menu.stationIcons.industrial
|
||||
elseif string.find(station.name:lower(), "bay") then
|
||||
icon = Config.Menu.stationIcons.rural
|
||||
end
|
||||
|
||||
table.insert(options, {
|
||||
title = icon .. " " .. station.name,
|
||||
description = station.description .. " - " .. Config.Menu.texts.price .. ": $" .. station.price,
|
||||
icon = 'train',
|
||||
onSelect = function()
|
||||
SelectDestination(train, station)
|
||||
end,
|
||||
metadata = {
|
||||
{label = Config.Menu.texts.price, value = "$" .. station.price},
|
||||
{label = "Entfernung", value = math.floor(#(playerCoords - vector3(station.coords.x, station.coords.y, station.coords.z))) .. "m"}
|
||||
}
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
table.insert(options, {
|
||||
title = "❌ " .. Config.Menu.texts.cancel,
|
||||
description = "Menü schließen",
|
||||
icon = 'xmark'
|
||||
})
|
||||
|
||||
lib:registerContext({
|
||||
id = 'train_destination_menu',
|
||||
title = Config.Menu.title,
|
||||
options = options,
|
||||
position = Config.Menu.position
|
||||
})
|
||||
|
||||
lib:showContext('train_destination_menu')
|
||||
end
|
||||
|
||||
-- Ziel auswählen
|
||||
function SelectDestination(train, destination)
|
||||
if not DoesEntityExist(train) then
|
||||
lib:notify({
|
||||
title = 'Fehler',
|
||||
description = Config.Menu.texts.trainNotAvailable,
|
||||
type = Config.Notifications.types.error,
|
||||
duration = Config.Notifications.duration.short
|
||||
})
|
||||
return
|
||||
end
|
||||
|
||||
-- Geld prüfen
|
||||
QBCore.Functions.TriggerCallback('train:server:canAfford', function(canAfford)
|
||||
if canAfford then
|
||||
StartTrainJourney(train, destination)
|
||||
else
|
||||
lib:notify({
|
||||
title = 'Nicht genug Geld',
|
||||
description = Config.Menu.texts.notEnoughMoney .. " ($" .. destination.price .. ")",
|
||||
type = Config.Notifications.types.error,
|
||||
duration = Config.Notifications.duration.medium
|
||||
})
|
||||
end
|
||||
end, destination.price)
|
||||
end
|
||||
|
||||
-- Nächste Station finden
|
||||
function GetNearestStation(coords)
|
||||
local nearestStation = nil
|
||||
local nearestDistance = math.huge
|
||||
|
||||
for _, station in pairs(Config.TrainStations) do
|
||||
local distance = #(coords - vector3(station.coords.x, station.coords.y, station.coords.z))
|
||||
if distance < nearestDistance then
|
||||
nearestDistance = distance
|
||||
nearestStation = station.name
|
||||
end
|
||||
end
|
||||
|
||||
return nearestStation
|
||||
end
|
||||
|
||||
-- Zugfahrt starten
|
||||
function StartTrainJourney(train, destination)
|
||||
local playerPed = PlayerPedId()
|
||||
currentTrain = train
|
||||
isRiding = true
|
||||
|
||||
-- Spieler in Zug setzen
|
||||
SetPedIntoVehicle(playerPed, train, 1)
|
||||
|
||||
-- Benachrichtigung
|
||||
lib:notify({
|
||||
title = '🚂 ' .. Config.Menu.texts.journeyStarted,
|
||||
description = "Fahrt nach " .. destination.name,
|
||||
type = Config.Notifications.types.success,
|
||||
duration = Config.Notifications.duration.medium
|
||||
})
|
||||
|
||||
-- Cinema Kamera starten
|
||||
if Config.CinemaCamera.enabled then
|
||||
StartCinemaCamera(train)
|
||||
end
|
||||
|
||||
-- Automatische Fahrt
|
||||
CreateThread(function()
|
||||
Wait(3000)
|
||||
|
||||
lib:notify({
|
||||
title = '🚂 ' .. Config.Menu.texts.trainDeparting,
|
||||
description = "Nächster Halt: " .. destination.name,
|
||||
type = Config.Notifications.types.info,
|
||||
duration = Config.Notifications.duration.short
|
||||
})
|
||||
|
||||
DriveTrainToDestination(train, destination)
|
||||
end)
|
||||
|
||||
-- Journey loggen
|
||||
if Config.DebugOptions.logJourneys then
|
||||
TriggerServerEvent('train:server:logJourney', GetNearestStation(GetEntityCoords(playerPed)), destination.name, destination.price)
|
||||
end
|
||||
end
|
||||
|
||||
-- Cinema Kamera
|
||||
function StartCinemaCamera(train)
|
||||
if cinemaCam then
|
||||
DestroyCam(cinemaCam, false)
|
||||
end
|
||||
|
||||
CreateThread(function()
|
||||
while isRiding and DoesEntityExist(train) do
|
||||
for _, camPos in pairs(Config.CinemaCamera.positions) do
|
||||
if not isRiding then break end
|
||||
|
||||
if cinemaCam then
|
||||
DestroyCam(cinemaCam, false)
|
||||
end
|
||||
|
||||
local trainCoords = GetEntityCoords(train)
|
||||
local trainHeading = GetEntityHeading(train)
|
||||
local camCoords = trainCoords + camPos.offset
|
||||
|
||||
cinemaCam = CreateCam("DEFAULT_SCRIPTED_CAMERA", true)
|
||||
SetCamCoord(cinemaCam, camCoords.x, camCoords.y, camCoords.z)
|
||||
SetCamRot(cinemaCam, camPos.rotation.x, camPos.rotation.y, camPos.rotation.z + trainHeading, 2)
|
||||
SetCamActive(cinemaCam, true)
|
||||
RenderScriptCams(true, true, 1000, true, true)
|
||||
|
||||
local holdTime = math.random(Config.CinemaCamera.switchInterval.min, Config.CinemaCamera.switchInterval.max)
|
||||
Wait(holdTime)
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
-- Zug zur Destination fahren
|
||||
function DriveTrainToDestination(train, destination)
|
||||
CreateThread(function()
|
||||
local targetCoords = vector3(destination.coords.x, destination.coords.y, destination.coords.z)
|
||||
local arrived = false
|
||||
|
||||
-- Beschleunigung
|
||||
for speed = 0, Config.TrainSpeed.max, Config.TrainSpeed.acceleration do
|
||||
if not DoesEntityExist(train) then return end
|
||||
SetTrainSpeed(train, speed)
|
||||
SetTrainCruiseSpeed(train, speed)
|
||||
Wait(500)
|
||||
end
|
||||
|
||||
-- Fahrt
|
||||
while not arrived and DoesEntityExist(train) and isRiding do
|
||||
local trainCoords = GetEntityCoords(train)
|
||||
local distance = #(trainCoords - targetCoords)
|
||||
|
||||
if distance < 200 then
|
||||
local newSpeed = math.max(Config.TrainSpeed.min, distance / 20)
|
||||
SetTrainSpeed(train, newSpeed)
|
||||
SetTrainCruiseSpeed(train, newSpeed)
|
||||
end
|
||||
|
||||
if distance < 50 then
|
||||
arrived = true
|
||||
SetTrainSpeed(train, 0)
|
||||
SetTrainCruiseSpeed(train, 0)
|
||||
|
||||
Wait(2000)
|
||||
|
||||
lib:notify({
|
||||
title = '🚂 ' .. Config.Menu.texts.arrived,
|
||||
description = destination.name,
|
||||
type = Config.Notifications.types.success,
|
||||
duration = Config.Notifications.duration.medium
|
||||
})
|
||||
|
||||
lib:notify({
|
||||
title = Config.Menu.texts.thankYou,
|
||||
description = "Gute Weiterreise!",
|
||||
type = Config.Notifications.types.info,
|
||||
duration = Config.Notifications.duration.short
|
||||
})
|
||||
|
||||
EndTrainJourney()
|
||||
end
|
||||
|
||||
Wait(1000)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
-- Zugfahrt beenden
|
||||
function EndTrainJourney()
|
||||
isRiding = false
|
||||
|
||||
if cinemaCam then
|
||||
RenderScriptCams(false, true, 1000, true, true)
|
||||
DestroyCam(cinemaCam, false)
|
||||
cinemaCam = nil
|
||||
end
|
||||
|
||||
if currentTrain and DoesEntityExist(currentTrain) then
|
||||
local playerPed = PlayerPedId()
|
||||
TaskLeaveVehicle(playerPed, currentTrain, 0)
|
||||
end
|
||||
|
||||
currentTrain = nil
|
||||
|
||||
Wait(3000)
|
||||
lib:notify({
|
||||
title = Config.Menu.texts.canExit,
|
||||
type = Config.Notifications.types.info,
|
||||
duration = Config.Notifications.duration.short
|
||||
})
|
||||
end
|
||||
|
||||
-- 3D Text zeichnen
|
||||
function DrawText3D(x, y, z, text)
|
||||
local onScreen, _x, _y = World3dToScreen2d(x, y, z)
|
||||
|
||||
if onScreen then
|
||||
SetTextScale(Config.DrawText.scale, Config.DrawText.scale)
|
||||
SetTextFont(Config.DrawText.font)
|
||||
SetTextProportional(1)
|
||||
SetTextColour(Config.DrawText.color.r, Config.DrawText.color.g, Config.DrawText.color.b, Config.DrawText.color.a)
|
||||
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,
|
||||
Config.DrawText.backgroundColor.r,
|
||||
Config.DrawText.backgroundColor.g,
|
||||
Config.DrawText.backgroundColor.b,
|
||||
Config.DrawText.backgroundColor.a)
|
||||
end
|
||||
end
|
||||
|
||||
-- Haupt-Loop
|
||||
CreateThread(function()
|
||||
while true do
|
||||
local sleep = 1000
|
||||
local playerPed = PlayerPedId()
|
||||
local playerCoords = GetEntityCoords(playerPed)
|
||||
|
||||
if not isRiding and not IsPedInAnyVehicle(playerPed, false) then
|
||||
nearbyTrains = FindNearbyTrains()
|
||||
|
||||
for _, train in pairs(nearbyTrains) do
|
||||
if train.distance <= 5.0 then
|
||||
sleep = 0
|
||||
|
||||
DrawText3D(train.coords.x, train.coords.y, train.coords.z + 2.0, Config.DrawText.interactText)
|
||||
|
||||
if IsControlJustPressed(0, 38) then -- E
|
||||
OpenDestinationMenu(train.entity)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if isRiding then
|
||||
sleep = 0
|
||||
if IsControlJustPressed(0, 23) then -- F
|
||||
lib:notify({
|
||||
title = Config.Menu.texts.emergencyExit,
|
||||
type = Config.Notifications.types.warning,
|
||||
duration = Config.Notifications.duration.short
|
||||
})
|
||||
EndTrainJourney()
|
||||
end
|
||||
end
|
||||
|
||||
Wait(sleep)
|
||||
end
|
||||
end)
|
||||
|
||||
-- Commands
|
||||
RegisterCommand('spawntrain', function(source, args)
|
||||
local stationId = args[1] or Config.TrainStations[1].id
|
||||
local station = nil
|
||||
|
||||
for _, s in pairs(Config.TrainStations) do
|
||||
if s.id == stationId then
|
||||
station = s
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if station then
|
||||
SpawnTrainAtLocation(station)
|
||||
lib:notify({
|
||||
title = 'Zug gespawnt',
|
||||
description = station.name,
|
||||
type = Config.Notifications.types.success
|
||||
})
|
||||
end
|
||||
end)
|
||||
|
||||
-- Auto-Spawn
|
||||
if Config.AutoSpawn.enabled then
|
||||
CreateThread(function()
|
||||
Wait(Config.AutoSpawn.delay)
|
||||
|
||||
for i = 1, Config.AutoSpawn.maxTrains do
|
||||
local randomStation = Config.TrainStations[math.random(1, #Config.TrainStations)]
|
||||
SpawnTrainAtLocation(randomStation)
|
||||
Wait(Config.AutoSpawn.spawnInterval)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
-- Cleanup
|
||||
AddEventHandler('onResourceStop', function(resourceName)
|
||||
if GetCurrentResourceName() == resourceName then
|
||||
if isRiding then
|
||||
EndTrainJourney()
|
||||
end
|
||||
end
|
||||
end)
|
201
resources/[freizeit]/nordi_ai_train/config.lua
Normal file
201
resources/[freizeit]/nordi_ai_train/config.lua
Normal file
|
@ -0,0 +1,201 @@
|
|||
Config = {}
|
||||
|
||||
-- Allgemeine Einstellungen
|
||||
Config.Debug = false
|
||||
Config.DefaultCurrency = 'cash' -- 'cash' oder 'bank'
|
||||
Config.InteractionDistance = 8.0
|
||||
Config.TrainSpeed = {
|
||||
min = 5.0,
|
||||
max = 25.0,
|
||||
acceleration = 2.0
|
||||
}
|
||||
|
||||
-- Cinema Kamera Einstellungen
|
||||
Config.CinemaCamera = {
|
||||
enabled = true,
|
||||
switchInterval = {min = 8000, max = 12000}, -- Zeit zwischen Kamerawechseln
|
||||
positions = {
|
||||
{
|
||||
offset = vector3(15.0, 5.0, 5.0),
|
||||
rotation = vector3(-10.0, 0.0, 90.0)
|
||||
},
|
||||
{
|
||||
offset = vector3(10.0, 15.0, 8.0),
|
||||
rotation = vector3(-15.0, 0.0, 45.0)
|
||||
},
|
||||
{
|
||||
offset = vector3(-10.0, -15.0, 6.0),
|
||||
rotation = vector3(-5.0, 0.0, -135.0)
|
||||
},
|
||||
{
|
||||
offset = vector3(0.0, -20.0, 15.0),
|
||||
rotation = vector3(-20.0, 0.0, 0.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-- Zug Waggon Konfiguration
|
||||
Config.TrainCars = {
|
||||
main = "freight", -- Hauptlok
|
||||
cars = {"freightcar", "freightcont1", "freightgrain", "tankercar"}
|
||||
}
|
||||
|
||||
-- Bahnhöfe / Ziele
|
||||
Config.TrainStations = {
|
||||
{
|
||||
id = "sandy_depot",
|
||||
coords = vector4(2533.0, 2833.0, 38.0, 0.0),
|
||||
name = "Sandy Shores Depot",
|
||||
description = "Hauptdepot in Sandy Shores",
|
||||
price = 0, -- Startbahnhof kostenlos
|
||||
blip = {
|
||||
sprite = 795,
|
||||
color = 2,
|
||||
scale = 0.7
|
||||
}
|
||||
},
|
||||
{
|
||||
id = "sandy_north",
|
||||
coords = vector4(2606.0, 2927.0, 40.0, 90.0),
|
||||
name = "Sandy Shores Nord",
|
||||
description = "Nördlicher Bahnhof von Sandy Shores",
|
||||
price = 50,
|
||||
blip = {
|
||||
sprite = 795,
|
||||
color = 3,
|
||||
scale = 0.7
|
||||
}
|
||||
},
|
||||
{
|
||||
id = "ls_depot",
|
||||
coords = vector4(1164.0, -3250.0, 7.0, 180.0),
|
||||
name = "Los Santos Hauptbahnhof",
|
||||
description = "Zentraler Bahnhof in Los Santos",
|
||||
price = 150,
|
||||
blip = {
|
||||
sprite = 795,
|
||||
color = 1,
|
||||
scale = 0.8
|
||||
}
|
||||
},
|
||||
{
|
||||
id = "elysian",
|
||||
coords = vector4(219.0, -2487.0, 6.0, 270.0),
|
||||
name = "Elysian Island",
|
||||
description = "Industriegebiet am Hafen",
|
||||
price = 100,
|
||||
blip = {
|
||||
sprite = 795,
|
||||
color = 4,
|
||||
scale = 0.7
|
||||
}
|
||||
},
|
||||
{
|
||||
id = "terminal",
|
||||
coords = vector4(-1100.0, -2724.0, 13.0, 0.0),
|
||||
name = "Fracht Terminal",
|
||||
description = "Großes Frachtterminal",
|
||||
price = 200,
|
||||
blip = {
|
||||
sprite = 795,
|
||||
color = 5,
|
||||
scale = 0.7
|
||||
}
|
||||
},
|
||||
{
|
||||
id = "downtown",
|
||||
coords = vector4(-500.0, -1500.0, 10.0, 45.0),
|
||||
name = "Downtown Station",
|
||||
description = "Bahnhof in der Innenstadt",
|
||||
price = 75,
|
||||
blip = {
|
||||
sprite = 795,
|
||||
color = 6,
|
||||
scale = 0.7
|
||||
}
|
||||
},
|
||||
{
|
||||
id = "paleto",
|
||||
coords = vector4(100.0, 6500.0, 32.0, 180.0),
|
||||
name = "Paleto Bay",
|
||||
description = "Kleiner Bahnhof in Paleto Bay",
|
||||
price = 250,
|
||||
blip = {
|
||||
sprite = 795,
|
||||
color = 7,
|
||||
scale = 0.7
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-- Menü Texte und Einstellungen
|
||||
Config.Menu = {
|
||||
title = "🚂 Zugfahrkarten",
|
||||
subtitle = "Wählen Sie Ihr Reiseziel",
|
||||
position = "top-right", -- ox_lib menu position
|
||||
|
||||
-- Texte
|
||||
texts = {
|
||||
selectDestination = "Ziel auswählen",
|
||||
price = "Preis",
|
||||
description = "Beschreibung",
|
||||
cancel = "Abbrechen",
|
||||
notEnoughMoney = "Nicht genug Geld",
|
||||
trainNotAvailable = "Zug nicht verfügbar",
|
||||
journeyStarted = "Zugfahrt gestartet",
|
||||
trainDeparting = "Der Zug fährt ab",
|
||||
arrived = "Ankunft",
|
||||
thankYou = "Vielen Dank für die Fahrt",
|
||||
emergencyExit = "Notfall-Ausstieg",
|
||||
canExit = "Sie können jetzt aussteigen"
|
||||
},
|
||||
|
||||
-- Icons für verschiedene Stationstypen
|
||||
stationIcons = {
|
||||
depot = "🏭",
|
||||
city = "🏢",
|
||||
industrial = "🏗️",
|
||||
port = "⚓",
|
||||
rural = "🌾"
|
||||
}
|
||||
}
|
||||
|
||||
-- Nachrichten Einstellungen
|
||||
Config.Notifications = {
|
||||
duration = {
|
||||
short = 3000,
|
||||
medium = 5000,
|
||||
long = 8000
|
||||
},
|
||||
types = {
|
||||
success = "success",
|
||||
error = "error",
|
||||
info = "info",
|
||||
warning = "warning"
|
||||
}
|
||||
}
|
||||
|
||||
-- Automatisches Spawnen
|
||||
Config.AutoSpawn = {
|
||||
enabled = true,
|
||||
delay = 10000, -- Wartezeit nach Server-Start
|
||||
maxTrains = 4, -- Maximale Anzahl gespawnter Züge
|
||||
spawnInterval = 3000 -- Zeit zwischen Spawns
|
||||
}
|
||||
|
||||
-- DrawText Einstellungen
|
||||
Config.DrawText = {
|
||||
font = 4,
|
||||
scale = 0.35,
|
||||
color = {r = 255, g = 255, b = 255, a = 215},
|
||||
backgroundColor = {r = 41, g = 128, b = 185, a = 100},
|
||||
interactText = "[E] Zug besteigen",
|
||||
emergencyText = "[F] Notfall-Ausstieg"
|
||||
}
|
||||
|
||||
-- Debug Einstellungen
|
||||
Config.DebugOptions = {
|
||||
showCoords = false,
|
||||
showDistance = false,
|
||||
logJourneys = true
|
||||
}
|
24
resources/[freizeit]/nordi_ai_train/fxmanifest.lua
Normal file
24
resources/[freizeit]/nordi_ai_train/fxmanifest.lua
Normal file
|
@ -0,0 +1,24 @@
|
|||
fx_version 'cerulean'
|
||||
game 'gta5'
|
||||
|
||||
description 'QBCore Train System with ox_lib'
|
||||
version '2.0.0'
|
||||
|
||||
shared_scripts {
|
||||
'config.lua'
|
||||
}
|
||||
|
||||
client_scripts {
|
||||
'client.lua'
|
||||
}
|
||||
|
||||
server_scripts {
|
||||
'server.lua'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
'qb-core',
|
||||
'ox_lib'
|
||||
}
|
||||
|
||||
lua54 'yes'
|
33
resources/[freizeit]/nordi_ai_train/server.lua
Normal file
33
resources/[freizeit]/nordi_ai_train/server.lua
Normal file
|
@ -0,0 +1,33 @@
|
|||
local QBCore = exports['qb-core']:GetCoreObject()
|
||||
|
||||
-- Geld prüfen
|
||||
QBCore.Functions.CreateCallback('train:server:canAfford', function(source, cb, price)
|
||||
local Player = QBCore.Functions.GetPlayer(source)
|
||||
if Player then
|
||||
local money = Player.PlayerData.money[Config.DefaultCurrency]
|
||||
if money >= price then
|
||||
Player.Functions.RemoveMoney(Config.DefaultCurrency, price)
|
||||
cb(true)
|
||||
else
|
||||
cb(false)
|
||||
end
|
||||
else
|
||||
cb(false)
|
||||
end
|
||||
end)
|
||||
|
||||
-- Journey Log
|
||||
RegisterNetEvent('train:server:logJourney', function(from, to, price)
|
||||
if not Config.DebugOptions.logJourneys then return end
|
||||
|
||||
local src = source
|
||||
local Player = QBCore.Functions.GetPlayer(src)
|
||||
|
||||
if Player then
|
||||
print(string.format("[TRAIN] %s (%s) - %s → %s ($%d)",
|
||||
Player.PlayerData.charinfo.firstname .. " " .. Player.PlayerData.charinfo.lastname,
|
||||
Player.PlayerData.citizenid,
|
||||
from, to, price
|
||||
))
|
||||
end
|
||||
end)
|
Loading…
Add table
Add a link
Reference in a new issue