Wert-ShopRobbery

You can access the setup information you need about this product

INSTALLATION

1 - Put all the files in your resources file

2 - Open server.cfg

3 - Give the command to start the script

4 - Don't forget to edit your config file for your own server

5 - Add items your item list

-- Items
['yellow_security_card'] 	= {['name'] = 'yellow_security_card', 	['label'] = 'Yellow Security Card', 		['weight'] = 0, 		['type'] = 'item', 		['image'] = 'yellow_security_card.png', 	['unique'] = false, 	['useable'] = true, 	['shouldClose'] = true,	   ['combinable'] = nil,   ['description'] = ''},

['lockpick'] 	= {['name'] = 'lockpick', 	['label'] = 'Lockpick', 		['weight'] = 300, 		['type'] = 'item', 		['image'] = 'lockpick.png', 			['unique'] = false, 	['useable'] = true, 	['shouldClose'] = true,	   ['combinable'] = {accept = {'screwdriverset'}, reward = 'advancedlockpick', anim = {['dict'] = 'anim@amb@business@weed@weed_inspecting_high_dry@', ['lib'] = 'weed_inspecting_high_base_inspector', ['text'] = 'Crafting lockpick', ['timeOut'] = 7500,}},   ['description'] = ''},

['drill'] 	 = {['name'] = 'drill', 	['label'] = 'Drill', 			['weight'] = 5000, 		['type'] = 'item', 		['image'] = 'drill.png', 				['unique'] = false, 	['useable'] = false, 	['shouldClose'] = false,   ['combinable'] = nil,   ['description'] = ''},

6 - Prepare the depends scripts and upload them to the resources folder.

7 - Everything is ok, have fun

ITEM IMAGES

Script information :

  • Find the right items and rob the shop but watch out for the cops

OPEN FILES

Config = {}

Config.Lang = "en"

Config.UseTarget = true
Config.DebugPoly = false
Config.OxLib = false

Config.UseDrill = true

Config.NoTargetRegisterZoneSize = 1.0
Config.NoTargetSafeZoneSize = 1.0

Config.NoTargetInteraction = 'textui' -- | 'textui', 'drawtext'
Config.NoTargetInteractionKey = 38

-- Minigames
Config.RegisterMiniGameType = 'ps-ui-circle' -- | 'qb-lock', 'ps-ui-circle', 'ox-skillbar', 'none'  | If you want configre codes in editable_client
Config.SafeMinigameType = 'ps-ui-thermite' -- | 'ps-ui-thermite', 'ps-ui-maze', 'memorygame', 'none' | If you want configre codes ind editable_client

-- Police notification
Config.PoliceNotificationSystem = 'wert-policesystem' -- | 'wert-policesystem', 'ps-dispatch', 'custom' | If you set custom you need edit in editable_client your special system

Config.Safetime = 15 -- Reset time (minute)
Config.Registertime = 15 -- Reset time (minute)

-- Needed cop counts
Config.Safecop = 0
Config.Registercop = 0

-- Reward settings
Config.SafeRewards = {
	-- type : "money", "item" | account : "cash", "bank" (Account only for bank type) | amount : {min = int, max = int}, int (min, max only for money type) | chance : % (If you want create rewards for your chance)
	{type = "money", account = "cash", amount = {min = 5000, max = 6000}},
	{type = "item", name = 'yellow_security_card', amount = 1, chance = 10},
}

Config.RegisterRewards = {
	-- type : "money", "item" | account : "cash", "bank" (Account only for bank type) | amount : {min = int, max = int}, int (min, max only for money type) | chance : % (If you want create rewards for your chance)
	{type = "money", account = "cash", amount = {min = 200, max = 500}},
	{type = "item", name = 'yellow_security_card', amount = 1, chance = 30},
}

-- Need items
Config.SafeItems = {
	{item = "drill", amount = 1},
	{item = "yellow_security_card", amount = 1},
	-- If you want add more need item here for registers
}

Config.RegisterItems = {
	{item = "lockpick", amount = 1},
	-- If you want add more need item here for registers
}

