local QBCore = exports['qb-core']:GetCoreObject() local spawnedNPCs = {} -- NPC Spawn Function local function SpawnNPC(npcId, npcData) local model = GetHashKey(npcData.model) RequestModel(model) while not HasModelLoaded(model) do Wait(1) end local npc = CreatePed(4, model, npcData.coords.x, npcData.coords.y, npcData.coords.z - 1.0, npcData.coords.w, false, true) SetEntityHeading(npc, npcData.coords.w) FreezeEntityPosition(npc, true) SetEntityInvincible(npc, true) SetBlockingOfNonTemporaryEvents(npc, true) exports['qb-target']:AddTargetEntity(npc, { options = { { type = 'client', event = 'npc-dialog:client:openDialog', icon = npcData.targetIcon, label = npcData.targetLabel, npcId = npcId } }, distance = 2.0 }) spawnedNPCs[npcId] = npc SetModelAsNoLongerNeeded(model) end -- Alle NPCs spawnen CreateThread(function() for npcId, npcData in pairs(Config.NPCs) do SpawnNPC(npcId, npcData) end end) -- Dialog öffnen - Startet mit NPC-Text Pop-up RegisterNetEvent('npc-dialog:client:openDialog', function(data) local npcId = data.npcId local npcData = Config.NPCs[npcId] if not npcData then return end -- NPC-Begrüßung als Pop-up (ohne :next()) CreateThread(function() local result = lib.alertDialog({ header = npcData.dialog.title, content = npcData.dialog.description, centered = true, cancel = false, labels = { confirm = 'Antworten' } }) if result == 'confirm' then ShowDialogOptions(npcData, npcId) end end) end) -- Dialog-Optionen anzeigen (Context-Menü) function ShowDialogOptions(npcData, npcId) local options = {} for i, option in ipairs(npcData.dialog.options) do table.insert(options, { title = option.title, description = option.description, icon = option.icon, onSelect = function() if option.info then -- Direkte Info als Pop-up CreateThread(function() lib.alertDialog({ header = option.title, content = option.info, centered = true, cancel = true, labels = { cancel = 'Zurück zum Gespräch' } }) Wait(500) -- Kurz warten ShowDialogOptions(npcData, npcId) end) elseif option.response then -- NPC-Antwort als Pop-up, dann weiter CreateThread(function() local result = lib.alertDialog({ header = option.response.title, content = option.response.description, centered = true, cancel = false, labels = { confirm = 'Weiter reden' } }) if result == 'confirm' then ShowResponseOptions(option.response, npcData, npcId) end end) end end }) end table.insert(options, { title = "🚪 Verlassen", description = "Dialog beenden", icon = 'times' }) lib.registerContext({ id = 'npc_options_' .. npcId, title = "Was möchtest du sagen?", options = options }) lib.showContext('npc_options_' .. npcId) end -- Response-Optionen anzeigen function ShowResponseOptions(response, npcData, npcId) if not response.options then return end local options = {} for i, option in ipairs(response.options) do table.insert(options, { title = option.title, description = option.description, icon = option.icon, onSelect = function() if option.info then -- Info als Pop-up CreateThread(function() lib.alertDialog({ header = option.title, content = option.info, centered = true, cancel = true, labels = { cancel = 'Gespräch beenden' } }) end) elseif option.response then -- Weitere NPC-Antwort als Pop-up CreateThread(function() local result = lib.alertDialog({ header = option.response.title, content = option.response.description, centered = true, cancel = false, labels = { confirm = 'Weiter' } }) if result == 'confirm' then ShowResponseOptions(option.response, npcData, npcId) end end) end end }) end -- Zurück zum Hauptgespräch table.insert(options, { title = "← Zurück", description = "Zurück zu den Hauptoptionen", icon = 'arrow-left', onSelect = function() ShowDialogOptions(npcData, npcId) end }) -- Verlassen table.insert(options, { title = "🚪 Verlassen", description = "Dialog beenden", icon = 'times' }) local contextId = 'npc_response_' .. npcId .. '_' .. math.random(1000, 9999) lib.registerContext({ id = contextId, title = "Was möchtest du antworten?", options = options }) lib.showContext(contextId) end -- Cleanup AddEventHandler('onResourceStop', function(resourceName) if GetCurrentResourceName() ~= resourceName then return end for _, npc in pairs(spawnedNPCs) do if DoesEntityExist(npc) then DeleteEntity(npc) end end end)