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