-- Icons
Config.RegisterInteractionIcon = "fas fa-money-bill"
Config.SafeInteractionIcon = "fas fa-money-bill"

-- Drill settings
Config.DrillModel = `hei_prop_heist_drill`
Config.DrillAnimationSettings = {
	dict = "anim@heists@fleeca_bank@drilling",
	anim = "drill_straight_idle",
	flag = 1
}

Config.ProgressbarTimes = {
	checkbar = 2500,
	lockpick = 20000,
	prepare = 5000,
	moneycollect = 10000,
}

Config.CheckAnimSettings = {
	dict = "mini@repair",
	anim = "fixing_a_player",
	flag = 49
}

Config.RegisterAnimSettings = {
	dict = "mini@repair",
	anim = "fixing_a_player",
	flag = 49
}

Config.PrepareAnimSettings = {
	dict = "mini@repair",
	anim = "fixing_a_player",
	flag = 49
}

Config.NoDrillAnimSettings = {
	dict = "mini@repair",
	anim = "fixing_a_player",
	flag = 49
}

Config.ShopInfos = {
    { 
		safe = vector4(378.25, 333.66, 103.57, 343.24),
		register = vector4(373.39, 328.59, 103.57, 255.74),
	},
	{ 
		safe = vector4(-43.72, -1748.15, 29.42, 51.54),
		register = vector4(-47.05, -1757.83, 29.44, 48.9),
	},
	{ 
		safe = vector4(-710.32, -904.24, 19.22, 90.02),
		register = vector4(-706.5, -913.6, 19.28, 87.85),
	},
	{ 
		safe = vector4(28.14, -1338.86, 29.51, 3.25),
		register = vector4(25.21, -1344.89, 29.93, 280.46),
	},
	{ 
		safe = vector4(-3048.09, 585.46, 7.93, 105.89),
		register = vector4(-3041.19, 584.06, 7.91, 25.92),
	},
	{ 
		safe = vector4(-1478.43, -375.87, 38.78, 222.92),
		register = vector4(-1486.54, -378.38, 40.16, 132.74),
	},
	{ 
		safe = vector4(1169.97, 2717.87, 36.78, 269.86),
		register = vector4(1166.0, 2710.37, 38.18, 179.28),
	},
	{
		safe = vector4(1708.15, 4920.97, 42.06, 325.53),
		register = vector4(1698.31, 4923.63, 42.44, 327.49),
	},
	{ 
		safe = vector4(-3250.5, 1004.36, 12.89, 81.82),
		register = vector4(-3244.58, 1000.46, 12.84, 356.88),
	},
	{ 
		safe = vector4(-2959.68, 386.45, 13.79, 173.89),
		register = vector4(-2966.86, 390.86, 15.04, 90.14),
	},
	{
		safe = vector4(1126.67, -979.45, 45.04, 3.92),
		register = vector4(1134.64, -982.35, 46.43, 276.23),
	},
	{ 
		safe = vector4(1959.03, 3749.16, 32.35, 29.79),
		register = vector4(1959.2, 3742.19, 32.33, 298.81),
	},
	{ 
		safe = nil,
		register = nil,
	},
	{
		safe = vector4(1159.16, -314.13, 69.21, 99.2),
		register = vector4(1164.34, -322.9, 69.22, 104.21),
	},
	{
		safe = vector4(1734.9, 6421.14, 35.04, 331.37),
		register = vector4(1729.12, 6417.19, 34.98, 239.9),
	},
	{
		safe = vector4(546.58, 2662.29, 42.16, 189.76),
		register = vector4(548.9, 2668.82, 42.32, 96.88),
	},
	{
		safe = vector4(2672.43, 3286.73, 55.14, 59.35),
		register = vector4(2676.2, 3281.2, 55.33, 327.36),
	},
	{
		safe = vector4(-1829.57, 798.28, 138.09, 121.42),
		register = vector4(-1820.59, 793.67, 138.4, 131.1),
	},
	{
		safe = vector4(-1221.38, -916.4, 10.95, 120.61),
		register = vector4(-1222.27, -907.98, 12.34, 31.46),
	},
}

