156 lines
8.8 KiB
Lua
156 lines
8.8 KiB
Lua
local wheelBusy = false
|
|
local casinoPeds = {}
|
|
local uiOpen = 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 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 ensureCasinoInterior()
|
|
for _, ipl in ipairs(DevXCasinoConfig.Ipls or {}) do RequestIpl(ipl) end
|
|
local p = DevXCasinoConfig.InteriorEntry
|
|
SetFocusPosAndVel(p.x, p.y, p.z, 0.0, 0.0, 0.0)
|
|
RequestCollisionAtCoord(p.x, p.y, p.z)
|
|
NewLoadSceneStartSphere(p.x, p.y, p.z, 150.0, 0)
|
|
local deadline = GetGameTimer() + 9000
|
|
while not IsNewLoadSceneLoaded() and GetGameTimer() < deadline do Wait(0) end
|
|
NewLoadSceneStop(); ClearFocus()
|
|
end
|
|
local function teleport(position)
|
|
DoScreenFadeOut(250); while not IsScreenFadedOut() do Wait(0) end
|
|
local ped = PlayerPedId(); FreezeEntityPosition(ped, true)
|
|
RequestCollisionAtCoord(position.x, position.y, position.z)
|
|
SetEntityCoordsNoOffset(ped, position.x, position.y, position.z, false, false, false)
|
|
SetEntityHeading(ped, position.w or position.heading or 0.0)
|
|
local deadline = GetGameTimer() + 5000
|
|
while not HasCollisionLoadedAroundEntity(ped) and GetGameTimer() < deadline do RequestCollisionAtCoord(position.x, position.y, position.z); Wait(0) end
|
|
FreezeEntityPosition(ped, false); Wait(150); DoScreenFadeIn(350)
|
|
end
|
|
local function spawnCasinoPeds()
|
|
for _, ped in ipairs(casinoPeds) do if DoesEntityExist(ped) then DeleteEntity(ped) end end
|
|
casinoPeds = {}
|
|
for _, definition in ipairs(DevXCasinoConfig.Npcs or {}) do
|
|
local model = loadModel(definition.model)
|
|
if model then
|
|
local c = definition.coords
|
|
local ped = CreatePed(4, model, c.x, c.y, c.z, c.w, false, false)
|
|
SetEntityInvincible(ped, true); SetBlockingOfNonTemporaryEvents(ped, true); FreezeEntityPosition(ped, true)
|
|
TaskStartScenarioInPlace(ped, definition.scenario or 'WORLD_HUMAN_STAND_MOBILE', 0, true)
|
|
casinoPeds[#casinoPeds + 1] = ped; SetModelAsNoLongerNeeded(model)
|
|
end
|
|
end
|
|
end
|
|
local function getWheelObject()
|
|
for _, modelName in ipairs(DevXCasinoConfig.WheelModels or {}) do
|
|
local object = GetClosestObjectOfType(DevXCasinoConfig.Wheel.x, DevXCasinoConfig.Wheel.y, DevXCasinoConfig.Wheel.z, 3.0, GetHashKey(modelName), false, false, false)
|
|
if object and object ~= 0 and DoesEntityExist(object) then return object end
|
|
end
|
|
return nil
|
|
end
|
|
local function animateWheel(result)
|
|
local wheel = getWheelObject()
|
|
if not wheel then notify('Das originale Casino-Glücksrad ist noch nicht geladen. Betritt das Casino erneut.'); return false end
|
|
local duration, start = 6200, GetGameTimer()
|
|
local base = GetEntityRotation(wheel, 2).y
|
|
local segment = 360.0 / tonumber(result.totalSegments or 8)
|
|
local target = 1440.0 + (360.0 - ((tonumber(result.segment or 0) * segment) + segment * .5))
|
|
FreezeEntityPosition(wheel, true)
|
|
while GetGameTimer() - start < duration do
|
|
local progress = (GetGameTimer() - start) / duration
|
|
local eased = 1.0 - ((1.0 - progress) ^ 4)
|
|
SetEntityRotation(wheel, 0.0, (base + target * eased) % 360.0, 0.0, 2, true)
|
|
help('Das Glücksrad dreht sich …'); Wait(0)
|
|
end
|
|
notify(('Glücksrad: %s gewonnen!'):format(result.reward and result.reward.label or 'Gewinn'))
|
|
return true
|
|
end
|
|
local function spinWheel()
|
|
if #(GetEntityCoords(PlayerPedId()) - DevXCasinoConfig.Wheel) > 3.0 then
|
|
notify('Du musst direkt am Glücksrad stehen.')
|
|
return
|
|
end
|
|
if wheelBusy then return end
|
|
wheelBusy = true
|
|
DevXTriggerCallback('casino:spin', {}, function(result)
|
|
if not result.ok then notify(result.error or 'Das Glücksrad konnte nicht gedreht werden.'); wheelBusy = false; return end
|
|
CreateThread(function() animateWheel(result); wheelBusy = false end)
|
|
end)
|
|
end
|
|
local function openUi(mode)
|
|
uiOpen = true; SetNuiFocus(true, true)
|
|
DevXTriggerCallback('casino:status', {}, function(status)
|
|
SendNUIMessage({ action = 'open', mode = mode, status = status })
|
|
end)
|
|
end
|
|
local function closeUi()
|
|
uiOpen = false; SetNuiFocus(false, false); SendNUIMessage({ action = 'close' })
|
|
end
|
|
|
|
RegisterNetEvent('devx_casino:client:notify', notify)
|
|
RegisterCommand('dailywheel', spinWheel, false)
|
|
RegisterNUICallback('close', function(_, cb) closeUi(); cb({ ok = true }) end)
|
|
RegisterNUICallback('refresh', function(_, cb) DevXTriggerCallback('casino:status', {}, cb) end)
|
|
RegisterNUICallback('exchange', function(data, cb) DevXTriggerCallback('casino:exchange', data, cb) end)
|
|
RegisterNUICallback('slots', function(data, cb) DevXTriggerCallback('casino:slots', data, cb) end)
|
|
RegisterNUICallback('roulette', function(data, cb) DevXTriggerCallback('casino:roulette', data, cb) end)
|
|
RegisterNUICallback('blackjackStart', function(data, cb) DevXTriggerCallback('casino:blackjackStart', data, cb) end)
|
|
RegisterNUICallback('blackjackAction', function(data, cb) DevXTriggerCallback('casino:blackjackAction', data, cb) end)
|
|
|
|
CreateThread(function()
|
|
ensureCasinoInterior(); Wait(1000); spawnCasinoPeds()
|
|
local blip = AddBlipForCoord(DevXCasinoConfig.ExteriorEntry.x, DevXCasinoConfig.ExteriorEntry.y, DevXCasinoConfig.ExteriorEntry.z)
|
|
SetBlipSprite(blip, 679); SetBlipScale(blip, .8); SetBlipColour(blip, 27); SetBlipAsShortRange(blip, true)
|
|
BeginTextCommandSetBlipName('STRING'); AddTextComponentString('Diamond Casino'); EndTextCommandSetBlipName(blip)
|
|
end)
|
|
|
|
local points = {
|
|
{ key = 'cashier', position = DevXCasinoConfig.Cashier, label = '~INPUT_CONTEXT~ Casino-Kasse und Chips', mode = 'cashier' },
|
|
{ key = 'slots', position = DevXCasinoConfig.Slots, label = '~INPUT_CONTEXT~ Spielautomaten', mode = 'slots' },
|
|
{ key = 'roulette', position = DevXCasinoConfig.Roulette, label = '~INPUT_CONTEXT~ Roulette', mode = 'roulette' },
|
|
{ key = 'blackjack', position = DevXCasinoConfig.Blackjack, label = '~INPUT_CONTEXT~ Blackjack', mode = 'blackjack' }
|
|
}
|
|
|
|
CreateThread(function()
|
|
while true do
|
|
local sleep = 700
|
|
if exports.devx_core:IsPlayerLoaded() and not uiOpen then
|
|
local coords = GetEntityCoords(PlayerPedId())
|
|
local exterior = vector3(DevXCasinoConfig.ExteriorEntry.x, DevXCasinoConfig.ExteriorEntry.y, DevXCasinoConfig.ExteriorEntry.z)
|
|
local interiorExit = vector3(DevXCasinoConfig.InteriorExit.x, DevXCasinoConfig.InteriorExit.y, DevXCasinoConfig.InteriorExit.z)
|
|
if #(coords - exterior) < 12.0 then
|
|
sleep = 0; DrawMarker(1, exterior.x, exterior.y, exterior.z - 1.0,0,0,0,0,0,0,1.1,1.1,.3,190,110,255,130,false,false,2,false,nil,nil,false)
|
|
if #(coords - exterior) < 1.5 then help('~INPUT_CONTEXT~ Casino betreten'); if IsControlJustReleased(0,38) then ensureCasinoInterior(); teleport(DevXCasinoConfig.InteriorEntry); spawnCasinoPeds() end end
|
|
elseif #(coords - interiorExit) < 8.0 then
|
|
sleep = 0; DrawMarker(1, interiorExit.x, interiorExit.y, interiorExit.z - 1.0,0,0,0,0,0,0,1.0,1.0,.25,190,110,255,130,false,false,2,false,nil,nil,false)
|
|
if #(coords - interiorExit) < 1.5 then help('~INPUT_CONTEXT~ Casino verlassen'); if IsControlJustReleased(0,38) then teleport(DevXCasinoConfig.ExteriorEntry) end end
|
|
else
|
|
local wheelDistance = #(coords - DevXCasinoConfig.Wheel)
|
|
if wheelDistance < 10.0 then
|
|
sleep = 0; DrawMarker(2, DevXCasinoConfig.Wheel.x,DevXCasinoConfig.Wheel.y,DevXCasinoConfig.Wheel.z+.15,0,0,0,0,180,0,.25,.25,.25,255,190,70,150,false,false,2,false,nil,nil,false)
|
|
if wheelDistance < 1.8 then help(wheelBusy and 'Das Glücksrad dreht sich …' or '~INPUT_CONTEXT~ täglichen Glücksrad-Dreh starten'); if not wheelBusy and IsControlJustReleased(0,38) then spinWheel() end end
|
|
end
|
|
for _, point in ipairs(points) do
|
|
local distance = #(coords - point.position)
|
|
if distance < 8.0 then
|
|
sleep = 0; DrawMarker(2,point.position.x,point.position.y,point.position.z+.15,0,0,0,0,180,0,.22,.22,.22,210,160,70,145,false,false,2,false,nil,nil,false)
|
|
if distance < 1.6 then help(point.label); if IsControlJustReleased(0,38) then openUi(point.mode) end end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
Wait(sleep)
|
|
end
|
|
end)
|
|
|
|
AddEventHandler('onResourceStop', function(resource)
|
|
if resource ~= GetCurrentResourceName() then return end
|
|
closeUi()
|
|
for _, ped in ipairs(casinoPeds) do if DoesEntityExist(ped) then DeleteEntity(ped) end end
|
|
end)
|