new k9 script
@@ -0,0 +1,25 @@
|
||||
|
||||
|
||||
|
||||
|
||||
## Installation
|
||||
1. Drag LSRPC-K9 into resources folder.
|
||||
2. Add resource name to LSRPC-K9 config.
|
||||
3. Start server.
|
||||
4. DO NOT CHANGE THE FOLDER NAME UNLESS YOU KNOW WHAT YOUR DOING
|
||||
|
||||
SUPPORT HERE
|
||||
|
||||
https://discord.gg/tUGFErqPx8 Toxic Custom Scripts
|
||||
|
||||
or
|
||||
|
||||
https://discord.gg/VbDtGCd Burk Studios Custom EUP | 3D MODELING
|
||||
|
||||
## Controls
|
||||
1. OPEN MENU | /K9
|
||||
2. FOLLOW / STOP | F1
|
||||
3. ATTACK | Point + F1
|
||||
4. GET IN & OUT VEHICLE | Delete
|
||||
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
--[[
|
||||
Scripted by: Xander Harrison [X. Cross]
|
||||
--]]
|
||||
resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937'
|
||||
|
||||
ui_page("html/index.html")
|
||||
|
||||
files {
|
||||
"html/index.html",
|
||||
"html/libraries/axios.min.js",
|
||||
"html/libraries/vue.min.js",
|
||||
"html/libraries/vuetify.js",
|
||||
"html/libraries/vuetify.css",
|
||||
"html/style.css",
|
||||
"html/script.js",
|
||||
"html/images/dog_left.png",
|
||||
"html/images/dog_right.png",
|
||||
"html/images/husky.png",
|
||||
"html/images/rottweiler.png",
|
||||
"html/images/shepherd.png",
|
||||
"html/images/retriever.png",
|
||||
"html/images/poodle.png",
|
||||
"html/images/pug.png",
|
||||
"html/images/westy.png",
|
||||
}
|
||||
|
||||
server_script "config.lua"
|
||||
server_script "server.lua"
|
||||
client_script "client.lua"
|
||||
@@ -0,0 +1,554 @@
|
||||
--[[ Variables ]]--
|
||||
-- DO NOT CHANGE --
|
||||
local just_started = true
|
||||
local k9_name = "Default"
|
||||
local spawned_ped = nil
|
||||
local following = false
|
||||
local attacking = false
|
||||
local attacked_player = 0
|
||||
local searching = false
|
||||
local playing_animation = false
|
||||
|
||||
local animations = {
|
||||
['Normal'] = {
|
||||
sit = {
|
||||
dict = "creatures@rottweiler@amb@world_dog_sitting@idle_a",
|
||||
anim = "idle_b"
|
||||
},
|
||||
laydown = {
|
||||
dict = "creatures@rottweiler@amb@sleep_in_kennel@",
|
||||
anim = "sleep_in_kennel"
|
||||
},
|
||||
searchhit = {
|
||||
dict = "creatures@rottweiler@indication@",
|
||||
anim = "indicate_high"
|
||||
}
|
||||
}
|
||||
}
|
||||
--]]
|
||||
|
||||
--[[ Tables ]]--
|
||||
local language = {}
|
||||
--]]
|
||||
|
||||
--[[ NUI Messages ]]--
|
||||
|
||||
-- Open Menu --
|
||||
function EnableMenu()
|
||||
SetNuiFocus(true, true)
|
||||
SendNUIMessage({
|
||||
type = "open_k9_menu"
|
||||
})
|
||||
end
|
||||
|
||||
--]]
|
||||
|
||||
--[[ NUI Callbacks ]]--
|
||||
|
||||
RegisterNUICallback("closemenu", function(data)
|
||||
SetNuiFocus(false, false)
|
||||
end)
|
||||
|
||||
RegisterNUICallback("updatename", function(data)
|
||||
k9_name = data.name
|
||||
end)
|
||||
|
||||
RegisterNUICallback("spawnk9", function(data)
|
||||
TriggerEvent("K9:ToggleK9", data.model)
|
||||
end)
|
||||
|
||||
RegisterNUICallback("vehicletoggle", function(data)
|
||||
if spawned_ped ~= nil then
|
||||
TriggerServerEvent("K9:RequestVehicleToggle")
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterNUICallback("vehiclesearch", function(data)
|
||||
if spawned_ped ~= nil then
|
||||
TriggerServerEvent("K9:RequestItems")
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterNUICallback("sit", function(data)
|
||||
if spawned_ped ~= nil then
|
||||
PlayAnimation(animations['Normal'].sit.dict, animations['Normal'].sit.anim)
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterNUICallback("laydown", function(data)
|
||||
if spawned_ped ~= nil then
|
||||
PlayAnimation(animations['Normal'].laydown.dict, animations['Normal'].laydown.anim)
|
||||
end
|
||||
end)
|
||||
|
||||
--]]
|
||||
|
||||
--[[ Main Event Handlers ]]--
|
||||
|
||||
-- Updates Language Settings
|
||||
RegisterNetEvent("K9:UpdateLanguage")
|
||||
AddEventHandler("K9:UpdateLanguage", function(commands)
|
||||
language = commands
|
||||
Citizen.Trace(tostring(json.encode(language)))
|
||||
end)
|
||||
|
||||
-- Opens K9 Menu
|
||||
RegisterNetEvent("K9:OpenMenu")
|
||||
AddEventHandler("K9:OpenMenu", function(pedRestriction, pedList)
|
||||
if pedRestriction then
|
||||
if CheckPedRestriction(GetLocalPed(), pedList) then
|
||||
EnableMenu()
|
||||
else
|
||||
Notification(tostring("~r~You do not have the right PED to use the K9."))
|
||||
end
|
||||
else
|
||||
EnableMenu()
|
||||
end
|
||||
end)
|
||||
|
||||
-- Error for Identifier Whitelist
|
||||
RegisterNetEvent("K9:IdentifierRestricted")
|
||||
AddEventHandler("K9:IdentifierRestricted", function()
|
||||
Notification(tostring("~r~You do not match any identifiers in the whitelist."))
|
||||
end)
|
||||
|
||||
-- Spawns and Deletes K9
|
||||
RegisterNetEvent("K9:ToggleK9")
|
||||
AddEventHandler("K9:ToggleK9", function(model)
|
||||
if spawned_ped == nil then
|
||||
local ped = GetHashKey(model)
|
||||
RequestModel(ped)
|
||||
while not HasModelLoaded(ped) do
|
||||
Citizen.Wait(1)
|
||||
RequestModel(ped)
|
||||
end
|
||||
local plyCoords = GetOffsetFromEntityInWorldCoords(GetLocalPed(), 0.0, 2.0, 0.0)
|
||||
local dog = CreatePed(28, ped, plyCoords.x, plyCoords.y, plyCoords.z, GetEntityHeading(GetLocalPed()), 0, 1)
|
||||
spawned_ped = dog
|
||||
SetBlockingOfNonTemporaryEvents(spawned_ped, true)
|
||||
SetPedFleeAttributes(spawned_ped, 0, 0)
|
||||
SetPedRelationshipGroupHash(spawned_ped, GetHashKey("k9"))
|
||||
local blip = AddBlipForEntity(spawned_ped)
|
||||
SetBlipAsFriendly(blip, true)
|
||||
SetBlipSprite(blip, 442)
|
||||
BeginTextCommandSetBlipName("STRING")
|
||||
AddTextComponentString(tostring("K9: ".. k9_name))
|
||||
EndTextCommandSetBlipName(blip)
|
||||
NetworkRegisterEntityAsNetworked(spawned_ped)
|
||||
GiveWeaponToPed(spawned_ped, GetHashKey("WEAPON_ANIMAL"), 200, true, true);
|
||||
while not NetworkGetEntityIsNetworked(spawned_ped) do
|
||||
NetworkRegisterEntityAsNetworked(spawned_ped)
|
||||
Citizen.Wait(1)
|
||||
end
|
||||
else
|
||||
local has_control = false
|
||||
RequestNetworkControl(function(cb)
|
||||
has_control = cb
|
||||
end)
|
||||
if has_control then
|
||||
SetEntityAsMissionEntity(spawned_ped, true, true)
|
||||
DeleteEntity(spawned_ped)
|
||||
spawned_ped = nil
|
||||
if attacking then
|
||||
SetPedRelationshipGroupDefaultHash(target_ped, GetHashKey("CIVMALE"))
|
||||
target_ped = nil
|
||||
attacking = false
|
||||
end
|
||||
following = false
|
||||
searching = false
|
||||
playing_animation = false
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
-- Toggles K9 to Follow / Heel
|
||||
RegisterNetEvent("K9:ToggleFollow")
|
||||
AddEventHandler("K9:ToggleFollow", function()
|
||||
if spawned_ped ~= nil then
|
||||
if not following then
|
||||
local has_control = false
|
||||
RequestNetworkControl(function(cb)
|
||||
has_control = cb
|
||||
end)
|
||||
if has_control then
|
||||
TaskFollowToOffsetOfEntity(spawned_ped, GetLocalPed(), 0.5, 0.0, 0.0, 5.0, -1, 0.0, 1)
|
||||
SetPedKeepTask(spawned_ped, true)
|
||||
following = true
|
||||
attacking = false
|
||||
Notification(tostring(k9_name .. " " .. language.follow))
|
||||
end
|
||||
else
|
||||
local has_control = false
|
||||
RequestNetworkControl(function(cb)
|
||||
has_control = cb
|
||||
end)
|
||||
if has_control then
|
||||
SetPedKeepTask(spawned_ped, false)
|
||||
ClearPedTasks(spawned_ped)
|
||||
following = false
|
||||
attacking = false
|
||||
Notification(tostring(k9_name .. " " .. language.stop))
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
-- Toggles K9 In and Out of Vehicles
|
||||
RegisterNetEvent("K9:ToggleVehicle")
|
||||
AddEventHandler("K9:ToggleVehicle", function(isRestricted, vehList)
|
||||
if not searching then
|
||||
if IsPedInAnyVehicle(spawned_ped, false) then
|
||||
SetEntityInvincible(spawned_ped, true)
|
||||
SetPedCanRagdoll(spawned_ped, false)
|
||||
TaskLeaveVehicle(spawned_ped, GetVehiclePedIsIn(spawned_ped, false), 256)
|
||||
Notification(tostring(k9_name .. " " .. language.exit))
|
||||
Wait(2000)
|
||||
SetPedCanRagdoll(spawned_ped, true)
|
||||
SetEntityInvincible(spawned_ped, false)
|
||||
else
|
||||
if not IsPedInAnyVehicle(GetLocalPed(), false) then
|
||||
local plyCoords = GetEntityCoords(GetLocalPed(), false)
|
||||
local vehicle = GetVehicleAheadOfPlayer()
|
||||
local door = GetClosestVehicleDoor(vehicle)
|
||||
if door ~= false then
|
||||
if isRestricted then
|
||||
if CheckVehicleRestriction(vehicle, vehList) then
|
||||
TaskEnterVehicle(spawned_ped, vehicle, -1, door, 2.0, 1, 0)
|
||||
Notification(tostring(k9_name .. " " .. language.enter))
|
||||
end
|
||||
else
|
||||
TaskEnterVehicle(spawned_ped, vehicle, -1, door, 2.0, 1, 0)
|
||||
Notification(tostring(k9_name .. " " .. language.enter))
|
||||
end
|
||||
end
|
||||
else
|
||||
local vehicle = GetVehiclePedIsIn(GetLocalPed(), false)
|
||||
local door = 1
|
||||
if isRestricted then
|
||||
if CheckVehicleRestriction(vehicle, vehList) then
|
||||
TaskEnterVehicle(spawned_ped, vehicle, -1, door, 2.0, 1, 0)
|
||||
Notification(tostring(k9_name .. " " .. language.enter))
|
||||
end
|
||||
else
|
||||
TaskEnterVehicle(spawned_ped, vehicle, -1, door, 2.0, 1, 0)
|
||||
Notification(tostring(k9_name .. " " .. language.enter))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
-- Triggers K9 to Attack
|
||||
RegisterNetEvent("K9:ToggleAttack")
|
||||
AddEventHandler("K9:ToggleAttack", function(target)
|
||||
if not attacking and not searching then
|
||||
if IsPedAPlayer(target) then
|
||||
local has_control = false
|
||||
RequestNetworkControl(function(cb)
|
||||
has_control = cb
|
||||
end)
|
||||
if has_control then
|
||||
local player = GetPlayerFromServerId(GetPlayerId(target))
|
||||
SetCanAttackFriendly(spawned_ped, true, true)
|
||||
TaskPutPedDirectlyIntoMelee(spawned_ped, target, 0.0, -1.0, 0.0, 0)
|
||||
attacked_player = player
|
||||
end
|
||||
else
|
||||
local has_control = false
|
||||
RequestNetworkControl(function(cb)
|
||||
has_control = cb
|
||||
end)
|
||||
if has_control then
|
||||
SetCanAttackFriendly(spawned_ped, true, true)
|
||||
TaskPutPedDirectlyIntoMelee(spawned_ped, target, 0.0, -1.0, 0.0, 0)
|
||||
attacked_player = 0
|
||||
end
|
||||
end
|
||||
attacking = true
|
||||
following = false
|
||||
Notification(tostring(k9_name .. " " .. language.attack))
|
||||
end
|
||||
end)
|
||||
|
||||
-- Triggers K9 to Search Vehicle
|
||||
RegisterNetEvent("K9:SearchVehicle")
|
||||
AddEventHandler("K9:SearchVehicle", function(items, openDoors)
|
||||
local vehicle = GetVehicleAheadOfPlayer()
|
||||
Citizen.Trace(tostring(vehicle))
|
||||
Citizen.Trace(tostring(json.encode(items)))
|
||||
if vehicle ~= 0 and not searching then
|
||||
searching = true
|
||||
local found_table = {}
|
||||
|
||||
Notification(tostring(k9_name .. " has began searching..."))
|
||||
|
||||
if openDoors then
|
||||
SetVehicleDoorOpen(vehicle, 0, 0, 0)
|
||||
SetVehicleDoorOpen(vehicle, 1, 0, 0)
|
||||
SetVehicleDoorOpen(vehicle, 2, 0, 0)
|
||||
SetVehicleDoorOpen(vehicle, 3, 0, 0)
|
||||
SetVehicleDoorOpen(vehicle, 4, 0, 0)
|
||||
SetVehicleDoorOpen(vehicle, 5, 0, 0)
|
||||
SetVehicleDoorOpen(vehicle, 6, 0, 0)
|
||||
SetVehicleDoorOpen(vehicle, 7, 0, 0)
|
||||
end
|
||||
|
||||
-- Back Right
|
||||
local offsetOne = GetOffsetFromEntityInWorldCoords(vehicle, 2.0, -2.0, 0.0)
|
||||
TaskGoToCoordAnyMeans(spawned_ped, offsetOne.x, offsetOne.y, offsetOne.z, 5.0, 0, 0, 1, 10.0)
|
||||
local oneItem = ChooseItem(items)
|
||||
if oneItem ~= false then
|
||||
table.insert(found_table, oneItem)
|
||||
end
|
||||
|
||||
Citizen.Wait(7000)
|
||||
|
||||
-- Front Right
|
||||
local offsetTwo = GetOffsetFromEntityInWorldCoords(vehicle, 2.0, 2.0, 0.0)
|
||||
TaskGoToCoordAnyMeans(spawned_ped, offsetTwo.x, offsetTwo.y, offsetTwo.z, 5.0, 0, 0, 1, 10.0)
|
||||
local twoItem = ChooseItem(items)
|
||||
if twoItem ~= false then
|
||||
table.insert(found_table, twoItem)
|
||||
end
|
||||
|
||||
Citizen.Wait(7000)
|
||||
|
||||
-- Front Left
|
||||
local offsetThree = GetOffsetFromEntityInWorldCoords(vehicle, -2.0, 2.0, 0.0)
|
||||
TaskGoToCoordAnyMeans(spawned_ped, offsetThree.x, offsetThree.y, offsetThree.z, 5.0, 0, 0, 1, 10.0)
|
||||
local threeItem = ChooseItem(items)
|
||||
if threeItem ~= false then
|
||||
table.insert(found_table, threeItem)
|
||||
end
|
||||
|
||||
Citizen.Wait(7000)
|
||||
|
||||
-- Front Right
|
||||
local offsetFour = GetOffsetFromEntityInWorldCoords(vehicle, -2.0, -2.0, 0.0)
|
||||
TaskGoToCoordAnyMeans(spawned_ped, offsetFour.x, offsetFour.y, offsetFour.z, 5.0, 0, 0, 1, 10.0)
|
||||
local fourItem = ChooseItem(items)
|
||||
if fourItem ~= false then
|
||||
table.insert(found_table, fourItem)
|
||||
end
|
||||
|
||||
Citizen.Wait(7000)
|
||||
|
||||
if openDoors then
|
||||
SetVehicleDoorsShut(vehicle, 0)
|
||||
end
|
||||
|
||||
local stringified_table = {}
|
||||
local found_illegal_item = false
|
||||
for a = 1, #found_table do
|
||||
table.insert(stringified_table, found_table[a].item)
|
||||
if found_table[a].illegal then
|
||||
found_illegal_item = true
|
||||
end
|
||||
end
|
||||
|
||||
if found_illegal_item then
|
||||
PlayAnimation(animations['Normal'].searchhit.dict, animations['Normal'].searchhit.anim)
|
||||
Citizen.Wait(3000)
|
||||
PlayAnimation(animations['Normal'].sit.dict, animations['Normal'].sit.anim)
|
||||
end
|
||||
|
||||
Notification(tostring(k9_name .. " has found [ " .. tostring(table.concat(stringified_table, ", ")) .. " ]."))
|
||||
searching = false
|
||||
end
|
||||
end)
|
||||
|
||||
--]]
|
||||
|
||||
--[[ Threads ]]
|
||||
|
||||
-- Controls Menu
|
||||
Citizen.CreateThread(function()
|
||||
while true do
|
||||
Citizen.Wait(0)
|
||||
|
||||
-- Trigger Attack
|
||||
if IsControlJustPressed(1, 288) and IsPlayerFreeAiming(PlayerId()) then
|
||||
local bool, target = GetEntityPlayerIsFreeAimingAt(PlayerId())
|
||||
|
||||
if bool then
|
||||
if IsEntityAPed(target) then
|
||||
TriggerEvent("K9:ToggleAttack", target)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Trigger Follow
|
||||
if IsControlJustPressed(1, 288) and not IsPlayerFreeAiming(PlayerId()) then
|
||||
TriggerEvent("K9:ToggleFollow")
|
||||
end
|
||||
|
||||
if IsControlJustPressed(1, 178) then
|
||||
if spawned_ped ~= nil then
|
||||
TriggerServerEvent("K9:RequestVehicleToggle")
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
-- DO NOT TOUCH (CLEANER)
|
||||
Citizen.CreateThread(function()
|
||||
while true do
|
||||
Citizen.Wait(0)
|
||||
|
||||
-- Setting K9 Settings
|
||||
if just_started then
|
||||
Citizen.Wait(1000)
|
||||
local resource = GetCurrentResourceName()
|
||||
SendNUIMessage({
|
||||
type = "update_resource_name",
|
||||
name = resource
|
||||
})
|
||||
just_started = false
|
||||
TriggerServerEvent("K9:SendLanguage")
|
||||
end
|
||||
|
||||
-- Deletes K9 when you die
|
||||
if spawned_ped ~= nil and IsEntityDead(GetLocalPed()) then
|
||||
TriggerEvent("K9:ToggleK9")
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
--]]
|
||||
|
||||
--[[ EXTRA FUNCTIONS ]]--
|
||||
|
||||
-- Gets Local Ped
|
||||
function GetLocalPed()
|
||||
return GetPlayerPed(PlayerId())
|
||||
end
|
||||
|
||||
-- Gets Control Of Ped
|
||||
function RequestNetworkControl(callback)
|
||||
local netId = NetworkGetNetworkIdFromEntity(spawned_ped)
|
||||
local timer = 0
|
||||
NetworkRequestControlOfNetworkId(netId)
|
||||
while not NetworkHasControlOfNetworkId(netId) do
|
||||
Citizen.Wait(1)
|
||||
NetworkRequestControlOfNetworkId(netId)
|
||||
timer = timer + 1
|
||||
if timer == 5000 then
|
||||
Citizen.Trace("Control failed")
|
||||
callback(false)
|
||||
break
|
||||
end
|
||||
end
|
||||
callback(true)
|
||||
end
|
||||
|
||||
-- Gets Players
|
||||
function GetPlayers()
|
||||
local players = {}
|
||||
for i = 0, 32 do
|
||||
if NetworkIsPlayerActive(i) then
|
||||
table.insert(players, i)
|
||||
end
|
||||
end
|
||||
return players
|
||||
end
|
||||
|
||||
-- Get Searching item
|
||||
function ChooseItem(items)
|
||||
local number = math.random(1, 100)
|
||||
|
||||
if number > 70 and number < 95 then -- 70 | 95
|
||||
local randomItem = math.random(1, #items)
|
||||
return items[randomItem]
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
-- Set K9 Animation (Sit / Laydown)
|
||||
function PlayAnimation(dict, anim)
|
||||
RequestAnimDict(dict)
|
||||
while not HasAnimDictLoaded(dict) do
|
||||
Citizen.Wait(0)
|
||||
end
|
||||
|
||||
TaskPlayAnim(spawned_ped, dict, anim, 8.0, -8.0, -1, 2, 0.0, 0, 0, 0)
|
||||
end
|
||||
|
||||
-- Gets Player ID
|
||||
function GetPlayerId(target_ped)
|
||||
local players = GetPlayers()
|
||||
for a = 1, #players do
|
||||
local ped = GetPlayerPed(players[a])
|
||||
local server_id = GetPlayerServerId(players[a])
|
||||
if target_ped == ped then
|
||||
return server_id
|
||||
end
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
-- Checks Ped Restriction
|
||||
function CheckPedRestriction(ped, PedList)
|
||||
for i = 1, #PedList do
|
||||
if GetHashKey(PedList[i]) == GetEntityModel(ped) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- Checks Vehicle Restriction
|
||||
function CheckVehicleRestriction(vehicle, VehicleList)
|
||||
for i = 1, #VehicleList do
|
||||
if GetHashKey(VehicleList[i]) == GetEntityModel(vehicle) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- Gets Vehicle Ahead Of Player
|
||||
function GetVehicleAheadOfPlayer()
|
||||
local lPed = GetLocalPed()
|
||||
local lPedCoords = GetEntityCoords(lPed, alive)
|
||||
local lPedOffset = GetOffsetFromEntityInWorldCoords(lPed, 0.0, 3.0, 0.0)
|
||||
local rayHandle = StartShapeTestCapsule(lPedCoords.x, lPedCoords.y, lPedCoords.z, lPedOffset.x, lPedOffset.y, lPedOffset.z, 1.2, 10, lPed, 7)
|
||||
local returnValue, hit, endcoords, surface, vehicle = GetShapeTestResult(rayHandle)
|
||||
|
||||
if hit then
|
||||
return vehicle
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
RegisterCommand('k9', function(source, args)
|
||||
TriggerServerEvent("K9:RequestOpenMenu")
|
||||
end, false)
|
||||
|
||||
-- Gets Closest Door To Player
|
||||
function GetClosestVehicleDoor(vehicle)
|
||||
local plyCoords = GetEntityCoords(GetLocalPed(), false)
|
||||
local backleft = GetWorldPositionOfEntityBone(vehicle, GetEntityBoneIndexByName(vehicle, "door_dside_r"))
|
||||
local backright = GetWorldPositionOfEntityBone(vehicle, GetEntityBoneIndexByName(vehicle, "door_pside_r"))
|
||||
local bldistance = GetDistanceBetweenCoords(backleft['x'], backleft['y'], backleft['z'], plyCoords.x, plyCoords.y, plyCoords.z, 1)
|
||||
local brdistance = GetDistanceBetweenCoords(backright['x'], backright['y'], backright['z'], plyCoords.x, plyCoords.y, plyCoords.z, 1)
|
||||
|
||||
local found_door = false
|
||||
|
||||
if (bldistance < brdistance) then
|
||||
found_door = 1
|
||||
elseif(brdistance < bldistance) then
|
||||
found_door = 2
|
||||
end
|
||||
|
||||
return found_door
|
||||
end
|
||||
|
||||
-- Displays Notification
|
||||
function Notification(message)
|
||||
SetNotificationTextEntry("STRING")
|
||||
AddTextComponentString(message)
|
||||
DrawNotification(0, 1)
|
||||
end
|
||||
--]]
|
||||
@@ -0,0 +1,49 @@
|
||||
K9Config = {}
|
||||
K9Config = setmetatable(K9Config, {})
|
||||
|
||||
K9Config.OpenMenuIdentifierRestriction = false
|
||||
K9Config.OpenMenuPedRestriction = false
|
||||
K9Config.LicenseIdentifiers = {
|
||||
"license:c06fbf1faaf995c7b9e207ef77712971a3ed4dc3"
|
||||
}
|
||||
--K9Config.SteamIdentifiers = {
|
||||
--"steam:1100001081f9ab0"
|
||||
--}
|
||||
K9Config.PedsList = {
|
||||
"s_m_y_cop_01",
|
||||
"s_m_y_sheriff_01"
|
||||
}
|
||||
|
||||
-- Restricts the dog to getting into certain vehicles
|
||||
K9Config.VehicleRestriction = false
|
||||
K9Config.VehiclesList = {
|
||||
|
||||
}
|
||||
|
||||
-- Searching Type ( RANDOM [AVAILABLE] | VRP [NOT AVAILABLE] | ESX [NOT AVAILABLE] )
|
||||
K9Config.SearchType = "Random"
|
||||
K9Config.OpenDoorsOnSearch = false
|
||||
|
||||
-- Used for Random Search Type --
|
||||
K9Config.Items = {
|
||||
{item = "Cocaine", illegal = true},
|
||||
{item = "Marijuana", illegal = true},
|
||||
{item = "Blunt Spray", illegal = false},
|
||||
{item = "Crowbar", illegal = false},
|
||||
{item = "Lockpicks", illegal = false},
|
||||
{item = "Baggies", illegal = false},
|
||||
{item = "Used Needle", illegal = false},
|
||||
{item = "Open Container", illegal = false},
|
||||
}
|
||||
|
||||
-- Language --
|
||||
K9Config.LanguageChoice = "English"
|
||||
K9Config.Languages = {
|
||||
["English"] = {
|
||||
follow = "Come",
|
||||
stop = "Heel",
|
||||
attack = "Bite",
|
||||
enter = "In",
|
||||
exit = "Out"
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 172 KiB |
|
After Width: | Height: | Size: 128 KiB |
|
After Width: | Height: | Size: 152 KiB |
|
After Width: | Height: | Size: 143 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 3.7 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
@@ -0,0 +1,100 @@
|
||||
<html style="overflow-x: hidden; overflow-y: hidden;">
|
||||
<header>
|
||||
<title>K9 Menu (LSRPC K9 MENU (LSRPC)</title>
|
||||
<script src="libraries/vue.min.js"></script>
|
||||
<script src="libraries/vuetify.js"></script>
|
||||
<script src="libraries/axios.min.js"></script>
|
||||
<link rel="stylesheet" href='https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons'>
|
||||
<link rel="stylesheet" href="libraries/vuetify.css">
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</header>
|
||||
<body>
|
||||
|
||||
<div id="app">
|
||||
<v-app style="background-color: transparent !important">
|
||||
<div id="k9_menu_base" v-show="show_app">
|
||||
<div id="k9_menu_header">
|
||||
K9 Menu
|
||||
</div>
|
||||
|
||||
<div id="k9_menu_body">
|
||||
|
||||
<div id="k9_main_tab" v-show="current_tab == 'main'">
|
||||
<v-btn block color="primary" dark @click="OpenTab('option')">Options</v-btn>
|
||||
<v-btn block color="primary" dark @click="OpenTab('animation')">Animations</v-btn>
|
||||
<v-btn block color="primary" dark @click="OpenTab('action')">Actions</v-btn>
|
||||
</div>
|
||||
|
||||
<div id="k9_options_tab" v-show="current_tab == 'option'">
|
||||
<!--<v-btn block color="primary" dark @click="ToggleNameChanger()">Change Name</v-btn>-->
|
||||
<v-btn block color="primary" dark @click="ToggleModelChanger()">Change Model</v-btn>
|
||||
<v-btn block color="primary" dark @click="SpawnK9()">Spawn/Delete K9</v-btn>
|
||||
<v-btn block color="primary" dark @click="OpenTab('main')">Go Back</v-btn>
|
||||
</div>
|
||||
|
||||
<div id="k9_animations_tab" v-show="current_tab == 'animation'">
|
||||
<v-btn block color="primary" dark @click="DogSit()">Sit</v-btn>
|
||||
<v-btn block color="primary" dark @click="DogLaydown()">Laydown</v-btn>
|
||||
<v-btn block color="primary" dark @click="OpenTab('main')">Go Back</v-btn>
|
||||
</div>
|
||||
|
||||
<div id="k9_actions_tab" v-show="current_tab == 'action'">
|
||||
<v-btn block color="primary" dark @click="VehicleSearch()">Search</v-btn>
|
||||
<v-btn block color="primary" dark @click="VehicleToggle()">Get in/out Vehicle</v-btn>
|
||||
<v-btn block color="primary" dark @click="OpenTab('main')">Go Back</v-btn>
|
||||
</div>
|
||||
|
||||
<v-btn block color="red" dark @click="DisableApp()">Close Menu</v-btn>
|
||||
|
||||
<div id="footer_credits"><font color="white">LSRPC - Development Team</font></div>
|
||||
</div>
|
||||
|
||||
<div id="k9_name_modal">
|
||||
<v-dialog v-model="k9_name_modal" max-width="500px">
|
||||
<v-card>
|
||||
<v-card-title id="k9_name_header">Choose Your Name</v-card-title>
|
||||
<v-divider></v-divider>
|
||||
<v-card-text>
|
||||
<v-form v-model="k9_name_form_valid">
|
||||
<v-text-field label="Name" :rules="k9_name_rules" :counter="10" v-model="dog_name"></v-text-field>
|
||||
<v-btn color="blue" dark block @click="SetK9Name()">Submit</v-btn>
|
||||
</v-form>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</div>
|
||||
|
||||
<div id="k9_model_header">
|
||||
<v-dialog v-model="k9_model_modal" max-width="70%">
|
||||
<v-card>
|
||||
<v-card-title id="k9_model_header">Choose Your Model</v-card-title>
|
||||
<v-divider></v-divider>
|
||||
<v-card-text>
|
||||
|
||||
<v-container grid-list-md text-xs-center>
|
||||
<v-layout row>
|
||||
<v-flex xs12 id="modelSelector" v-for="model in dog_models_list">
|
||||
<v-card>
|
||||
<v-card-media :src="model.img"></v-card-media>
|
||||
<v-card-media :src="model.img" height="200px" contain></v-card-media>
|
||||
<v-card-title id="model_header_text">{{model.title}}</v-card-title>
|
||||
<v-card-actions>
|
||||
<v-btn color="blue" block dark @click="ChooseK9Model(model.model)">Select</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-flex>
|
||||
</v-layout>
|
||||
</v-container>
|
||||
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</v-app>
|
||||
</div>
|
||||
|
||||
<script src="script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,150 @@
|
||||
// Vue //
|
||||
var app = new Vue({
|
||||
el: "#app",
|
||||
|
||||
data: {
|
||||
resource_name: "",
|
||||
show_app: false,
|
||||
current_tab: "main",
|
||||
|
||||
k9_name_modal: false,
|
||||
dog_name: "",
|
||||
|
||||
k9_model_modal: false,
|
||||
dog_models_list: [
|
||||
{title: "Rottweiler", model: "a_c_rottweiler", img: "images/rottweiler.png"},
|
||||
{title: "Husky", model: "a_c_husky", img: "images/husky.png"},
|
||||
{title: "Shephard", model: "a_c_shepherd", img: "images/shepherd.png"},
|
||||
{title: "Retriver", model: "a_c_retriever", img: "images/retriever.png"},
|
||||
{title: "Poodle", model: "a_c_poodle", img: "images/poodle.png"},
|
||||
{title: "Pug", model: "a_c_pug", img: "images/pug.png"},
|
||||
{title: "Westy", model: "a_c_westy", img: "images/westy.png"}
|
||||
],
|
||||
dog_model: "a_c_rottweiler",
|
||||
|
||||
k9_name_form_valid: false,
|
||||
k9_name_rules: [
|
||||
v => !!v || 'Name is required',
|
||||
v => v.length > 2 || 'Name must be atleast 2 characters',
|
||||
v => v.length < 10 || 'Name must be less than 10 characters',
|
||||
v => /^[A-Za-z]+$/.test(v) || "You can only use letters in the name"
|
||||
],
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
EnableApp() {
|
||||
this.show_app = true;
|
||||
},
|
||||
|
||||
DisableApp() {
|
||||
this.show_app = false;
|
||||
this.current_tab = "main";
|
||||
this.SendCloseMenuPost();
|
||||
},
|
||||
|
||||
// Open Tab
|
||||
OpenTab(tab) {
|
||||
this.current_tab = tab;
|
||||
},
|
||||
|
||||
// Opens Name Changer
|
||||
ToggleNameChanger() {
|
||||
this.k9_name_modal = !this.k9_name_modal;
|
||||
},
|
||||
|
||||
// Opens Model Changer
|
||||
ToggleModelChanger() {
|
||||
this.k9_model_modal = !this.k9_model_modal;
|
||||
},
|
||||
|
||||
// Passes Chosen Model To Data
|
||||
ChooseK9Model(model) {
|
||||
this.k9_model_modal = false;
|
||||
this.dog_model = model;
|
||||
},
|
||||
|
||||
// Updates Resource Name
|
||||
UpdateResource(name) {
|
||||
this.resource_name = name
|
||||
},
|
||||
|
||||
// Sets K9 Name
|
||||
SetK9Name() {
|
||||
if (this.k9_name_form_valid) {
|
||||
axios.post("http://" + this.resource_name + "/updatename", {name: this.dog_name}).then(function(response) {
|
||||
console.log(response);
|
||||
}).catch(function(error) {
|
||||
console.log(error);
|
||||
});
|
||||
} else {
|
||||
console.log("Form Not Valid!");
|
||||
}
|
||||
},
|
||||
|
||||
// Spawns K9 or Deletes K9
|
||||
SpawnK9() {
|
||||
if (!this.dog_model == "") {
|
||||
axios.post("http://" + this.resource_name + "/spawnk9", {model: this.dog_model}).then(function(response) {
|
||||
console.log(response);
|
||||
}).catch(function(error) {
|
||||
console.log(error);
|
||||
});
|
||||
};
|
||||
},
|
||||
|
||||
VehicleToggle() {
|
||||
axios.post("http://" + this.resource_name + "/vehicletoggle", {}).then(function(response) {
|
||||
console.log(response);
|
||||
}).catch(function(error) {
|
||||
console.log(error);
|
||||
});
|
||||
},
|
||||
|
||||
VehicleSearch() {
|
||||
axios.post("http://" + this.resource_name + "/vehiclesearch", {}).then(function(response) {
|
||||
console.log(response);
|
||||
}).catch(function(error) {
|
||||
console.log(error);
|
||||
})
|
||||
},
|
||||
|
||||
DogSit() {
|
||||
axios.post("http://" + this.resource_name + "/sit", {}).then(function(response) {
|
||||
console.log(response);
|
||||
}).catch(function(error) {
|
||||
console.log(error);
|
||||
})
|
||||
},
|
||||
|
||||
DogLaydown() {
|
||||
axios.post("http://" + this.resource_name + "/laydown", {}).then(function(response) {
|
||||
console.log(response);
|
||||
}).catch(function(error) {
|
||||
console.log(error);
|
||||
})
|
||||
},
|
||||
|
||||
// Send POST Close Menu
|
||||
SendCloseMenuPost() {
|
||||
axios.post("http://" + this.resource_name + "/closemenu", {}).then(function(response) {
|
||||
console.log(response);
|
||||
}).catch(function(error) {
|
||||
console.log(error);
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// Event Listener
|
||||
document.onreadystatechange = () => {
|
||||
if (document.readyState === "complete") {
|
||||
window.addEventListener('message', function(event) {
|
||||
if (event.data.type == "open_k9_menu") {
|
||||
app.EnableApp();
|
||||
} else if (event.data.type == "update_resource_name") {
|
||||
app.UpdateResource(event.data.name);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
body {
|
||||
font-family: Verdana, Geneva, Tahoma, sans-serif;
|
||||
-moz-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-ms-user-select:none;
|
||||
user-select:none;
|
||||
-o-user-select:none;
|
||||
}
|
||||
|
||||
#k9_menu_base {
|
||||
position: relative;
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 325px;
|
||||
background-color: rgba(0, 0, 0, 0.527);
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
#modelSelector {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
#dog_icon_left {
|
||||
width: 40px;
|
||||
}
|
||||
|
||||
#dog_icon_right {
|
||||
width: 40px;
|
||||
}
|
||||
|
||||
#k9_menu_header {
|
||||
position: relative;
|
||||
color: white;
|
||||
background: linear-gradient(63deg, rgba(0,70,136,1) 12%, rgba(0,112,255,1) 86%);
|
||||
|
||||
font-size: 25px;
|
||||
font-weight: bold;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
border-top-left-radius: 5px;
|
||||
border-top-right-radius: 5px;
|
||||
}
|
||||
|
||||
#k9_menu_body {
|
||||
position: relative;
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
border-bottom-left-radius: 5px;
|
||||
border-bottom-right-radius: 5px;
|
||||
}
|
||||
|
||||
#k9_name_header {
|
||||
font-size: 25px;
|
||||
}
|
||||
|
||||
#k9_model_header {
|
||||
font-size: 25px;
|
||||
}
|
||||
|
||||
#model_header_text {
|
||||
text-align: center;
|
||||
font-size: 25px;
|
||||
}
|
||||
|
||||
#footer_credits {
|
||||
text-align: center;
|
||||
}
|
||||
.btn:hover {
|
||||
background-color: rgba(253, 253, 253, 0.493) !important;
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
RegisterServerEvent("K9:SendLanguage")
|
||||
AddEventHandler("K9:SendLanguage", function()
|
||||
local s = source
|
||||
TriggerClientEvent("K9:UpdateLanguage", s, K9Config.Languages[K9Config.LanguageChoice])
|
||||
end)
|
||||
|
||||
RegisterServerEvent("K9:RequestOpenMenu")
|
||||
AddEventHandler("K9:RequestOpenMenu", function()
|
||||
local src = source
|
||||
if K9Config.OpenMenuIdentifierRestriction then
|
||||
local foundIdentifier = false
|
||||
for a = 1, #K9Config.LicenseIdentifiers do
|
||||
if not foundIdentifier then
|
||||
if GetPlayerId('license', src) == K9Config.LicenseIdentifiers[a] then
|
||||
foundIdentifier = true
|
||||
end
|
||||
end
|
||||
end
|
||||
for b = 1, #K9Config.SteamIdentifiers do
|
||||
if not foundIdentifier then
|
||||
if GetPlayerId('steam', src) == K9Config.SteamIdentifiers[b] then
|
||||
foundIdentifier = true
|
||||
end
|
||||
end
|
||||
end
|
||||
if foundIdentifier then
|
||||
TriggerClientEvent("K9:OpenMenu", src, K9Config.OpenMenuPedRestriction, K9Config.PedsList)
|
||||
return
|
||||
else
|
||||
TriggerClientEvent("K9:IdentifierRestricted", src)
|
||||
end
|
||||
else
|
||||
TriggerClientEvent("K9:OpenMenu", src, K9Config.OpenMenuPedRestriction, K9Config.PedsList)
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterServerEvent("K9:RequestVehicleToggle")
|
||||
AddEventHandler("K9:RequestVehicleToggle", function()
|
||||
local src = source
|
||||
print("Requested Vehicle Toggle")
|
||||
TriggerClientEvent("K9:ToggleVehicle", src, K9Config.VehicleRestriction, K9Config.VehiclesList)
|
||||
end)
|
||||
|
||||
RegisterServerEvent("K9:RequestItems")
|
||||
AddEventHandler("K9:RequestItems", function()
|
||||
print("Requested Items")
|
||||
local src = source
|
||||
TriggerClientEvent("K9:SearchVehicle", src, K9Config.Items, K9Config.OpenDoorsOnSearch)
|
||||
end)
|
||||
|
||||
--[[ Functions ]]--
|
||||
function GetPlayerId(type, id)
|
||||
local identifiers = GetPlayerIdentifiers(id)
|
||||
for i = 1, #identifiers do
|
||||
if string.find(identifiers[i], type, 1) ~= nil then
|
||||
return identifiers[i]
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
@@ -226,7 +226,7 @@ ensure SimplePriorities
|
||||
ensure cooldown
|
||||
ensure scully_lawenforcement
|
||||
ensure VehicleTrustSystem-master
|
||||
ensure
|
||||
ensure LSRPC-K9
|
||||
ensure
|
||||
ensure
|
||||
|
||||
|
||||