Config.Locales = {
	en = {
		item_error = "You don't have enough items",
		cop_error = "Not enough cop",
		drill_okey = "Drill success",
		drill_fail = "Rob failed",
		case_forced = "This case forced",
		lockpick_okey = "Lockpick success",
		progress_checkcase = "Case checking...",
		progress_lockpick = "Case lockpicking...",
		progress_prepare = "Prepare items...",
		rob_register = "Rob Register",
		rob_safe = "Rob Safe",
		minigame_fail = "The attempt to infiltrate the system failed!",
		drill_push = "Push",
		drill_back = "Pull Back",
		drill_speed_up = "Speed Up",
		drill_speed_down = "Speed Down",
		nodrill_progressbarlabel = "Money Collecting...",
		notargetregister_interaction = "[E] Rob Register",
		notargetasafe_interaction = "[E] Rob Safe"
	},
	tr = {
		item_error = "Gerkeli eşyalara sahip değilsin!",
		cop_error = "Yeterli polis yok!",
		drill_okey = "Delme işlemi başarılı",
		drill_fail = "Soygun başarısız!",
		case_forced = "Bu kasa zorlanmış!",
		lockpick_okey = "Maymuncuk başarılı",
		progress_checkcase = "Kasa kontrol ediliyor...",
		progress_lockpick = "Maymuncuklanıyor...",
		progress_prepare = "Malzemeler hazırlanıyor...",
		rob_register = "Yazar Kasayı Soy",
		rob_safe = "Kasayı Soy",
		minigame_fail = "Sisteme sızma işlemi başarısız oldu!",
		drill_push = "İttir",
		drill_back = "Geri Çek",
		drill_speed_up = "Hızı Arttır",
		drill_speed_down = "Yavaşlat",
		nodrill_progressbarlabel = "Paralar Toplanıyor...",
			notargetregister_interaction = "[E] Yazar Kasayı Soy",
		notargetasafe_interaction = "[E] Kasayı Soy"
	},
}
local QBCore = exports['qb-core']:GetCoreObject()
local LANG = Config.Locales[Config.Lang]
local listen = false
local CurrentShop = nil
aktif = false -- IMPORTANT don't touch please!

-- No target seçeneği

-- # Functions
function CustomNotifVariation(text, style, time)
	QBCore.Functions.Notify(text, style, time)
end

function ProgressbarSetting(data, cb)
	if not Config.OxLib then
		QBCore.Functions.Progressbar("wert_hazır", data.label, data.time, false, true, {
			disableMovement = data.disablemove,
			disableCarMovement = data.disablecar,
			disableMouse = data.disablemouse,
			disableCombat = data.disablecombat,
		}, {
			animDict = data.animdict,
			anim = data.animname,
			flags = data.animflag or 49,
		}, {}, {}, function() -- Done    
			cb('finish')
		end, function() -- Cancel
			cb('cancel')
		end)
	else
		if lib.progressCircle({
			duration = data.time,
			position = 'bottom',
			useWhileDead = false,
			canCancel = true,
			disable = {
				car = data.disablecar,
				move = data.disablemove,
				mouse, data.disablemouse,
				combat = data.disablecombat
			},
			anim = {
				dict = data.animdict,
				clip = data.animname,
				flag = data.animflag or 49
			},
		}) then cb('finish') else cb('cancel') end
	end
end

function RegisterMiniGame(cb)
	if Config.RegisterMiniGameType == 'qb-lock' then
		local finished = exports['qb-lock']:StartLockPickCircle(3, 10, success)
		cb(finished) -- Must return check valid
	elseif Config.RegisterMiniGameType == 'ps-ui-circle' then
		exports['ps-ui']:Circle(function(success)
			cb(success)
		end, 2, 20)
	elseif Config.RegisterMiniGameType == 'ox-skillbar' then
		local success = lib.skillCheck({'easy', 'easy', {areaSize = 60, speedMultiplier = 2}, 'hard'}, {'w', 'a', 's', 'd'})
		cb(success)
	elseif Config.RegisterMiniGameType == 'none' then
		cb(true)
	end
