first commit

This commit is contained in:
Colin-Joel Scupin
2026-08-05 01:29:39 +02:00
commit 86d4bcdc37
85 changed files with 7706 additions and 0 deletions
@@ -0,0 +1,124 @@
local peds = {}
local companion = nil
local busy = false
local function notify(message) exports.devx_core:Notify(message) end
local function help(text)
BeginTextCommandDisplayHelp('STRING'); AddTextComponentSubstringPlayerName(text); EndTextCommandDisplayHelp(0, false, true, -1)
end
local function subtitle(text, duration)
BeginTextCommandPrint('STRING'); AddTextComponentSubstringPlayerName(text); EndTextCommandPrint(duration or 3000, true)
end
local function loadModel(name)
local hash = GetHashKey(name); RequestModel(hash)
local deadline = GetGameTimer() + 6000
while not HasModelLoaded(hash) and GetGameTimer() < deadline do Wait(0) end
return HasModelLoaded(hash) and hash or nil
end
local function loadAnim(dict)
RequestAnimDict(dict); local deadline = GetGameTimer() + 5000
while not HasAnimDictLoaded(dict) and GetGameTimer() < deadline do Wait(0) end
return HasAnimDictLoaded(dict)
end
local function spawnPed(modelName, pos, scenario)
local model = loadModel(modelName); if not model then return nil end
local ped = CreatePed(4, model, pos.x, pos.y, pos.z, pos.w or 0.0, false, false)
SetEntityInvincible(ped, true); SetBlockingOfNonTemporaryEvents(ped, true); FreezeEntityPosition(ped, true)
if scenario then TaskStartScenarioInPlace(ped, scenario, 0, true) end
SetModelAsNoLongerNeeded(model); return ped
end
local function updateBar(result, message)
SendNUIMessage({ action = 'relationship', name = DevXStripclub.Nikki.name,
value = result.satisfaction or 0, maximum = result.threshold or 100, message = message })
end
local function runTalk(action)
if busy then return end
busy = true
DevXTriggerCallback('stripclub:interact', { action = action }, function(result)
if not result.ok then notify(result.error or 'Interaktion fehlgeschlagen.'); busy = false; return end
local player = PlayerPedId(); local nikki = peds.nikki
if nikki and DoesEntityExist(nikki) then
ClearPedTasksImmediately(nikki); FreezeEntityPosition(player, true)
TaskTurnPedToFaceEntity(player, nikki, 900); TaskTurnPedToFaceEntity(nikki, player, 900); Wait(900)
if action == 'lounge' then
local lounge = DevXStripclub.Nikki.lounge
SetEntityCoordsNoOffset(player, lounge.x + 1.25, lounge.y, lounge.z, false, false, false)
SetEntityHeading(player, lounge.w)
SetEntityCoordsNoOffset(nikki, lounge.x, lounge.y, lounge.z, false, false, false)
SetEntityHeading(nikki, lounge.w + 180.0)
if loadAnim('mini@strip_club@idles@stripper') then
TaskPlayAnim(nikki, 'mini@strip_club@idles@stripper', 'stripper_idle_02', 2.0, -2.0, 9000, 1, 0.0, false, false, false)
end
TaskStartScenarioInPlace(player, 'WORLD_HUMAN_SEAT_WALL', 0, true)
subtitle('~p~Nikki:~s~ Schön, dass du wieder da bist.', 4000); Wait(9000)
else
if loadAnim('gestures@f@standing@casual') then
TaskPlayAnim(nikki, 'gestures@f@standing@casual', 'gesture_hello', 2.0, -2.0, 3200, 49, 0.0, false, false, false)
end
subtitle('~p~Nikki:~s~ Hey, wie läuft dein neues Leben in DevX-City?', 3500); Wait(3600)
end
ClearPedTasksImmediately(player); FreezeEntityPosition(player, false)
FreezeEntityPosition(nikki, true); TaskStartScenarioInPlace(nikki, 'WORLD_HUMAN_STAND_MOBILE', 0, true)
end
updateBar(result, result.newlyUnlocked and 'Kontakt freigeschaltet Nikki wurde im Handy gespeichert.' or 'Zufriedenheit gestiegen.')
busy = false
end)
end
local function spawnClub()
for _, ped in pairs(peds) do if DoesEntityExist(ped) then DeleteEntity(ped) end end
peds = {}
peds.nikki = spawnPed(DevXStripclub.Nikki.model, DevXStripclub.Nikki.position, 'WORLD_HUMAN_STAND_MOBILE')
for index, definition in ipairs(DevXStripclub.Dancers) do
peds['ambient' .. index] = spawnPed(definition.model, definition.position, definition.scenario)
end
end
RegisterNetEvent('devx_stripclub:client:spawnCompanion', function(data)
if companion and DoesEntityExist(companion) then DeleteEntity(companion) end
local pos = data.spawn
companion = spawnPed(data.model, vector4(pos.x, pos.y, pos.z, pos.heading or pos.w or 0.0), 'WORLD_HUMAN_STAND_MOBILE')
if companion then notify(('%s ist in deinem Apartment angekommen.'):format(data.name or 'Dein Gast')) end
end)
AddEventHandler('devx_housing:client:leftApartment', function()
if companion and DoesEntityExist(companion) then DeleteEntity(companion) end
companion = nil
end)
CreateThread(function()
while not exports.devx_core:IsPlayerLoaded() do Wait(500) end
spawnClub()
local blip = AddBlipForCoord(DevXStripclub.Entry.x, DevXStripclub.Entry.y, DevXStripclub.Entry.z)
SetBlipSprite(blip, 121); SetBlipScale(blip, .7); SetBlipColour(blip, 27); SetBlipAsShortRange(blip, true)
BeginTextCommandSetBlipName('STRING'); AddTextComponentString('Vanilla Unicorn'); EndTextCommandSetBlipName(blip)
end)
CreateThread(function()
while true do
local sleep = 700
if exports.devx_core:IsPlayerLoaded() and peds.nikki and DoesEntityExist(peds.nikki) then
local coords = GetEntityCoords(PlayerPedId()); local npcCoords = GetEntityCoords(peds.nikki)
local distance = #(coords - npcCoords)
if distance < 8.0 then
sleep = 0
DrawMarker(2, npcCoords.x, npcCoords.y, npcCoords.z + 1.0, 0,0,0,0,180.0,0, .18,.18,.18, 220,90,180,150,false,false,2,false,nil,nil,false)
if distance < 1.8 then
help(('~INPUT_CONTEXT~ mit Nikki reden | ~INPUT_DETONATE~ VIP-Lounge (%s $)'):format(DevXStripclub.LoungePrice))
if IsControlJustReleased(0, 38) then runTalk('talk')
elseif IsControlJustReleased(0, 47) then runTalk('lounge') end
end
end
end
Wait(sleep)
end
end)
AddEventHandler('onResourceStop', function(resource)
if resource ~= GetCurrentResourceName() then return end
for _, ped in pairs(peds) do if DoesEntityExist(ped) then DeleteEntity(ped) end end
if companion and DoesEntityExist(companion) then DeleteEntity(companion) end
end)