2025-06-08 12:19:35 +02:00
|
|
|
QBCore = exports['qb-core']:GetCoreObject()
|
|
|
|
|
|
|
|
Player = nil
|
2025-06-25 12:52:13 +02:00
|
|
|
npcHandle = nil
|
|
|
|
isNPCSpawned = false
|
2025-06-09 18:14:06 +02:00
|
|
|
CurrentZone = nil
|
2025-06-08 12:19:35 +02:00
|
|
|
|
2025-06-25 13:05:25 +02:00
|
|
|
CurrentActionData = {}
|
|
|
|
hasAlreadyEnteredMarker = false
|
|
|
|
|
2025-06-08 12:19:35 +02:00
|
|
|
Citizen.CreateThread(function()
|
|
|
|
while Player == nil do
|
|
|
|
Player = exports['qb-core']:GetPlayerData()
|
|
|
|
Wait(0)
|
|
|
|
end
|
|
|
|
end)
|
|
|
|
|
2025-06-09 15:23:24 +02:00
|
|
|
Citizen.CreateThread(function()
|
|
|
|
while true do
|
2025-06-09 15:26:06 +02:00
|
|
|
Wait(15000)
|
2025-06-09 15:23:24 +02:00
|
|
|
local ped = PlayerPedId()
|
|
|
|
|
2025-06-09 15:30:45 +02:00
|
|
|
if IsPedInAnyVehicle(ped, false) then
|
2025-06-09 17:20:17 +02:00
|
|
|
local veh = GetVehiclePedIsIn(ped, false)
|
2025-06-09 17:21:31 +02:00
|
|
|
local mods = QBCore.Functions.GetVehicleProperties(veh)
|
2025-06-09 17:34:09 +02:00
|
|
|
print("Triggert setMods: "..json.encode(mods))
|
2025-06-09 15:23:24 +02:00
|
|
|
TriggerServerEvent('mh_garage:setMods', mods)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end)
|
|
|
|
|
2025-06-08 12:19:35 +02:00
|
|
|
-- Funktion zum Spawnen des NPCs
|
2025-06-08 13:12:49 +02:00
|
|
|
function SpawnGuardNPC(npc)
|
2025-06-08 12:19:35 +02:00
|
|
|
-- Ped Model laden
|
|
|
|
RequestModel(npc.model)
|
2025-06-08 13:44:19 +02:00
|
|
|
local timeout = 0
|
2025-06-08 13:45:42 +02:00
|
|
|
while not HasModelLoaded(npc.model) and timeout < 100 do
|
2025-06-08 13:44:19 +02:00
|
|
|
timeout = timeout + 1
|
|
|
|
Wait(100)
|
2025-06-08 12:19:35 +02:00
|
|
|
end
|
|
|
|
|
2025-06-08 13:45:42 +02:00
|
|
|
if not HasModelLoaded(npc.model) then
|
2025-06-08 13:44:19 +02:00
|
|
|
return
|
|
|
|
end
|
|
|
|
|
2025-06-08 12:19:35 +02:00
|
|
|
-- NPC erstellen
|
2025-06-08 13:52:14 +02:00
|
|
|
npcHandle = CreatePed(4, npc.model, npc.spawn.x, npc.spawn.y, npc.spawn.z, npc.spawn.w, false, true)
|
2025-06-08 13:44:19 +02:00
|
|
|
if not DoesEntityExist(npcHandle) then
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
2025-06-08 12:19:35 +02:00
|
|
|
-- NPC Eigenschaften setzen
|
|
|
|
SetEntityAsMissionEntity(npcHandle, true, true)
|
|
|
|
SetBlockingOfNonTemporaryEvents(npcHandle, true)
|
|
|
|
SetPedDiesWhenInjured(npcHandle, false)
|
|
|
|
SetPedCanPlayAmbientAnims(npcHandle, true)
|
|
|
|
SetPedCanRagdollFromPlayerImpact(npcHandle, false)
|
|
|
|
SetEntityInvincible(npcHandle, true)
|
2025-06-08 13:53:03 +02:00
|
|
|
FreezeEntityPosition(npcHandle, true)
|
2025-06-08 12:19:35 +02:00
|
|
|
|
|
|
|
-- Optional: Animation für den NPC
|
|
|
|
TaskStartScenarioInPlace(npcHandle, "WORLD_HUMAN_GUARD_STAND", 0, true)
|
|
|
|
|
|
|
|
isNPCSpawned = true
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Funktion zum Entfernen des NPCs
|
2025-06-08 13:12:49 +02:00
|
|
|
function RemoveGuardNPC()
|
2025-06-08 12:19:35 +02:00
|
|
|
if DoesEntityExist(npcHandle) then
|
|
|
|
DeleteEntity(npcHandle)
|
|
|
|
isNPCSpawned = false
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Hauptthread zum Überprüfen der Spieler-Position
|
|
|
|
CreateThread(function()
|
|
|
|
while true do
|
2025-06-25 13:06:15 +02:00
|
|
|
Wait(0)
|
2025-06-25 13:05:25 +02:00
|
|
|
local ped = PlayerPedId()
|
|
|
|
local coords = GetEntityCoords(ped)
|
|
|
|
|
|
|
|
local isInMarker = false
|
2025-06-08 12:19:35 +02:00
|
|
|
|
|
|
|
for k, v in pairs(Config.Zonen) do
|
2025-06-25 13:06:48 +02:00
|
|
|
local dist = #(coords - vector3(v.NPC.spawn.x, v.NPC.spawn.y, v.NPC.spawn.z))
|
2025-06-08 12:19:35 +02:00
|
|
|
local spawnDistance = v.NPC.distance
|
2025-06-25 13:05:25 +02:00
|
|
|
|
|
|
|
if dist <= spawnDistance then
|
|
|
|
isInMarker = true
|
2025-06-09 18:14:06 +02:00
|
|
|
CurrentZone = v
|
2025-06-08 12:19:35 +02:00
|
|
|
end
|
|
|
|
end
|
2025-06-25 13:05:25 +02:00
|
|
|
|
|
|
|
if isInMarker and not hasAlreadyEnteredMarker then
|
|
|
|
hasAlreadyEnteredMarker = true
|
|
|
|
SpawnGuardNPC(CurrentZone.NPC)
|
|
|
|
AddTargetOptions()
|
|
|
|
end
|
|
|
|
|
|
|
|
if not isInMarker and hasAlreadyEnteredMarker then
|
|
|
|
hasAlreadyEnteredMarker = false
|
|
|
|
CurrentZone = nil
|
|
|
|
exports['qb-target']:RemoveTargetEntity(npcHandle)
|
|
|
|
RemoveGuardNPC()
|
|
|
|
end
|
2025-06-08 12:19:35 +02:00
|
|
|
end
|
2025-06-08 14:04:18 +02:00
|
|
|
end)
|
|
|
|
|
2025-06-09 18:14:54 +02:00
|
|
|
function AddTargetOptions()
|
2025-06-09 14:13:06 +02:00
|
|
|
|
|
|
|
local opt = {
|
|
|
|
{
|
2025-06-09 14:17:23 +02:00
|
|
|
type = "client",
|
|
|
|
event = "mh_garage:storeVehicle",
|
|
|
|
icon = "fas fa-parking",
|
|
|
|
label = "Fahrzeug einparken",
|
|
|
|
},
|
2025-06-25 20:31:26 +02:00
|
|
|
{
|
|
|
|
type = "client",
|
|
|
|
event = "mh_garage:retrieveOwnerVehicle",
|
|
|
|
icon = "fas fa-car",
|
|
|
|
label = "Eigene Fahrzeug ausparken",
|
|
|
|
},
|
2025-06-09 14:17:23 +02:00
|
|
|
{
|
|
|
|
type = "client",
|
|
|
|
event = "mh_garage:retrieveVehicle",
|
|
|
|
icon = "fas fa-car",
|
2025-06-25 20:31:26 +02:00
|
|
|
label = "Schlüssel Fahrzeug ausparken",
|
2025-06-09 14:17:23 +02:00
|
|
|
}
|
2025-06-09 14:13:06 +02:00
|
|
|
}
|
2025-06-09 14:14:43 +02:00
|
|
|
|
|
|
|
if Config.Verwaltung.garage then
|
|
|
|
table.insert(opt, {
|
|
|
|
type = "client",
|
|
|
|
event = "mh_garage:verwaltungVeh",
|
2025-06-09 14:22:50 +02:00
|
|
|
icon = "hand",
|
2025-06-09 14:14:43 +02:00
|
|
|
label = "Fahrzeuge Verwalten",
|
|
|
|
})
|
|
|
|
end
|
|
|
|
|
2025-06-09 14:13:06 +02:00
|
|
|
exports['qb-target']:AddTargetEntity(npcHandle, {
|
|
|
|
options = opt,
|
2025-06-08 14:04:18 +02:00
|
|
|
distance = 2.5
|
|
|
|
})
|
2025-06-09 13:28:19 +02:00
|
|
|
end
|
|
|
|
|
2025-06-09 18:14:06 +02:00
|
|
|
function Notification(text, type)
|
2025-06-09 13:28:19 +02:00
|
|
|
lib.notify({
|
2025-06-09 18:14:06 +02:00
|
|
|
title = "Garage - "..CurrentZone.name,
|
2025-06-09 13:28:19 +02:00
|
|
|
description = text,
|
|
|
|
type = type,
|
|
|
|
position = 'top',
|
|
|
|
})
|
|
|
|
end
|
|
|
|
|
|
|
|
---------------------------- NetEvents
|
|
|
|
RegisterNetEvent('mh_jobgarage:notify')
|
|
|
|
AddEventHandler('mh_jobgarage:notify', function(title, text, type)
|
|
|
|
Notification(text, type)
|
|
|
|
end)
|
|
|
|
|
|
|
|
function GetVehicleDamagePercentage(vehicle)
|
|
|
|
if not vehicle then return 0 end
|
|
|
|
|
|
|
|
-- Hole die verschiedenen Gesundheitswerte
|
|
|
|
local engineHealth = GetVehicleEngineHealth(vehicle)
|
|
|
|
local bodyHealth = GetVehicleBodyHealth(vehicle)
|
|
|
|
local tankHealth = GetVehiclePetrolTankHealth(vehicle)
|
|
|
|
|
|
|
|
-- Normalisiere die Werte (Standard-Maximalwerte: 1000.0)
|
|
|
|
local enginePercent = (engineHealth / 1000.0) * 100
|
|
|
|
local bodyPercent = (bodyHealth / 1000.0) * 100
|
|
|
|
local tankPercent = (tankHealth / 1000.0) * 100
|
|
|
|
|
|
|
|
-- Berechne Durchschnitt als Gesamtzustand
|
|
|
|
local totalHealth = (enginePercent + bodyPercent + tankPercent) / 3
|
|
|
|
|
|
|
|
-- Runde auf ganze Zahlen
|
|
|
|
return math.floor(totalHealth)
|
2025-06-08 14:04:18 +02:00
|
|
|
end
|