end

function SafeMiniGame(cb)
	if Config.SafeMinigameType == 'ps-ui-thermite' then
		exports['ps-ui']:Thermite(function(success)
			cb(success)
		end, 10, 5, 3)
	elseif Config.SafeMinigameType == 'ps-ui-maze' then
		exports['ps-ui']:Maze(function(success)
			cb(success)
		end, 20)
	elseif Config.SafeMinigameType == 'memorygame' then
		exports["memorygame"]:thermiteminigame(6, 1, 3, 10, function() -- success
			cb(true)
		end, function() -- failure
			cb(false)
		end)
	elseif Config.SafeMinigameType == 'none' then
		cb(true)
	end
end

function HideInteraction()
	if Config.NoTargetInteraction == 'textui' then
		if Config.OxLib then
			lib.hideTextUI()
		else
			exports['qb-core']:HideText()
		end
	end
end

function ShowInteraction(displayText)
	if Config.NoTargetInteraction == 'textui' then
		if Config.OxLib then
			lib.showTextUI(displayText)
		else
			exports['qb-core']:DrawText(displayText, 'left')
		end
	end
end

local function DrawText3D(x, y, z, text)
    -- Use local function instead
    SetTextScale(0.35, 0.35)
    SetTextFont(4)
    SetTextProportional(1)
    SetTextColour(255, 255, 255, 215)
    SetTextEntry('STRING')
    SetTextCentre(true)
    AddTextComponentString(text)
    SetDrawOrigin(x, y, z, 0)
    DrawText(0.0, 0.0)
    local factor = (string.len(text)) / 370
    DrawRect(0.0, 0.0 + 0.0125, 0.017 + factor, 0.03, 0, 0, 0, 75)
    ClearDrawOrigin()
end

local function StartNoTargetThread(coord, event, notargetlabel)
	CreateThread(function()
		local event_name = event
		local label = notargetlabel
		if Config.NoTargetInteraction == 'textui' then
			while listen do
				if aktif then
					Wait(1000)
				else
					if IsControlJustPressed(0, Config.NoTargetInteractionKey) then
						if CurrentShop then
							TriggerEvent(event_name, CurrentShop)
						end
					end
				end
				Wait(1)
			end
		elseif Config.NoTargetInteraction == 'drawtext' then
			while listen do
				if aktif then
					Wait(1000)
				else
					DrawText3D(coord.x, coord.y, coord.z, label)
					if IsControlJustPressed(0, Config.NoTargetInteractionKey) then
						if CurrentShop then TriggerEvent(event_name, CurrentShop) end
					end
				end
				Wait(1)
			end
		end
	end)
end

-- # Events
RegisterNetEvent("wert-shoprobbery:client:police-alert", function(shopno)
    -- Add your police alert event
	if Config.PoliceNotificationSystem == 'wert-policesystem' then
		exports['wert-policesystem']:alert({
			style = "police", -- police or ambulance (job)
			code = "10-80", -- code
			name = "Shop #" .. shopno .. " Being Robbed", -- title
		})
	elseif Config.PoliceNotificationSystem == 'ps-dispatch' then
		exports['ps-dispatch']:StoreRobbery(shopno)
	elseif Config.PoliceNotificationSystem == 'custom' then
		-- Your special system
	end
end)

RegisterNetEvent("wert-shoprobbery:client:arka-kasa", function(key)
	SafeMiniGame(function(success)
		if success then
			TriggerEvent("wert-shoprobbery:client:police-alert", key)
			local animset = Config.PrepareAnimSettings
			ProgressbarSetting({label = LANG.progress_prepare, time = Config.ProgressbarTimes.prepare, disablemove = true, disablecar = true, disablemouse = false, disablecombat = true, animdict = animset.dict, animname = animset.anim, animflag = animset.flag}, function(result)
				if result == 'finish' then
					TriggerEvent('wert-shoprobbery:client:arka-kasa-steptwo', key)
				else
					aktif = false
				end
			end)
		else
			aktif = false
			CustomNotifVariation(LANG.minigame_fail, "error")
		end
	end)
end)

