213 lines
		
	
	
	
		
			6.6 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			213 lines
		
	
	
	
		
			6.6 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
| 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)
 | 
