-
Notifications
You must be signed in to change notification settings - Fork 78
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
385 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,385 @@ | ||
|
||
local Crates = {} | ||
local minutes = 0 | ||
local seconds = 0 | ||
local NPCProp = nil | ||
local PedSpawned = nil | ||
local GumballZone = nil | ||
local inZone = false | ||
|
||
local function InteractWithGumball() | ||
lib.hideTextUI() | ||
if Config.SecretGumball.Machine.Payment == 'items' then | ||
exports['envi-interact']:OpenChoiceMenu({ | ||
title = 'Gumball Machine', | ||
speech = '1 Gumball for Both Memberships & '..Config.SecretGumball.Machine.Price..' Casino Chips', | ||
duration = 1500, | ||
menuID = 'gumball-menu', | ||
position = 'right', | ||
options = { | ||
{ | ||
key = 'E', | ||
label = 'Request Gumball', | ||
selected = function() | ||
TriggerServerEvent('doj:server:checkItemsForGumball', source) | ||
end | ||
}, | ||
{ | ||
key = 'X', | ||
label = 'Nevermind', | ||
selected = function(data) | ||
exports['envi-interact']:UpdateSpeech('gumball-menu', 'Later...', 500) | ||
exports['envi-interact']:CloseEverything() | ||
end | ||
} | ||
} | ||
}) | ||
elseif Config.SecretGumball.Machine.Payment == 'cash' then | ||
exports['envi-interact']:OpenChoiceMenu({ | ||
title = 'Gumball Machine', | ||
speech = '1 Gumball for $'..Config.SecretGumball.Machine.Price, | ||
duration = 1000, | ||
menuID = 'gumball-menu', | ||
position = 'right', | ||
options = { | ||
{ | ||
key = 'E', | ||
label = 'Request Gumball', | ||
selected = function() | ||
TriggerServerEvent('doj:server:checkItemsForGumball', source) | ||
end | ||
}, | ||
{ | ||
key = 'X', | ||
label = 'Nevermind', | ||
selected = function(data) | ||
exports['envi-interact']:UpdateSpeech('gumball-menu', 'Later...', 500) | ||
exports['envi-interact']:CloseEverything() | ||
end | ||
} | ||
} | ||
}) | ||
end | ||
end | ||
|
||
local function RGBRainbow(frequency) | ||
local result = {} | ||
local curtime = GetGameTimer() / 1000 | ||
result.r = math.floor( math.sin( curtime * frequency + 0 ) * 127 + 128 ) | ||
result.g = math.floor( math.sin( curtime * frequency + 2 ) * 127 + 128 ) | ||
result.b = math.floor( math.sin( curtime * frequency + 4 ) * 127 + 128 ) | ||
return result | ||
end | ||
|
||
local function countTime() | ||
seconds = seconds - 1 | ||
if seconds == 0 then | ||
seconds = 59 | ||
minutes = minutes - 1 | ||
end | ||
|
||
if minutes == -1 then | ||
minutes = 0 | ||
seconds = 0 | ||
end | ||
lib.showTextUI('Time To Loot: '..minutes..':'..seconds) | ||
end | ||
|
||
local function hasPlayerRunOutOfTime() | ||
return (minutes == 0 and seconds <= 1) | ||
end | ||
|
||
local function spawnGumballLoot() | ||
CreateThread(function() | ||
for k, v in pairs(Config.SecretGumball.Loot.Spawn) do | ||
local prop = 'xs_prop_arena_crate_01a' | ||
local rainbow = RGBRainbow(1) | ||
lib.RequestModel(prop) | ||
local crates = CreateObject(prop, v.Location.x, v.Location.y, v.Location.z - 1, false, true, false) | ||
SetEntityHeading(crates, v.Heading) | ||
PlaceObjectOnGroundProperly(crates) | ||
FreezeEntityPosition(crates, true) | ||
SetModelAsNoLongerNeeded(prop) | ||
if Config.SecretGumball.Loot.Highlight then | ||
SetEntityDrawOutline(crates, true) | ||
SetEntityDrawOutlineColor(rainbow.r, rainbow.g, rainbow.b, 0) | ||
end | ||
Crates[#Crates+1] = crates | ||
exports['qb-target']:AddTargetModel(prop, { | ||
options = { | ||
{ | ||
event = 'doj:client:OpenGumballCrate', | ||
icon = 'fa-solid fa-magnifying-glass', | ||
label = 'Search Crate', | ||
}, | ||
}, | ||
distance = 1.8 | ||
}) | ||
end | ||
end) | ||
end | ||
|
||
local function despawnGumballLoot() | ||
for _, v in pairs(Crates) do SetEntityAsMissionEntity(v, false, true) DeleteObject(v) end | ||
exports.ox_target:removeLocalEntity(Crates, 'crates') | ||
end | ||
|
||
RegisterNetEvent('doj:client:GumballLocations', function() | ||
GumballSpawn = math.random(1, #Config.SecretGumball.MachineSpawns) | ||
local rainbow = RGBRainbow(1) | ||
local prop = GetHashKey('prop_gumball_03') | ||
local prop2 = GetHashKey('bkr_prop_bkr_cash_scatter_03') | ||
GumballZone = lib.zones.box({ | ||
coords = vec3(Config.SecretGumball.MachineSpawns[GumballSpawn].x, Config.SecretGumball.MachineSpawns[GumballSpawn].y, Config.SecretGumball.MachineSpawns[GumballSpawn].z), | ||
size = vec3(2, 2, 4), | ||
onEnter = function() | ||
lib.showTextUI('E - Interact') | ||
end, | ||
onExit = function() | ||
lib.hideTextUI() | ||
end, | ||
inside = function() | ||
if IsControlJustReleased(0, 38) then | ||
InteractWithGumball() | ||
end | ||
end, | ||
debug = false, | ||
}) | ||
lib.RequestModel(prop) | ||
lib.RequestModel(prop2) | ||
NPCProp = CreateObject(prop, Config.SecretGumball.MachineSpawns[GumballSpawn].x, Config.SecretGumball.MachineSpawns[GumballSpawn].y, Config.SecretGumball.MachineSpawns[GumballSpawn].z - 1, true, false, true) | ||
NPCProp2 = CreateObject(prop2, Config.SecretGumball.MachineSpawns[GumballSpawn].x, Config.SecretGumball.MachineSpawns[GumballSpawn].y, Config.SecretGumball.MachineSpawns[GumballSpawn].z - 0.99, true, false, true) | ||
if Config.SecretGumball.Machine.Highlight then | ||
SetEntityDrawOutline(NPCProp, true) | ||
SetEntityDrawOutlineColor(rainbow.r, rainbow.g, rainbow.b, 0) | ||
end | ||
FreezeEntityPosition(NPCProp, true) | ||
SetEntityInvincible(NPCProp, true) | ||
PlaceObjectOnGroundProperly(NPCProp) | ||
PlaceObjectOnGroundProperly(NPCProp2) | ||
SetModelAsNoLongerNeeded(prop) | ||
SetModelAsNoLongerNeeded(prop2) | ||
return NPCProp, NPCProp2, GumballZone | ||
end) | ||
|
||
RegisterNetEvent('doj:client:acceptTradeForGumball', function() | ||
exports['envi-interact']:CloseEverything() | ||
local playerPed = cache.ped | ||
local animDict = 'mp_common' | ||
local animName = 'givetake1_a' | ||
lib.requestAnimDict(animDict) | ||
local Item = CreateObject(GetHashKey('sf_prop_sf_cash_pile_01'), 0, 0, 0, true, true, true) | ||
TaskPlayAnim(playerPed, animDict, animName, 1.0, -1.0, 1000, 49, 0, false, false, false) | ||
AttachEntityToEntity(Item, playerPed, GetPedBoneIndex(playerPed, 0x188E), 0.08, -0.06, -0.01, 96.0, 20.0, 180.0, true, true, false, true, 1, true) | ||
Wait(1000) | ||
DeleteObject(Item) | ||
TriggerServerEvent('doj:server:giveGumball') | ||
Wait(900) | ||
TriggerEvent('doj:client:RefreshZones') | ||
end) | ||
|
||
RegisterNetEvent('doj:client:OpenGumballCrate', function() | ||
local playerPed = PlayerPedId() | ||
local coords = GetEntityCoords(playerPed) | ||
local nearbyObject, nearbyID | ||
for i=1, #Crates, 1 do | ||
if #(coords - GetEntityCoords(Crates[i])) < 2.0 then | ||
nearbyObject, nearbyID = Crates[i], i | ||
end | ||
end | ||
if nearbyObject and IsPedOnFoot(playerPed) then | ||
local success = lib.skillCheck(Config.SecretGumball.Loot.Skill.Difficulty, Config.SecretGumball.Loot.Skill.Inputs) | ||
if success then | ||
local OpenCrateTimer = math.random(2500, 5000) | ||
if lib.progressCircle({ duration = OpenCrateTimer, label = 'Searching Crate', position = 'bottom', useWhileDead = false, canCancel = true, disable = { car = false, move = true, }, anim = { dict = 'mini@repair', clip = 'fixing_a_ped' } }) then | ||
ClearPedTasks(PlayerPedId()) | ||
SetEntityAsMissionEntity(nearbyObject, false, true) | ||
DeleteObject(nearbyObject) | ||
Crates[nearbyID] = nil | ||
TriggerServerEvent('doj:server:AddRandomGumballLoot') | ||
else | ||
ClearPedTasks(PlayerPedId()) | ||
lib.notify({title = 'Action cancelled', type = 'error'}) | ||
end | ||
else | ||
lib.notify({title = '!+*@_=? - Gumball', type = 'warning'}) | ||
end | ||
end | ||
end) | ||
|
||
|
||
RegisterNetEvent('doj:client:RefreshZones', function() | ||
if GumballZone then | ||
GumballZone:remove() | ||
end | ||
if NPCProp then | ||
SetEntityDrawOutline(NPCProp, false) | ||
DeleteEntity(NPCProp) | ||
DeleteEntity(NPCProp2) | ||
NPCProp = nil | ||
end | ||
SetTimeout(Config.SecretGumball.Machine.RespawnAfterUse * 1000, function() | ||
TriggerEvent('doj:client:GumballLocations') | ||
end) | ||
end) | ||
----------------------------------------------------------------- | ||
|
||
Citizen.CreateThread(function() | ||
while true do | ||
Citizen.Wait(1000) | ||
if inZone then | ||
if hasPlayerRunOutOfTime() then | ||
SpawnBackToCasino() | ||
end | ||
countTime() | ||
if inZone == false then | ||
lib.hideTextUI() | ||
end | ||
end | ||
end | ||
end) | ||
|
||
local function StartFadingOut() | ||
local playerPed = cache.ped | ||
lib.requestAnimDict('timetable@gardener@smoking_joint') | ||
lib.playAnim(playerPed, 'timetable@gardener@smoking_joint', 'idle_cough', 1.0, -1.0, 2000, 49, 0, false, 0.0, false) | ||
Wait(2000) | ||
DoScreenFadeOut(500) | ||
Wait(500) | ||
DoScreenFadeIn(500) | ||
if not IsPedRagdoll(playerPed) and IsPedOnFoot(playerPed) then | ||
ShakeGameplayCam('SMALL_EXPLOSION_SHAKE', 0.08) | ||
SetPedToRagdollWithFall(playerPed, 1000, 2000, 1, GetEntityForwardVector(playerPed), 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) | ||
Wait(1000) | ||
DoScreenFadeOut(500) | ||
Wait(1000) | ||
SecretLootLocation() | ||
Wait(1000) | ||
DoScreenFadeIn(500) | ||
if not PedSpawned then | ||
PedSpawned = true | ||
StartClonePed() | ||
end | ||
end | ||
end | ||
|
||
function SecretLootLocation() | ||
local playerPed = cache.ped | ||
minutes = Config.SecretGumball.Loot.Timer.Minutes | ||
seconds = Config.SecretGumball.Loot.Timer.Seconds | ||
inZone = true | ||
spawnGumballLoot() | ||
SetEntityCoords(playerPed, 1204.192, -2268.225, -47.177, false, false, false, false) | ||
lib.requestAnimDict('missheist_agency3astumble_getup') | ||
lib.playAnim(playerPed, 'missheist_agency3astumble_getup', 'stumble_getup', 1.0, -1.0, 2000, 0, 0, false, 0.0, false) | ||
lib.requestAnimSet('MOVE_M@DRUNK@VERYDRUNK') | ||
SetPedMovementClipset(playerPed, 'MOVE_M@DRUNK@VERYDRUNK', 1) | ||
SetPedMotionBlur(playerPed, true) | ||
SetPedIsDrunk(playerPed, true) | ||
ShakeGameplayCam('DRUNK_SHAKE', 2.0) | ||
AnimpostfxPlay('DrugsMichaelAliensFight', 0, true) | ||
end | ||
|
||
function SpawnBackToCasino() | ||
inZone = false | ||
PedSpawned = false | ||
local playerPed = cache.ped | ||
lib.showTextUI('Time expired') | ||
despawnGumballLoot() | ||
SetPedMoveRateOverride(playerPed, 1.0) | ||
SetRunSprintMultiplierForPlayer(playerPed, 1.0) | ||
SetPedIsDrunk(playerPed, false) | ||
SetPedMotionBlur(playerPed, false) | ||
ResetPedMovementClipset(playerPed, 0.0) | ||
ShakeGameplayCam('DRUNK_SHAKE', 0.0) | ||
if not IsPedRagdoll(playerPed) and IsPedOnFoot(playerPed) then | ||
ShakeGameplayCam('SMALL_EXPLOSION_SHAKE', 0.03) | ||
SetPedToRagdollWithFall(playerPed, 1000, 2000, 1, GetEntityForwardVector(playerPed), 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) | ||
Wait(1000) | ||
DoScreenFadeOut(500) | ||
Wait(1000) | ||
if EvilPed then | ||
DeletePed(EvilPed) | ||
end | ||
SetEntityCoords(playerPed, 924.268, 59.659, 111.335, false, false, false, false) | ||
lib.requestAnimDict('missheist_agency3astumble_getup') | ||
lib.playAnim(playerPed, 'missheist_agency3astumble_getup', 'stumble_getup', 1.0, -1.0, 2000, 0, 0, false, 0.0, false) | ||
Wait(750) | ||
DoScreenFadeIn(500) | ||
AnimpostfxStop('DrugsMichaelAliensFight') | ||
end | ||
end | ||
|
||
local function TrackPlayer() | ||
while true do | ||
local dist = #(GetEntityCoords(cache.ped) - GetEntityCoords(EvilPed)) | ||
if dist > 5.0 then | ||
TaskGoToEntity(EvilPed, cache.ped, -1, 4.0, 100.0, 1073741824, 0) | ||
Wait(1000) | ||
else | ||
if not IsTaskMoveNetworkActive(EvilPed) then | ||
lib.requestAnimDict("anim@mp_point") | ||
TaskMoveNetworkByName(EvilPed, "task_mp_pointing", 0.5, true, "anim@mp_point", 24) | ||
SetPedCurrentWeaponVisible(EvilPed, true, false, false, false) | ||
SetPedConfigFlag(EvilPed, 36, false) | ||
end | ||
if not LastPedTurn or (GetGameTimer() - LastPedTurn) > 1000 then | ||
LastPedTurn = GetGameTimer() | ||
TaskTurnPedToFaceEntity(EvilPed, cache.ped, -1) | ||
end | ||
SetTaskMoveNetworkSignalFloat (EvilPed, "Pitch", 0.4) | ||
SetTaskMoveNetworkSignalFloat (EvilPed, "Heading", 0.5) | ||
SetTaskMoveNetworkSignalBool (EvilPed, "isBlocked", false) | ||
SetTaskMoveNetworkSignalBool (EvilPed, "isFirstPerson", false) | ||
if IsPedRagdoll(EvilPed) then | ||
while IsPedRagdoll(EvilPed) do Wait(0); end | ||
ClearPedTasksImmediately(EvilPed) | ||
Wait(10) | ||
end | ||
Wait(0) | ||
end | ||
end | ||
end | ||
|
||
function StartClonePed() | ||
EvilPed = ClonePed(cache.ped, true, false, false) | ||
SetEntityAlpha(EvilPed, 100, false) | ||
SetEntityCoordsNoOffset(EvilPed, 1211.474, -2275.694, -49.0, false, false, true) | ||
SetPedComponentVariation(EvilPed, 1, 155, 0, 0) | ||
SetEntityInvincible(EvilPed,true) | ||
SetBlockingOfNonTemporaryEvents(EvilPed,true) | ||
TrackPlayer() | ||
return EvilPed | ||
end | ||
|
||
RegisterNetEvent('doj:client:consumeGumball', function() | ||
local gumballItem = CreateObject(GetHashKey('prop_paper_ball'), 0, 0, 0, true, true, true) | ||
local playerPed = cache.ped | ||
lib.requestAnimDict('mp_suicide') | ||
lib.playAnim(playerPed, 'mp_suicide', 'pill', 1.0, -1.0, 2000, 49, 0, false, 0.0, false) | ||
Wait(1300) | ||
AttachEntityToEntity(gumballItem, playerPed, GetPedBoneIndex(playerPed, 0x188E), 0.08, -0.06, -0.01, 96.0, 20.0, 180.0, true, true, false, true, 1, true) | ||
Wait(700) | ||
DeleteObject(gumballItem) | ||
StartFadingOut() | ||
end) | ||
|
||
RegisterNetEvent('doj:client:KillGumballZones', function() | ||
if GumballZone then | ||
GumballZone:remove() | ||
end | ||
if NPCProp then | ||
SetEntityDrawOutline(NPCProp, false) | ||
DeleteEntity(NPCProp) | ||
DeleteEntity(NPCProp2) | ||
NPCProp = nil | ||
end | ||
if EvilPed then | ||
DeletePed(EvilPed) | ||
end | ||
end) | ||
|
||
AddEventHandler('onResourceStop', function(resource) | ||
if cache.resource ~= resource then return end | ||
TriggerEvent('doj:client:KillGumballZones') | ||
end) |