CreateThread(function()
	Wait(1000)
	local Zones = {}
	for k, v in pairs(Config.ShopInfos) do
		if v.register and v.safe then
			local register_name = k .. "WertShopRegister"
			local safe_name = k .. "WertShopSafe"
			local register_coord = vector3(v.register.x, v.register.y, v.register.z)
			local safe_coord = vector3(v.safe.x, v.safe.y, v.safe.z)
			if Config.UseTarget then
				exports["qb-target"]:AddBoxZone(register_name, register_coord, 0.8, 0.8, {
					name = register_name,
					heading = v.register.w,
					debugPoly = Config.DebugPoly,
					minZ = v.register.z - 0.5,
					maxZ = v.register.z + 0.5
				}, {
					options = {
						{
							icon = Config.RegisterInteractionIcon,
							label = LANG.rob_register,
							action = function(entity) TriggerEvent("wert-shoprobbery:client:rob-register", k) end,
							canInteract = function(entity)
								if not aktif then return true else return false end
							end,
						},
					},
					distance = 1.5
				})
				exports["qb-target"]:AddBoxZone(safe_name, safe_coord, 0.8, 0.8, {
					name = safe_name,
					heading = v.safe.w,
					debugPoly = Config.DebugPoly,
					minZ = v.safe.z - 0.5,
					maxZ = v.safe.z + 0.5
				}, {
					options = {
						{
							icon = Config.SafeInteractionIcon,
							label = LANG.rob_safe,
							action = function(entity) TriggerEvent("wert-shoprobbery:client:rob-safe", k) end,
							canInteract = function(entity)
								if not aktif then return true else return false end
							end,
						},
					},
					distance = 1.5
				})
			else
				-- No target
				Zones[#Zones+1] = CircleZone:Create(register_coord, Config.NoTargetRegisterZoneSize, {
					name = register_name,
					debugPoly = false,
					data = {
						casetype = 'register',
						key = k
					}
				})
				Zones[#Zones+1] = CircleZone:Create(safe_coord, Config.NoTargetSafeZoneSize, {
					name = safe_name,
					debugPoly = false,
					data = {
						casetype = 'safe',
						key = k
					}
				})
			end
		end
	end
	if not Config.UseTarget and #Zones > 0 then
		local comboZone = ComboZone:Create(Zones, { name = 'wertshoprobberycombo', debugPoly = Config.DebugPoly })
		comboZone:onPlayerInOut(function(isPointInside, _, zone)
			if isPointInside then
				if not listen then
					CurrentShop = zone.data.key
					listen = true
					local shop_coord = Config.ShopInfos[CurrentShop].register
					local displayText = LANG.notargetregister_interaction
					local eventname = "wert-shoprobbery:client:rob-register"
					if zone.data.casetype == 'safe' then
						shop_coord = Config.ShopInfos[CurrentShop].safe
						displayText = LANG.notargetasafe_interaction
						eventname = "wert-shoprobbery:client:rob-safe"
					end
					StartNoTargetThread(shop_coord, eventname, displayText)
					ShowInteraction(displayText)
				end
			else
				listen = false
				CurrentShop = nil
				HideInteraction()
			end
		end)
	end
end)
local WebHook = "YOUR_WEBHOOK"

function DiscordLog(title, message)
    local embedData = {
        {
            ['title'] = title,
            ['color'] = '65280',
            ['footer'] = {['text'] = os.date('%c')},
            ['description'] = message,
            ['author'] = {
                ['name'] = 'Shop Robberies',
            },
        }
    }
    PerformHttpRequest(WebHook, function() end, 'POST', json.encode({ username = 'Shop Robberies', embeds = embedData}), { ['Content-Type'] = 'application/json' })
end

Installation complete

Last updated