part2 update ers and other scripts
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
Config.Callouts["roxwood_aggresive_boars"] = {
|
||||
|
||||
Enabled = true,
|
||||
CalloutName = "Aggressive Boars",
|
||||
CalloutDescriptions = {
|
||||
"Respond to a report of aggressive boars attacking a farmer; ensure public safety and coordinate with animal control.",
|
||||
"Alert: wild boars spotted attacking a farmer; deploy units to contain the animals and protect civilians.",
|
||||
"Units needed: emergency call for aggressive boars; focus on securing the area and preventing any harm.",
|
||||
"Notice: boars reported attacking a farmer; act promptly to control the situation and provide assistance.",
|
||||
"Alert: report of aggressive boars; intervention needed to secure the scene and ensure safety.",
|
||||
"Incident reported: boars sighted attacking a farmer; take action to deliver urgent response and support.",
|
||||
"Respond to a situation involving aggressive boars; prioritize public safety and coordinate with wildlife experts.",
|
||||
"Situation alert: boars on the loose; provide immediate assistance and ensure the area is secure.",
|
||||
"Alert: report of boars attacking a farmer; respond swiftly to address the emergency and offer necessary support.",
|
||||
"Response needed: aggressive boars; ensure public safety, provide aid, and secure the area.",
|
||||
},
|
||||
CalloutUnitsRequired = {
|
||||
description = "Police",
|
||||
policeRequired = true,
|
||||
ambulanceRequired = false,
|
||||
fireRequired = false,
|
||||
towRequired = false,
|
||||
},
|
||||
CalloutLocations = {
|
||||
[1] = vector3(-1823.0022, 6998.0410, 34.9726),
|
||||
[2] = vector3(-2387.3379, 7242.6768, 29.0290),
|
||||
[3] = vector3(-2461.5059, 7537.0752, 29.0388),
|
||||
[4] = vector3(-2497.2771, 7169.6704, 29.0752),
|
||||
[5] = vector3(-2538.9504, 7436.2910, 28.8805),
|
||||
},
|
||||
PedChanceToFleeFromPlayer = 0, -- Boars won't flee from the player.
|
||||
PedChanceToAttackPlayer = 100, -- Low chance to attack the player.
|
||||
PedChanceToSurrender = 0, -- Boars won't surrender.
|
||||
PedChanceToObtainWeapons = 0, -- Boars don't use weapons.
|
||||
PedActionMinimumTimeoutInMs = 10000, -- Milliseconds for the minimum timeout time to start the secondary action listed above.
|
||||
PedActionMaximumTimeoutInMs = 15000, -- Milliseconds for the maximum timeout time to start the secondary action. Must be a higher number than the minimum!
|
||||
PedActionOnNoActionFound = "flee",-- When no action of the above options is found. It'll perform this action after the set timeout. Options: "none", "attack", "flee", "surrender"
|
||||
PedWeaponData = { -- The ped will be given one randomly selected weapon (in hand) from these weapons if PedChanceToObtainWeapons passed.
|
||||
"weapon_musket",
|
||||
},
|
||||
|
||||
client = function(plyPed, pedList, vehicleList, playersList, objectList, propList, fireList, smokeList, calloutDataClient)
|
||||
local farmer
|
||||
local boarPedList = {}
|
||||
|
||||
for index, pedNetId in pairs(pedList) do
|
||||
local ped = NetToPed(pedNetId)
|
||||
if DoesEntityExist(ped) then
|
||||
ERS_RequestNetControlForEntity(ped)
|
||||
if index == 1 then
|
||||
farmer = ped
|
||||
ERS_PedEquipWeapon(ped, "weapon_musket", 100)
|
||||
Wait(100)
|
||||
TaskCombatPed(ped, NetToPed(pedList[2]), 0, 16)
|
||||
else
|
||||
TaskCombatPed(ped, farmer, 0, 16)
|
||||
table.insert(boarPedList, pedNetId)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ERS_CreateTemporaryBlipForEntities(boarPedList, 30000)
|
||||
|
||||
ERS_PerformTimedActionOnPed(calloutDataClient, boarPedList)
|
||||
end,
|
||||
|
||||
server = function(request, src, calloutData, pedList, vehicleList, objectList, propList, playersList, fireList, smokeList)
|
||||
local diameter = 15
|
||||
|
||||
-- Build farmer
|
||||
local farmerModel = "a_m_m_farmer_01"
|
||||
local farmerCoords = vector3(calloutData.Coordinates.x, calloutData.Coordinates.y, calloutData.Coordinates.z+1.0)
|
||||
local farmerHeading = math.random(360)
|
||||
local farmerNetId = ERS_CreatePed(farmerModel, farmerCoords, farmerHeading)
|
||||
local farmer = NetworkGetEntityFromNetworkId(farmerNetId)
|
||||
table.insert(pedList, farmerNetId)
|
||||
|
||||
-- Build boars
|
||||
local boarModel = "a_c_boar"
|
||||
local randomAmountOfBoars = math.random(3, 5) -- Randomize number of boars
|
||||
for i = 1, randomAmountOfBoars do
|
||||
local coords = ERS_GetRandomCoordinateWithinRangeOfCoordinate(calloutData.Coordinates, diameter)
|
||||
local boarCoords = vector3(coords.x, coords.y, coords.z+1.0)
|
||||
local boarHeading = math.random(360)
|
||||
local boarNetId = ERS_CreatePed(boarModel, boarCoords, boarHeading)
|
||||
local boar = NetworkGetEntityFromNetworkId(boarNetId)
|
||||
table.insert(pedList, boarNetId)
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
Config.Callouts["roxwood_animal_on_road"] = {
|
||||
|
||||
Enabled = true,
|
||||
CalloutName = "Animal on the Road in Roxwood",
|
||||
CalloutDescriptions = {
|
||||
"An unexpected type of animal has appeared on the road, causing a disruption in traffic flow.",
|
||||
"Emergency services have been called to intervene in a situation where an animal is impeding traffic on the road.",
|
||||
"Reports indicate a disturbance on the roadway, with an unidentified creature causing a commotion.",
|
||||
"A peculiar incident has unfolded on the road, requiring immediate attention to ensure public safety.",
|
||||
"Emergency services have been dispatched to address an obstruction on the road, involving an animal.",
|
||||
"A surprising encounter has occurred on the road, with an unknown creature causing a hindrance to traffic.",
|
||||
"Witnesses report an unusual occurrence on the road, with an unidentified animal creating a hazard for motorists.",
|
||||
"An incident has occurred on the road, with an animal posing a potential threat to drivers.",
|
||||
"Emergency services have been alerted to a situation where an unidentified creature is obstructing the roadway.",
|
||||
"Reports suggest an unexpected type of animal on the road, involving an animal that requires immediate assistance.",
|
||||
},
|
||||
CalloutUnitsRequired = {
|
||||
description = "Police, animal rescue.",
|
||||
policeRequired = true,
|
||||
ambulanceRequired = false,
|
||||
fireRequired = false,
|
||||
towRequired = false,
|
||||
},
|
||||
CalloutLocations = {
|
||||
[1] = vector3(-2917.2009, 6687.8828, 24.9933),
|
||||
[2] = vector3(-2385.1338, 6949.2163, 35.3990),
|
||||
[3] = vector3(-1927.2576, 7528.9648, 75.0004),
|
||||
[4] = vector3(-673.5764, 7669.7896, 28.7780),
|
||||
[5] = vector3(-670.4109, 6713.2271, 21.3245),
|
||||
[6] = vector3(-397.3026, 7055.0483, 20.4035),
|
||||
[7] = vector3(-2483.4431, 7576.3521, 28.6643),
|
||||
[8] = vector3(-2060.8218, 8574.8389, 36.1939),
|
||||
[9] = vector3(-2706.7444, 6928.1416, 28.8962),
|
||||
[10] = vector3(-2615.2388, 6572.5176, 24.5263),
|
||||
},
|
||||
PedChanceToFleeFromPlayer = 0, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedChanceToAttackPlayer = 0, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedChanceToSurrender = 0, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedChanceToObtainWeapons = 0, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedActionMinimumTimeoutInMs = 0, -- Milliseconds for the minimum timeout time to start the secondary action listed above.
|
||||
PedActionMaximumTimeoutInMs = 1000, -- Milliseconds for the maximum timeout time to start the secondary action. Must be a higher number than the minimum!
|
||||
PedActionOnNoActionFound = "none", -- When no action of the above options is found. It'll perform this action after the set timeout. Options: "none", "attack", "flee", "surrender"
|
||||
PedWeaponData = { -- The ped will be given one randomly selected weapon (in hand) from these weapons if PedChanceToObtainWeapons passed.
|
||||
"weapon_unarmed",
|
||||
},
|
||||
|
||||
client = function(plyPed, pedList, vehicleList, playersList, objectList, propList, fireList, smokeList, calloutDataClient)
|
||||
|
||||
for index, pedNetId in pairs(pedList) do
|
||||
local ped = NetToPed(pedNetId)
|
||||
if DoesEntityExist(ped) then
|
||||
ERS_RequestNetControlForEntity(ped)
|
||||
ClearPedTasks(ped)
|
||||
|
||||
if Config.Debug then
|
||||
print("Found animal entity: "..ped)
|
||||
end
|
||||
|
||||
TaskWanderStandard(ped, 10.0, 10)
|
||||
end
|
||||
end
|
||||
|
||||
ERS_CreateTemporaryBlipForEntities(pedList, 15000)
|
||||
--ERS_PerformTimedActionOnPed(calloutDataClient, pedList)
|
||||
|
||||
end,
|
||||
server = function(request, src, calloutData, pedList, vehicleList, objectList, propList, playersList, fireList, smokeList)
|
||||
|
||||
local diameter = 20
|
||||
|
||||
local randomAmountOfAnimals = math.random(1, 8)
|
||||
local randomAnimalPedModel = ERS_GetRandomModel(Config.calloutAnimals)
|
||||
for i = 1, randomAmountOfAnimals do
|
||||
-- Build animals of the same type.
|
||||
local coords = ERS_GetRandomCoordinateWithinRangeOfCoordinate(calloutData.Coordinates, diameter)
|
||||
local animalPedCoords = vector3(coords.x, coords.y, coords.z)
|
||||
local animalPedHeading = math.random(360)
|
||||
local animalPedNetId = ERS_CreatePed(randomAnimalPedModel, animalPedCoords, animalPedHeading)
|
||||
local animalPed = NetworkGetEntityFromNetworkId(animalPedNetId)
|
||||
table.insert(pedList, animalPedNetId)
|
||||
end
|
||||
return true
|
||||
end
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
Config.Callouts["roxwood_arson"] = {
|
||||
|
||||
Enabled = true,
|
||||
CalloutName = "Reports of Arson in Roxwood",
|
||||
CalloutDescriptions = {
|
||||
"Suspected arson incidents have been reported, requiring immediate response from law enforcement and fire services.",
|
||||
"Urgent assistance needed to address suspected arson, ensuring community safety and property protection.",
|
||||
"Multiple suspected arson cases reported, demanding swift action to prevent further damage and risk.",
|
||||
"Identified arson cases prompt the need for additional resources to investigate and control the situation.",
|
||||
"Emergency services alerted to suspected arson, necessitating coordinated efforts to apprehend those responsible.",
|
||||
"Authorities seek assistance in addressing suspected arson, emphasizing public vigilance and cooperation.",
|
||||
"Additional units required to support law enforcement and fire teams in responding to suspected arson incidents.",
|
||||
"Emergency backup needed to help manage and contain suspected arson, ensuring public safety.",
|
||||
"Responders call for assistance in dealing with suspected arson, highlighting the urgency of the situation.",
|
||||
"Immediate intervention crucial to manage and address suspected arson, safeguarding lives and property.",
|
||||
},
|
||||
CalloutUnitsRequired = {
|
||||
description = "Police, Fire",
|
||||
policeRequired = true,
|
||||
ambulanceRequired = false,
|
||||
fireRequired = true,
|
||||
towRequired = false,
|
||||
},
|
||||
CalloutLocations = {
|
||||
[1] = vector3(-3082.4443, 7910.6416, 54.4692),
|
||||
[2] = vector3(-3083.5991, 7936.8086, 54.1143),
|
||||
[3] = vector3(-3044.8267, 7937.8999, 58.7173),
|
||||
[4] = vector3(-3013.9849, 7916.1396, 58.6186),
|
||||
[5] = vector3(-2541.5210, 7480.6040, 28.7263),
|
||||
[6] = vector3(-2304.5576, 7760.9302, 44.3912),
|
||||
[7] = vector3(-2281.4097, 8151.0815, 34.1373),
|
||||
[8] = vector3(-1140.2708, 8119.0449, 23.1818),
|
||||
[9] = vector3(-416.6748, 7650.4414, 6.3326),
|
||||
[10] = vector3(-341.3544, 7396.8135, 6.4100),
|
||||
},
|
||||
PedChanceToFleeFromPlayer = 50, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedChanceToAttackPlayer = 50, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedChanceToSurrender = 10, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedChanceToObtainWeapons = 60, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedActionMinimumTimeoutInMs = 5000, -- Milliseconds for the minimum timeout time to start the secondary action listed above.
|
||||
PedActionMaximumTimeoutInMs = 10000, -- Milliseconds for the maximum timeout time to start the secondary action. Must be a higher number than the minimum!
|
||||
PedActionOnNoActionFound = "flee", -- When no action of the above options is found. It'll perform this action after the set timeout. Options: "none", "attack", "flee", "surrender"
|
||||
PedWeaponData = { -- The ped will be given one randomly selected weapon (in hand) from these weapons if PedChanceToObtainWeapons passed.
|
||||
"weapon_knife",
|
||||
"weapon_hammer",
|
||||
"weapon_crowbar",
|
||||
"weapon_bottle",
|
||||
},
|
||||
|
||||
client = function(plyPed, pedList, vehicleList, playersList, objectList, propList, fireList, smokeList, calloutDataClient)
|
||||
|
||||
for index, pedNetId in pairs(pedList) do
|
||||
local ped = NetToPed(pedNetId)
|
||||
if DoesEntityExist(ped) then
|
||||
ERS_RequestNetControlForEntity(ped)
|
||||
TaskSetBlockingOfNonTemporaryEvents(ped, true)
|
||||
Wait(100)
|
||||
ERS_SetPedToFleeFromPlayer(ped)
|
||||
end
|
||||
end
|
||||
|
||||
ERS_CreateTemporaryBlipForEntities(pedList, 15000)
|
||||
|
||||
ERS_PerformTimedActionOnPed(calloutDataClient, pedList)
|
||||
|
||||
end,
|
||||
server = function(request, src, calloutData, pedList, vehicleList, objectList, propList, playersList, fireList, smokeList)
|
||||
|
||||
local diameter = 2
|
||||
|
||||
if UsingSmartFires then
|
||||
-- Full version
|
||||
local fireSize = Config.RandomSmallFireOrSmokeSize[math.random(#Config.RandomSmallFireOrSmokeSize)]
|
||||
local fireType = Config.NormalFireTypes[math.random(#Config.NormalFireTypes)]
|
||||
local fireId = exports['SmartFires']:CreateFire(vector3(calloutData.Coordinates.x, calloutData.Coordinates.y, calloutData.Coordinates.z-0.5), fireSize, fireType)
|
||||
DebugPrint("Created fire with ID: "..fireId)
|
||||
table.insert(fireList, fireId)
|
||||
else
|
||||
-- Lite version
|
||||
local fireSize = Config.RandomSmallFireOrSmokeSize[math.random(#Config.RandomSmallFireOrSmokeSize)]
|
||||
local fireType = "normal"
|
||||
local fireId = exports['SmartFiresLite']:CreateFire(vector3(calloutData.Coordinates.x, calloutData.Coordinates.y, calloutData.Coordinates.z-0.5), fireSize, fireType)
|
||||
DebugPrint("Created fire with SmartFiresLite with ID: "..fireId)
|
||||
table.insert(fireList, fireId)
|
||||
end
|
||||
|
||||
-- Build suspect peds
|
||||
local randomAmountOfSuspects = math.random(3)
|
||||
for i = 1, randomAmountOfSuspects do
|
||||
local coords = ERS_GetRandomCoordinateWithinRangeOfCoordinate(calloutData.Coordinates, diameter)
|
||||
|
||||
local suspectPedModel = ERS_GetRandomModel(Config.randomPeds)
|
||||
local suspectPedCoords = vector3(coords.x, coords.y, coords.z)
|
||||
local suspectPedHeading = math.random(360)
|
||||
local suspectPedNetId = ERS_CreatePed(suspectPedModel, suspectPedCoords, suspectPedHeading)
|
||||
local suspectPed = NetworkGetEntityFromNetworkId(suspectPedNetId)
|
||||
table.insert(pedList, suspectPedNetId)
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
Config.Callouts["roxwood_bouncer_in_trouble"] = {
|
||||
|
||||
Enabled = true,
|
||||
CalloutName = "Bouncer in Trouble",
|
||||
CalloutDescriptions = {
|
||||
"A bouncer is struggling to control a rowdy crowd at a nightclub, with tensions escalating quickly.",
|
||||
"Security personnel have called for backup as a confrontation with patrons turns violent.",
|
||||
"Reports indicate a bouncer is overwhelmed by a group of unruly individuals at a local bar.",
|
||||
"A nightclub bouncer is facing resistance from aggressive patrons, requiring immediate assistance.",
|
||||
"A disturbance at a bar has led to a bouncer being outnumbered, with the situation deteriorating.",
|
||||
"A bouncer is attempting to defuse a volatile situation at a club, with the potential for violence.",
|
||||
"Witnesses report a bouncer being attacked by patrons, with the need for urgent intervention.",
|
||||
"Security at a venue is under threat as a bouncer deals with a hostile crowd, needing backup.",
|
||||
"A bouncer is in distress as a confrontation with patrons escalates, requiring swift response.",
|
||||
"Emergency services are needed to assist a bouncer in trouble, with the potential for further conflict.",
|
||||
},
|
||||
CalloutUnitsRequired = {
|
||||
description = "Police.",
|
||||
policeRequired = true,
|
||||
ambulanceRequired = false,
|
||||
fireRequired = false,
|
||||
towRequired = false,
|
||||
},
|
||||
CalloutLocations = {
|
||||
[1] = vector3(-605.2895, 7008.7100, 24.2095),
|
||||
[2] = vector3(-626.9119, 6922.6372, 24.3170),
|
||||
[3] = vector3(-330.2892, 7173.5366, 6.4107),
|
||||
},
|
||||
PedChanceToFleeFromPlayer = 20, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedChanceToAttackPlayer = 50, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedChanceToSurrender = 20, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedChanceToObtainWeapons = 25, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedActionMinimumTimeoutInMs = 10000,-- Milliseconds for the minimum timeout time to start the secondary action listed above.
|
||||
PedActionMaximumTimeoutInMs = 15000,-- Milliseconds for the maximum timeout time to start the secondary action. Must be a higher number than the minimum!
|
||||
PedActionOnNoActionFound = "flee", -- When no action of the above options is found. It'll perform this action after the set timeout. Options: "none", "attack", "flee", "surrender"
|
||||
PedWeaponData = { -- The ped will be given one randomly selected weapon (in hand) from these weapons if PedChanceToObtainWeapons passed.
|
||||
"weapon_knife",
|
||||
"weapon_bat",
|
||||
"weapon_hammer",
|
||||
"weapon_wrench",
|
||||
"weapon_pistol",
|
||||
},
|
||||
|
||||
client = function(plyPed, pedList, vehicleList, playersList, objectList, propList, fireList, smokeList, calloutDataClient)
|
||||
local teamBouncers = {}
|
||||
local teamOthers = {}
|
||||
|
||||
for index, pedNetId in pairs(pedList) do
|
||||
local ped = NetToPed(pedNetId)
|
||||
if DoesEntityExist(ped) then
|
||||
ERS_RequestNetControlForEntity(ped)
|
||||
local model = GetEntityModel(ped)
|
||||
|
||||
-- Check if the ped is a bouncer
|
||||
if model == GetHashKey("s_m_m_bouncer_01") or model == GetHashKey("s_m_m_highsec_01") or model == GetHashKey("s_m_m_highsec_02") then
|
||||
table.insert(teamBouncers, ped)
|
||||
else
|
||||
table.insert(teamOthers, ped)
|
||||
end
|
||||
|
||||
TaskSetBlockingOfNonTemporaryEvents(ped, true)
|
||||
Wait(100)
|
||||
ERS_SpawnConfiguredWeaponForPed(ped, calloutDataClient)
|
||||
end
|
||||
end
|
||||
|
||||
-- Function to make peds flee
|
||||
local function makePedsFlee(peds)
|
||||
for _, ped in pairs(peds) do
|
||||
if DoesEntityExist(ped) and not IsPedDeadOrDying(ped, true) then
|
||||
TaskSmartFleePed(ped, plyPed, 100.0, -1, false, false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Monitor and update ped behavior
|
||||
Citizen.CreateThread(function()
|
||||
while true do
|
||||
Citizen.Wait(1000) -- Check every second
|
||||
|
||||
-- Remove dead peds from teams
|
||||
for i = #teamBouncers, 1, -1 do
|
||||
if IsPedDeadOrDying(teamBouncers[i], true) then
|
||||
table.remove(teamBouncers, i)
|
||||
end
|
||||
end
|
||||
|
||||
for i = #teamOthers, 1, -1 do
|
||||
if IsPedDeadOrDying(teamOthers[i], true) then
|
||||
table.remove(teamOthers, i)
|
||||
end
|
||||
end
|
||||
|
||||
-- If the others team or the bouncers team is too small, make them flee (and let bouncers stay)
|
||||
if #teamOthers < 3 or #teamBouncers < 2 then
|
||||
makePedsFlee(teamOthers)
|
||||
break
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
-- Initial combat setup
|
||||
if #teamBouncers > 0 and #teamOthers > 0 then
|
||||
for _, bouncer in pairs(teamBouncers) do
|
||||
local randomTarget = teamOthers[math.random(#teamOthers)]
|
||||
TaskCombatPed(bouncer, randomTarget, 0, 16)
|
||||
if Config.Debug then
|
||||
print("Bouncer "..bouncer.." is attacking ped "..randomTarget)
|
||||
end
|
||||
end
|
||||
|
||||
for _, other in pairs(teamOthers) do
|
||||
local randomTarget = teamBouncers[math.random(#teamBouncers)]
|
||||
TaskCombatPed(other, randomTarget, 0, 16)
|
||||
if Config.Debug then
|
||||
print("Other ped "..other.." is attacking bouncer "..randomTarget)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ERS_CreateTemporaryBlipForEntities(pedList, 15000)
|
||||
ERS_PerformTimedActionOnPed(calloutDataClient, pedList)
|
||||
end,
|
||||
server = function(request, src, calloutData, pedList, vehicleList, objectList, propList, playersList, fireList, smokeList)
|
||||
local bouncerPedModels = {
|
||||
"s_m_m_bouncer_01",
|
||||
"s_m_m_highsec_01",
|
||||
"s_m_m_highsec_02",
|
||||
}
|
||||
local randomBouncers = math.random(1, 3)
|
||||
for i = 1, randomBouncers do
|
||||
-- Build peds
|
||||
local pedModel = bouncerPedModels[math.random(#bouncerPedModels)]
|
||||
local pedCoords = vector3(calloutData.Coordinates.x, calloutData.Coordinates.y, calloutData.Coordinates.z)
|
||||
local pedHeading = math.random(360)
|
||||
local pedNetId = ERS_CreatePed(pedModel, pedCoords, pedHeading)
|
||||
local ped = NetworkGetEntityFromNetworkId(pedNetId)
|
||||
table.insert(pedList, pedNetId)
|
||||
end
|
||||
|
||||
local randomBrawlers = math.random(2, 8)
|
||||
for i = 1, randomBrawlers do
|
||||
-- Build peds
|
||||
local pedModel = ERS_GetRandomModel(Config.randomPeds)
|
||||
local pedCoords = vector3(calloutData.Coordinates.x, calloutData.Coordinates.y, calloutData.Coordinates.z)
|
||||
local pedHeading = math.random(360)
|
||||
local pedNetId = ERS_CreatePed(pedModel, pedCoords, pedHeading)
|
||||
local ped = NetworkGetEntityFromNetworkId(pedNetId)
|
||||
table.insert(pedList, pedNetId)
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
Config.Callouts["roxwood_bridge_blockade"] = {
|
||||
|
||||
Enabled = true,
|
||||
CalloutName = "Bridge blockade",
|
||||
CalloutDescriptions = {
|
||||
"Emergency: respond to reports of a bridge blockade; ensure the area is cleared to prevent accidents.",
|
||||
"Urgent alert: dispatch units to address a bridge blockade; remove debris to ensure safe passage for vehicles.",
|
||||
"Critical response required: attend to reports of a bridge blockade; secure the area and prevent further incidents.",
|
||||
"Notice: check reports of a bridge blockade; take immediate action to clear debris and restore road safety.",
|
||||
"Alert: respond promptly to reports of a bridge blockade; prioritize the safety of motorists and clear the obstruction.",
|
||||
"Incident reported: investigate reports of a bridge blockade; coordinate with local authorities to manage the situation.",
|
||||
"Immediate action: address reports of a bridge blockade; use appropriate methods to clear the area and ensure safety.",
|
||||
"Situation alert: assist with clearing a bridge blockade; ensure the area is safe for traffic and pedestrians.",
|
||||
"Emergency response: handle reports of a bridge blockade and follow protocols to remove debris and ensure road safety.",
|
||||
"Response needed: investigate reports of a bridge blockade urgently; take appropriate actions to prevent accidents and ensure clear passage.",
|
||||
},
|
||||
CalloutUnitsRequired = {
|
||||
description = "Police.",
|
||||
policeRequired = true,
|
||||
ambulanceRequired = false,
|
||||
fireRequired = false,
|
||||
towRequired = false,
|
||||
},
|
||||
CalloutLocations = {
|
||||
[1] = vector3(-2015.0530, 7387.4570, 53.4759),
|
||||
[2] = vector3(-1930.3730, 7569.9995, 81.9424),
|
||||
[3] = vector3(-2857.5974, 8359.9668, 43.2680),
|
||||
[4] = vector3(-652.4728, 6653.6875, 20.9940),
|
||||
[5] = vector3(-1568.6243, 6724.4087, 17.7642),
|
||||
},
|
||||
PedChanceToFleeFromPlayer = 0, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedChanceToAttackPlayer = 0, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedChanceToSurrender = 0, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedChanceToObtainWeapons = 0, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedActionMinimumTimeoutInMs = 0, -- Milliseconds for the minimum timeout time to start the secondary action listed above.
|
||||
PedActionMaximumTimeoutInMs = 1000, -- Milliseconds for the maximum timeout time to start the secondary action. Must be a higher number than the minimum!
|
||||
PedActionOnNoActionFound = "none", -- When no action of the above options is found. It'll perform this action after the set timeout. Options: "none", "attack", "flee", "surrender"
|
||||
PedWeaponData = { -- The ped will be given one randomly selected weapon (in hand) from these weapons if PedChanceToObtainWeapons passed.
|
||||
"weapon_unarmed",
|
||||
},
|
||||
|
||||
client = function(plyPed, pedList, vehicleList, playersList, objectList, propList, fireList, smokeList, calloutDataClient)
|
||||
for index, objNetId in pairs(objectList) do
|
||||
local obj = NetToObj(objNetId)
|
||||
if DoesEntityExist(obj) then
|
||||
ERS_RequestNetControlForEntity(obj)
|
||||
PlaceObjectOnGroundProperly(obj)
|
||||
end
|
||||
end
|
||||
ERS_CreateTemporaryBlipForEntities(objectList, 30000)
|
||||
end,
|
||||
server = function(request, src, calloutData, pedList, vehicleList, objectList, propList, playersList, fireList, smokeList)
|
||||
local diameter = 10
|
||||
-- Build objects
|
||||
local bridgeBlockObjects = {"prop_rub_scrap_06", "prop_tree_fallen_02", "prop_rub_pile_02", "prop_rub_pile_01", "prop_pile_dirt_04", "prop_pile_dirt_02", "prop_pipe_single_01"}
|
||||
local randomAmountOfObjects = math.random(5)
|
||||
for i = 1, randomAmountOfObjects do
|
||||
local coords = ERS_GetRandomCoordinateWithinRangeOfCoordinate(calloutData.Coordinates, diameter)
|
||||
local objModel = ERS_GetRandomModel(bridgeBlockObjects)
|
||||
local objCoords = vector3(coords.x, coords.y, coords.z)
|
||||
local objHeading = math.random(360)
|
||||
local objNetId = ERS_CreateObject(objModel, objCoords, objHeading)
|
||||
if objNetId then
|
||||
local obj = NetworkGetEntityFromNetworkId(objNetId)
|
||||
table.insert(objectList, objNetId)
|
||||
else
|
||||
DebugPrint("^1ERROR ^7Could not create object: "..objModel)
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
Config.Callouts["roxwood_crop_fire"] = {
|
||||
Enabled = true,
|
||||
CalloutName = "Roxwood Crop Fire",
|
||||
CalloutDescriptions = {
|
||||
"Reports of a combine harvester malfunction causing a rapidly spreading wheat field fire.",
|
||||
"Lightning strike has ignited multiple dry crop fields, threatening nearby farm structures.",
|
||||
"Agricultural equipment sparked a fire in drought-affected corn fields, requiring immediate response.",
|
||||
"Burning embers from a controlled burn have spread to adjacent crop fields.",
|
||||
"Chemical fertilizer storage caught fire near valuable crop fields, situation escalating.",
|
||||
"Electrical fault in irrigation system has triggered a fire in the surrounding crop fields.",
|
||||
"Severe drought conditions have led to spontaneous combustion in hay storage, threatening nearby crops.",
|
||||
"Farm workers report uncontrolled fire spreading through mature wheat fields during harvest.",
|
||||
"Mechanical failure in grain silo ventilation system caused fire to spread to surrounding crops.",
|
||||
"Emergency response needed for crop fire threatening multiple agricultural structures and equipment.",
|
||||
},
|
||||
CalloutUnitsRequired = {
|
||||
description = "Police, Fire.",
|
||||
policeRequired = true,
|
||||
ambulanceRequired = false,
|
||||
fireRequired = true,
|
||||
towRequired = false,
|
||||
},
|
||||
CalloutLocations = {
|
||||
[1] = vector3(-2399.7097, 7358.4756, 29.0479),
|
||||
[2] = vector3(-2487.0852, 7449.9502, 29.0479),
|
||||
[3] = vector3(-2494.1135, 7374.3760, 29.0479),
|
||||
[4] = vector3(-2517.3569, 7199.2168, 29.0479),
|
||||
[5] = vector3(-2652.8608, 7139.6714, 29.0479),
|
||||
[6] = vector3(-2579.2705, 7414.2432, 29.0479),
|
||||
[7] = vector3(-2398.9187, 7448.2280, 29.0479),
|
||||
[8] = vector3(-2344.8552, 7197.0410, 29.0479),
|
||||
[9] = vector3(-2189.1917, 7144.0063, 29.0479),
|
||||
[10] = vector3(-2502.3936, 7176.9692, 29.0479),
|
||||
},
|
||||
PedChanceToFleeFromPlayer = 0, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedChanceToAttackPlayer = 0, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedChanceToSurrender = 0, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedChanceToObtainWeapons = 0, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedActionMinimumTimeoutInMs = 0, -- Milliseconds for the minimum timeout time to start the secondary action listed above.
|
||||
PedActionMaximumTimeoutInMs = 1000, -- Milliseconds for the maximum timeout time to start the secondary action. Must be a higher number than the minimum!
|
||||
PedActionOnNoActionFound = "none", -- When no action of the above options is found. It'll perform this action after the set timeout. Options: "none", "attack", "flee", "surrender"
|
||||
PedWeaponData = { -- The ped will be given one randomly selected weapon (in hand) from these weapons if PedChanceToObtainWeapons passed.
|
||||
"weapon_unarmed",
|
||||
},
|
||||
client = function(plyPed, pedList, vehicleList, playersList, objectList, propList, fireList, smokeList, calloutDataClient)
|
||||
|
||||
for index, objNetId in pairs(objectList) do
|
||||
local obj = NetToObj(objNetId)
|
||||
if DoesEntityExist(obj) then
|
||||
ERS_RequestNetControlForEntity(obj)
|
||||
PlaceObjectOnGroundProperly(obj)
|
||||
end
|
||||
end
|
||||
|
||||
end,
|
||||
server = function(request, src, calloutData, pedList, vehicleList, objectList, propList, playersList, fireList, smokeList)
|
||||
|
||||
local diameter = 30
|
||||
|
||||
-- Build Fires & smoke
|
||||
local randomAmountOfFires = math.random(10)
|
||||
for i = 1, randomAmountOfFires do
|
||||
local coords = ERS_GetRandomCoordinateWithinRangeOfCoordinate(calloutData.Coordinates, diameter)
|
||||
if UsingSmartFires then
|
||||
-- Full version
|
||||
local fireSize = Config.RandomLargeFireOrSmokeSize[math.random(#Config.RandomLargeFireOrSmokeSize)]
|
||||
local fireType = Config.NormalFireTypes[math.random(#Config.NormalFireTypes)]
|
||||
local fireId = exports['SmartFires']:CreateFire(vector3(coords.x, coords.y, coords.z+0.6), fireSize, fireType)
|
||||
DebugPrint("Created fire with ID: "..fireId)
|
||||
table.insert(fireList, fireId)
|
||||
|
||||
local smokeSize = Config.RandomMediumFireOrSmokeSize[math.random(#Config.RandomMediumFireOrSmokeSize)]
|
||||
local smokeType = Config.AllSmokeTypes[math.random(#Config.AllSmokeTypes)]
|
||||
local smokeId = exports['SmartFires']:CreateSmoke(vector3(coords.x, coords.y, coords.z-0.5), smokeSize, smokeType)
|
||||
DebugPrint("Created smoke particle with ID: "..smokeId)
|
||||
table.insert(smokeList, smokeId)
|
||||
else
|
||||
-- Lite version
|
||||
local fireSize = Config.RandomLargeFireOrSmokeSize[math.random(#Config.RandomLargeFireOrSmokeSize)]
|
||||
local fireType = "normal"
|
||||
local fireId = exports['SmartFiresLite']:CreateFire(vector3(coords.x, coords.y, coords.z+0.6), fireSize, fireType)
|
||||
DebugPrint("Created fire with SmartFiresLite with ID: "..fireId)
|
||||
table.insert(fireList, fireId)
|
||||
|
||||
local smokeSize = Config.RandomMediumFireOrSmokeSize[math.random(#Config.RandomMediumFireOrSmokeSize)]
|
||||
local smokeType = "normal"
|
||||
local smokeId = exports['SmartFiresLite']:CreateSmoke(vector3(coords.x, coords.y, coords.z-0.5), smokeSize, smokeType)
|
||||
DebugPrint("Created smoke particle with ID: "..smokeId)
|
||||
table.insert(smokeList, smokeId)
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
Config.Callouts["roxwood_drug_lab_incident"] = {
|
||||
|
||||
Enabled = true,
|
||||
CalloutName = "Drug Lab Incident",
|
||||
CalloutDescriptions = {
|
||||
"Emergency response needed at the drug lab; individual requiring immediate medical attention.",
|
||||
"Alert: medical emergency reported at drug lab facilities; units requested for immediate response.",
|
||||
"Units needed: incident reported at drug lab involving an injured person.",
|
||||
"Emergency situation at drug lab; medical assistance required for lab visitor.",
|
||||
"Alert: drug lab incident in progress; medical response team needed on scene.",
|
||||
"First responders requested at drug lab location; medical emergency reported.",
|
||||
"Respond to drug lab emergency; coordinate with on-site staff for immediate assistance.",
|
||||
"Situation alert: medical incident at drug lab facilities requiring urgent response.",
|
||||
"Emergency services needed at drug lab; injured person requiring immediate attention.",
|
||||
"Response needed: drug lab incident involving injured visitor; medical assistance required.",
|
||||
},
|
||||
CalloutUnitsRequired = {
|
||||
description = "Police, Ambulance, Fire.",
|
||||
policeRequired = true,
|
||||
ambulanceRequired = true,
|
||||
fireRequired = true,
|
||||
towRequired = false,
|
||||
},
|
||||
CalloutLocations = {
|
||||
[1] = vector3(-2281.0774, 8149.1436, 31.2439),
|
||||
[2] = vector3(-2280.4634, 8029.7676, 34.1530),
|
||||
[3] = vector3(-3075.2825, 7893.6514, 56.5999),
|
||||
},
|
||||
PedChanceToFleeFromPlayer = 30, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedChanceToAttackPlayer = 30, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedChanceToSurrender = 30, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedChanceToObtainWeapons = 30, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedActionMinimumTimeoutInMs = 0, -- Milliseconds for the minimum timeout time to start the secondary action listed above.
|
||||
PedActionMaximumTimeoutInMs = 1000, -- Milliseconds for the maximum timeout time to start the secondary action. Must be a higher number than the minimum!
|
||||
PedActionOnNoActionFound = "none", -- When no action of the above options is found. It'll perform this action after the set timeout. Options: "none", "attack", "flee", "surrender"
|
||||
PedWeaponData = { -- The ped will be given one randomly selected weapon (in hand) from these weapons if PedChanceToObtainWeapons passed.
|
||||
"weapon_pistol",
|
||||
},
|
||||
|
||||
client = function(plyPed, pedList, vehicleList, playersList, objectList, propList, fireList, smokeList, calloutDataClient)
|
||||
|
||||
for index, pedNetId in pairs(pedList) do
|
||||
local ped = NetToPed(pedNetId)
|
||||
if DoesEntityExist(ped) then
|
||||
ERS_RequestNetControlForEntity(ped)
|
||||
ERS_SetPedAsDrunkPed(ped)
|
||||
ERS_ApplyBloodToPed(ped)
|
||||
ERS_SetPedToFleeFromPlayer(ped)
|
||||
end
|
||||
end
|
||||
|
||||
ERS_CreateTemporaryBlipForEntities(pedList, 15000)
|
||||
ERS_PerformTimedActionOnPed(calloutDataClient, pedList)
|
||||
|
||||
end,
|
||||
server = function(request, src, calloutData, pedList, vehicleList, objectList, propList, playersList, fireList, smokeList)
|
||||
|
||||
-- Build peds
|
||||
local diameter = 1.5
|
||||
local randomAmountOfWorkers = math.random(1, 3)
|
||||
local drugLabWorkerPedModels = {"mp_f_cocaine_01", "mp_f_meth_01", "mp_m_meth_01", "mp_m_cocaine_01"}
|
||||
for i = 1, randomAmountOfWorkers do
|
||||
local coords = ERS_GetRandomCoordinateWithinRangeOfCoordinate(calloutData.Coordinates, diameter)
|
||||
local pedModel = drugLabWorkerPedModels[math.random(1, #drugLabWorkerPedModels)]
|
||||
local pedCoords = vector3(coords.x, coords.y, coords.z+1.0)
|
||||
local pedHeading = math.random(360)
|
||||
local pedNetId = ERS_CreatePed(pedModel, pedCoords, pedHeading)
|
||||
local ped = NetworkGetEntityFromNetworkId(pedNetId)
|
||||
table.insert(pedList, pedNetId)
|
||||
end
|
||||
|
||||
-- Build a small sized fire
|
||||
if UsingSmartFires then
|
||||
-- Full version
|
||||
local fireSize = Config.RandomSmallFireOrSmokeSize[math.random(#Config.RandomSmallFireOrSmokeSize)]
|
||||
local fireType = Config.NormalFireTypes[math.random(#Config.NormalFireTypes)]
|
||||
local fireId = exports['SmartFires']:CreateFire(vector3(calloutData.Coordinates.x, calloutData.Coordinates.y, calloutData.Coordinates.z-0.5), fireSize, fireType)
|
||||
DebugPrint("Created fire with ID: "..fireId)
|
||||
table.insert(fireList, fireId)
|
||||
|
||||
-- Build smoke
|
||||
local chanceOnASmoke = 50
|
||||
if math.random(1, 100) <= chanceOnASmoke then
|
||||
local smokeSize = Config.RandomSmallFireOrSmokeSize[math.random(#Config.RandomSmallFireOrSmokeSize)]
|
||||
local smokeType = Config.AllSmokeTypes[math.random(#Config.AllSmokeTypes)]
|
||||
local smokeId = exports['SmartFires']:CreateSmoke(vector3(calloutData.Coordinates.x, calloutData.Coordinates.y, calloutData.Coordinates.z-0.5), smokeSize, smokeType)
|
||||
|
||||
DebugPrint("Created smoke with ID: "..smokeId)
|
||||
table.insert(smokeList, smokeId)
|
||||
end
|
||||
else
|
||||
-- Lite version
|
||||
local fireSize = Config.RandomSmallFireOrSmokeSize[math.random(#Config.RandomSmallFireOrSmokeSize)]
|
||||
local fireType = "normal"
|
||||
local fireId = exports['SmartFiresLite']:CreateFire(vector3(calloutData.Coordinates.x, calloutData.Coordinates.y, calloutData.Coordinates.z-0.5), fireSize, fireType)
|
||||
DebugPrint("Created fire with SmartFiresLite with ID: "..fireId)
|
||||
table.insert(fireList, fireId)
|
||||
|
||||
-- Build smoke
|
||||
local chanceOnASmoke = 50
|
||||
if math.random(1, 100) <= chanceOnASmoke then
|
||||
local smokeSize = Config.RandomSmallFireOrSmokeSize[math.random(#Config.RandomSmallFireOrSmokeSize)]
|
||||
local smokeType = "normal"
|
||||
local smokeId = exports['SmartFiresLite']:CreateSmoke(vector3(calloutData.Coordinates.x, calloutData.Coordinates.y, calloutData.Coordinates.z-0.5), smokeSize, smokeType)
|
||||
|
||||
DebugPrint("Created smoke with ID: "..smokeId)
|
||||
table.insert(smokeList, smokeId)
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
Config.Callouts["roxwood_gas_station_robbery"] = {
|
||||
|
||||
Enabled = true,
|
||||
CalloutName = "Roxwood Gas Station Robbery",
|
||||
CalloutDescriptions = {
|
||||
"Respond to a report of an armed robbery at a gas station; secure the area and apprehend the suspects.",
|
||||
"Alert: armed robbery in progress at a gas station; deploy units to the location and ensure public safety.",
|
||||
"Units needed: report of a robbery involving multiple armed suspects; focus on securing the scene and detaining the suspects.",
|
||||
"Notice: armed robbery reported at a gas station; act promptly to control the situation and prevent harm.",
|
||||
"Alert: report of an armed robbery; intervention needed to apprehend the suspects and ensure safety.",
|
||||
"Incident reported: armed robbery at a gas station; take action to secure the premises and protect bystanders.",
|
||||
"Respond to a situation involving an armed robbery; prioritize public safety and coordinate with law enforcement.",
|
||||
"Situation alert: armed robbery in progress; secure the area and detain the suspects.",
|
||||
"Alert: report of a robbery with weapons; respond swiftly to address the situation and ensure safety.",
|
||||
"Response needed: armed robbery; secure the area, apprehend the suspects, and restore order.",
|
||||
},
|
||||
CalloutUnitsRequired = {
|
||||
description = "Police, Ambulance.",
|
||||
policeRequired = true,
|
||||
ambulanceRequired = true,
|
||||
fireRequired = false,
|
||||
towRequired = false,
|
||||
},
|
||||
CalloutLocations = {
|
||||
[1] = vector3(-1228.4095, 6927.7363, 20.4751),
|
||||
[2] = vector3(-522.2498, 7560.3276, 6.5205),
|
||||
},
|
||||
PedChanceToFleeFromPlayer = 50, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedChanceToAttackPlayer = 50, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedChanceToSurrender = 20, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedChanceToObtainWeapons = 100, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedActionMinimumTimeoutInMs = 10000, -- Milliseconds for the minimum timeout time to start the secondary action listed above.
|
||||
PedActionMaximumTimeoutInMs = 15000, -- Milliseconds for the maximum timeout time to start the secondary action. Must be a higher number than the minimum!
|
||||
PedActionOnNoActionFound = "attack", -- When no action of the above options is found. It'll perform this action after the set timeout. Options: "none", "attack", "flee", "surrender"
|
||||
PedWeaponData = { -- The ped will be given one randomly selected weapon (in hand) from these weapons if PedChanceToObtainWeapons passed.
|
||||
"weapon_pistol",
|
||||
},
|
||||
|
||||
client = function(plyPed, pedList, vehicleList, playersList, objectList, propList, fireList, smokeList, calloutDataClient)
|
||||
|
||||
local plyGroupHash = GetPedRelationshipGroupHash(plyPed)
|
||||
local retval, suspectGroupHash = AddRelationshipGroup("SUSPECT_GROUP_HASH")
|
||||
local victim
|
||||
local suspectPedList = {}
|
||||
|
||||
for index, pedNetId in pairs(pedList) do
|
||||
local ped = NetToPed(pedNetId)
|
||||
if DoesEntityExist(ped) then
|
||||
ERS_RequestNetControlForEntity(ped)
|
||||
if index == 1 then
|
||||
victim = ped
|
||||
ERS_ClearPedTasksAndBlockEvents(ped)
|
||||
Wait(100)
|
||||
TaskHandsUp(ped, -1, 0, -1, true)
|
||||
else
|
||||
SetPedRelationshipGroupHash(ped, suspectGroupHash)
|
||||
SetEntityCanBeDamagedByRelationshipGroup(ped, false, suspectGroupHash)
|
||||
SetRelationshipBetweenGroups(5, suspectGroupHash, plyGroupHash)
|
||||
SetRelationshipBetweenGroups(5, plyGroupHash, suspectGroupHash)
|
||||
|
||||
ERS_ClearPedTasksAndBlockEvents(ped)
|
||||
ERS_SpawnConfiguredWeaponForPed(ped, calloutDataClient)
|
||||
Wait(100)
|
||||
TaskAimGunAtEntity(ped, victim, -1, false)
|
||||
table.insert(suspectPedList, pedNetId)
|
||||
|
||||
Citizen.CreateThread(function()
|
||||
local randomTime = math.random(5000, 9000)
|
||||
Citizen.Wait(randomTime)
|
||||
local chanceToShoot = math.random(1, 100)
|
||||
if chanceToShoot <= 50 then
|
||||
TaskShootAtEntity(ped, victim, -1, false)
|
||||
else
|
||||
TaskSmartFleePed(ped, plyPed, 10000, -1, false)
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ERS_CreateTemporaryBlipForEntities(suspectPedList, 15000)
|
||||
|
||||
ERS_PerformTimedActionOnPed(calloutDataClient, suspectPedList)
|
||||
|
||||
end,
|
||||
server = function(request, src, calloutData, pedList, vehicleList, objectList, propList, playersList, fireList, smokeList)
|
||||
|
||||
local diameter = 15
|
||||
|
||||
-- Build victim
|
||||
local pedModel = ERS_GetRandomModel(Config.randomPeds)
|
||||
local pedCoords = vector3(calloutData.Coordinates.x, calloutData.Coordinates.y, calloutData.Coordinates.z+1.0)
|
||||
local pedHeading = math.random(360)
|
||||
local pedNetId = ERS_CreatePed(pedModel, pedCoords, pedHeading)
|
||||
local ped = NetworkGetEntityFromNetworkId(pedNetId)
|
||||
table.insert(pedList, pedNetId)
|
||||
|
||||
-- Build suspects
|
||||
local randomAmountOfSuspects = math.random(2, 4) -- Randomize number of suspects
|
||||
for i = 1, randomAmountOfSuspects do
|
||||
local coords = ERS_GetRandomCoordinateWithinRangeOfCoordinate(calloutData.Coordinates, diameter)
|
||||
local pedModel = ERS_GetRandomModel(Config.randomPeds)
|
||||
local pedCoords = vector3(coords.x, coords.y, coords.z+1.0)
|
||||
local pedHeading = math.random(360)
|
||||
local pedNetId = ERS_CreatePed(pedModel, pedCoords, pedHeading)
|
||||
local ped = NetworkGetEntityFromNetworkId(pedNetId)
|
||||
table.insert(pedList, pedNetId)
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
Config.Callouts["roxwood_illegal_camping"] = {
|
||||
|
||||
Enabled = true,
|
||||
CalloutName = "Illegal Camping",
|
||||
CalloutDescriptions = {
|
||||
"Investigate reports of illegal camping in a restricted area; ensure compliance with local regulations.",
|
||||
"Alert: dispatch units to handle reports of unauthorized camping; assess environmental impact.",
|
||||
"Units required: respond to reports of illegal camping and evaluate potential safety hazards.",
|
||||
"Notice: check reports of campers setting up in prohibited zones; enforce park rules.",
|
||||
"Alert: respond promptly to reports of unauthorized camping; prioritize public safety and environmental protection.",
|
||||
"Incident reported: look into reports of illegal camping activities to understand the situation.",
|
||||
"Investigate reports of campers in restricted areas; coordinate with park authorities and secure the site.",
|
||||
"Situation alert: address reports of illegal camping; work with local enforcement to resolve the issue.",
|
||||
"Alert: handle reports of unauthorized camping and adhere to protocols for potential environmental hazards.",
|
||||
"Response needed: investigate reports of illegal camping and take steps to ensure compliance with regulations.",
|
||||
},
|
||||
CalloutUnitsRequired = {
|
||||
description = "Police",
|
||||
policeRequired = true,
|
||||
ambulanceRequired = false,
|
||||
fireRequired = false,
|
||||
towRequired = false,
|
||||
},
|
||||
CalloutLocations = {
|
||||
[1] = vector3(-2968.4868, 8348.0039, 43.2270),
|
||||
[2] = vector3(-2376.2881, 7808.8652, 33.1581),
|
||||
[3] = vector3(-2710.9854, 7801.0586, 46.5524),
|
||||
[4] = vector3(-3067.7266, 7109.3135, 42.5468),
|
||||
[5] = vector3(-3676.9055, 6168.9692, 24.5723),
|
||||
[6] = vector3(-3588.0854, 7165.6846, 46.3299),
|
||||
[7] = vector3(-3312.8560, 8835.7363, 36.2966),
|
||||
[8] = vector3(-1284.6665, 8242.3164, 12.2473),
|
||||
[9] = vector3(-1490.4974, -262.6434, 50.2380),
|
||||
[10] = vector3(-2220.6472, 7570.6499, 56.8878),
|
||||
},
|
||||
PedChanceToFleeFromPlayer = 10, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedChanceToAttackPlayer = 10, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedChanceToSurrender = 50, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedChanceToObtainWeapons = 10, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedActionMinimumTimeoutInMs = 10000, -- Milliseconds for the minimum timeout time to start the secondary action listed above.
|
||||
PedActionMaximumTimeoutInMs = 15000, -- Milliseconds for the maximum timeout time to start the secondary action. Must be a higher number than the minimum!
|
||||
PedActionOnNoActionFound = "none", -- When no action of the above options is found. It'll perform this action after the set timeout. Options: "none", "attack", "flee", "surrender"
|
||||
PedWeaponData = { -- The ped will be given one randomly selected weapon (in hand) from these weapons if PedChanceToObtainWeapons passed.
|
||||
"weapon_knife",
|
||||
},
|
||||
|
||||
client = function(plyPed, pedList, vehicleList, playersList, objectList, propList, fireList, smokeList, calloutDataClient)
|
||||
|
||||
local vehicle
|
||||
local driver
|
||||
|
||||
for index, vehNetId in pairs(vehicleList) do
|
||||
local veh = NetToVeh(vehNetId)
|
||||
if DoesEntityExist(veh) then
|
||||
vehicle = veh
|
||||
ERS_RequestNetControlForEntity(vehicle)
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
for index, pedNetId in pairs(pedList) do
|
||||
local ped = NetToPed(pedNetId)
|
||||
if DoesEntityExist(ped) then
|
||||
if index == 1 then
|
||||
driver = ped
|
||||
ERS_RequestNetControlForEntity(driver)
|
||||
TaskSetBlockingOfNonTemporaryEvents(driver, true)
|
||||
ERS_SetPedAsDrunkPed(driver)
|
||||
else
|
||||
-- Play a smoking weed animation on them
|
||||
ERS_SetPedAsDrunkPed(ped)
|
||||
local scenario = ERS_SelectRandomSmokeScenario()
|
||||
TaskStartScenarioInPlace(ped, scenario, 0, true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ERS_CreateTemporaryBlipForEntities(vehicleList, 15000)
|
||||
ERS_CreateTemporaryBlipForEntities(pedList, 15000)
|
||||
|
||||
end,
|
||||
server = function(request, src, calloutData, pedList, vehicleList, objectList, propList, playersList, fireList, smokeList)
|
||||
|
||||
-- Build vehicle
|
||||
local campingVehicles = {"camper", "journey", "paradise"}
|
||||
local vehModel = ERS_GetRandomModel(campingVehicles)
|
||||
local vehType = "automobile"
|
||||
local vehCoords = vector3(calloutData.Coordinates.x, calloutData.Coordinates.y, calloutData.Coordinates.z)
|
||||
local vehHeading = math.random(360)
|
||||
local vehNetId = ERS_CreateVehicle(vehModel, vehType, vehCoords, vehHeading)
|
||||
local vehicle = NetworkGetEntityFromNetworkId(vehNetId)
|
||||
table.insert(vehicleList, vehNetId)
|
||||
|
||||
-- Build ped
|
||||
local pedModel = ERS_GetRandomModel(Config.randomPeds)
|
||||
local pedCoords = vector3(calloutData.Coordinates.x, calloutData.Coordinates.y, calloutData.Coordinates.z+3.0)
|
||||
local pedHeading = math.random(360)
|
||||
local pedNetId = ERS_CreatePed(pedModel, pedCoords, pedHeading)
|
||||
local ped = NetworkGetEntityFromNetworkId(pedNetId)
|
||||
SetPedIntoVehicle(ped, vehicle, -1)
|
||||
table.insert(pedList, pedNetId)
|
||||
|
||||
-- Build camping friends
|
||||
local amountOfCampingFriends = math.random(1, 5)
|
||||
for i = 1, amountOfCampingFriends do
|
||||
local diameter = 20.0
|
||||
local coords = ERS_GetRandomCoordinateWithinRangeOfCoordinate(calloutData.Coordinates, diameter)
|
||||
local companionModel = ERS_GetRandomModel(Config.randomPeds)
|
||||
local companionCoords = vector3(coords.x, coords.y, coords.z+3.0)
|
||||
local companionHeading = math.random(360)
|
||||
local companionNetId = ERS_CreatePed(companionModel, companionCoords, companionHeading)
|
||||
table.insert(pedList, companionNetId)
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
Config.Callouts["roxwood_miner_panic_alarm"] = {
|
||||
|
||||
Enabled = true,
|
||||
CalloutName = "Panic alarm at the mine",
|
||||
CalloutDescriptions = {
|
||||
"Emergency responders are required to investigate the source of the panic alarm at the mine.",
|
||||
"Authorities report panic alarm at the mine, demanding immediate investigation to ensure safety.",
|
||||
"Panic alarm has been reported at the mine, necessitating urgent action to identify and address the cause.",
|
||||
"Critical situation with panic alarm at the mine; additional units are needed for support.",
|
||||
"Immediate response needed to address panic alarm at the mine posing potential danger.",
|
||||
"Panic alarm has been detected at the mine, posing a possible threat; reinforcements are necessary to investigate and contain any hazards.",
|
||||
"Emergency crews are requesting backup to assist in investigating and managing panic alarm at the mine.",
|
||||
"An urgent call for help has been issued to handle panic alarm at the mine and ensure safety.",
|
||||
"Responders are on the scene of panic alarm at the mine and need extra support to stabilize the situation.",
|
||||
"A serious emergency involving panic alarm at the mine demands swift action to prevent a potential catastrophic outcome.",
|
||||
},
|
||||
CalloutUnitsRequired = {
|
||||
description = "Police, Fire.",
|
||||
policeRequired = true,
|
||||
ambulanceRequired = false,
|
||||
fireRequired = true,
|
||||
towRequired = false,
|
||||
},
|
||||
CalloutLocations = {
|
||||
[1] = vector3(-1474.1163, 7612.5264, 90.0090),
|
||||
[2] = vector3(-1498.0601, 7648.6548, 89.9406),
|
||||
[3] = vector3(-1561.5817, 7478.5679, 95.6648),
|
||||
[4] = vector3(-1400.6205, 7501.4053, 80.8366),
|
||||
},
|
||||
PedChanceToFleeFromPlayer = 0, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedChanceToAttackPlayer = 0, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedChanceToSurrender = 0, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedChanceToObtainWeapons = 0, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedActionMinimumTimeoutInMs = 0, -- Milliseconds for the minimum timeout time to start the secondary action listed above.
|
||||
PedActionMaximumTimeoutInMs = 1000, -- Milliseconds for the maximum timeout time to start the secondary action. Must be a higher number than the minimum!
|
||||
PedActionOnNoActionFound = "none", -- When no action of the above options is found. It'll perform this action after the set timeout. Options: "none", "attack", "flee", "surrender"
|
||||
PedWeaponData = { -- The ped will be given one randomly selected weapon (in hand) from these weapons if PedChanceToObtainWeapons passed.
|
||||
"weapon_unarmed",
|
||||
},
|
||||
|
||||
client = function(plyPed, pedList, vehicleList, playersList, objectList, propList, fireList, smokeList, calloutDataClient)
|
||||
|
||||
-- No other actions required clientside.
|
||||
for index, pedNetId in pairs(pedList) do
|
||||
local ped = NetToPed(pedNetId)
|
||||
if DoesEntityExist(ped) then
|
||||
ERS_RequestNetControlForEntity(ped)
|
||||
TaskSetBlockingOfNonTemporaryEvents(ped, true)
|
||||
ERS_ApplyBloodToPed(ped)
|
||||
local scenario = ERS_SelectRandomWoundedPersonScenario()
|
||||
TaskStartScenarioInPlace(ped, scenario, 0, true)
|
||||
end
|
||||
end
|
||||
|
||||
ERS_CreateTemporaryBlipForEntities(pedList, 120000)
|
||||
ERS_PerformTimedActionOnPed(calloutDataClient, pedList)
|
||||
end,
|
||||
server = function(request, src, calloutData, pedList, vehicleList, objectList, propList, playersList, fireList, smokeList)
|
||||
|
||||
-- Build smoke
|
||||
if UsingSmartFires then
|
||||
-- Full version
|
||||
local smokeSize = Config.RandomMediumFireOrSmokeSize[math.random(#Config.RandomMediumFireOrSmokeSize)]
|
||||
local smokeType = Config.FoggySmoke
|
||||
local smokeId = exports['SmartFires']:CreateSmoke(vector3(calloutData.Coordinates.x, calloutData.Coordinates.y, calloutData.Coordinates.z-0.5), smokeSize, smokeType)
|
||||
DebugPrint("Created smoke particle with ID: "..smokeId)
|
||||
table.insert(smokeList, smokeId)
|
||||
else
|
||||
-- Lite version
|
||||
local smokeSize = Config.RandomMediumFireOrSmokeSize[math.random(#Config.RandomMediumFireOrSmokeSize)]
|
||||
local smokeType = "normal"
|
||||
local smokeId = exports['SmartFiresLite']:CreateSmoke(vector3(calloutData.Coordinates.x, calloutData.Coordinates.y, calloutData.Coordinates.z-0.5), smokeSize, smokeType)
|
||||
DebugPrint("Created smoke particle with ID: "..smokeId)
|
||||
table.insert(smokeList, smokeId)
|
||||
end
|
||||
|
||||
-- Build wounded miner
|
||||
local amountOfPeds = math.random(1, 4)
|
||||
local minerPedModels = {"s_m_y_construct_01", "s_m_y_construct_02"}
|
||||
for i = 1, amountOfPeds do
|
||||
local pedModel = ERS_GetRandomModel(minerPedModels)
|
||||
local pedCoords = vector3(calloutData.Coordinates.x, calloutData.Coordinates.y, calloutData.Coordinates.z)
|
||||
local pedHeading = math.random(360)
|
||||
local pedNetId = ERS_CreatePed(pedModel, pedCoords, pedHeading)
|
||||
local ped = NetworkGetEntityFromNetworkId(pedNetId)
|
||||
table.insert(pedList, pedNetId)
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
}
|
||||
@@ -0,0 +1,516 @@
|
||||
Config.Callouts["roxwood_mysterious_egg"] = {
|
||||
|
||||
Enabled = true,
|
||||
CalloutName = "Mysterious egg(s) reported",
|
||||
CalloutDescriptions = {
|
||||
"Emergency: respond to reports of a mysterious egg; assess potential hazards.",
|
||||
"Urgent alert: unidentified egg-like object reported requiring immediate investigation.",
|
||||
"Critical response required: investigate reports of an unusual egg of unknown origin.",
|
||||
"Notice: mysterious egg discovered in the area; assessment needed.",
|
||||
"Alert: respond to reports of a suspicious egg-shaped object; evaluate potential risks.",
|
||||
"Incident reported: mysterious egg found requiring immediate attention.",
|
||||
"Immediate action: address reports of an unidentified egg; assess situation.",
|
||||
"Situation alert: investigation needed for mysterious egg discovery.",
|
||||
"Emergency response: handle reports of an unusual egg; ensure public safety.",
|
||||
"Response needed: investigate reports of a mysterious egg; assess and secure the area.",
|
||||
},
|
||||
CalloutUnitsRequired = {
|
||||
description = "Police, fire.",
|
||||
policeRequired = true,
|
||||
ambulanceRequired = false,
|
||||
fireRequired = true,
|
||||
towRequired = false,
|
||||
},
|
||||
CalloutLocations = {
|
||||
[1] = vector3(-176.0005, 7555.7231, 2.0013),
|
||||
[2] = vector3(-229.1338, 7345.6353, 4.2200),
|
||||
[3] = vector3(-3411.0190, 6075.2427, 2.6527),
|
||||
[4] = vector3(-783.9731, 6659.8804, 2.3201),
|
||||
[5] = vector3(-328.8283, 6974.1064, 2.4945),
|
||||
},
|
||||
PedChanceToFleeFromPlayer = 0, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedChanceToAttackPlayer = 0, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedChanceToSurrender = 0, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedChanceToObtainWeapons = 0, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedActionMinimumTimeoutInMs = 0, -- Milliseconds for the minimum timeout time to start the secondary action listed above.
|
||||
PedActionMaximumTimeoutInMs = 1000, -- Milliseconds for the maximum timeout time to start the secondary action. Must be a higher number than the minimum!
|
||||
PedActionOnNoActionFound = "none", -- When no action of the above options is found. It'll perform this action after the set timeout. Options: "none", "attack", "flee", "surrender"
|
||||
PedWeaponData = { -- The ped will be given one randomly selected weapon (in hand) from these weapons if PedChanceToObtainWeapons passed.
|
||||
"weapon_unarmed",
|
||||
},
|
||||
|
||||
client = function(plyPed, pedList, vehicleList, playersList, objectList, propList, fireList, smokeList, calloutDataClient)
|
||||
local eggObjects = {}
|
||||
for index, objNetId in pairs(objectList) do
|
||||
local obj = NetToObj(objNetId)
|
||||
if DoesEntityExist(obj) then
|
||||
ERS_RequestNetControlForEntity(obj)
|
||||
PlaceObjectOnGroundProperly(obj)
|
||||
table.insert(eggObjects, obj)
|
||||
|
||||
-- Make weird shit happen, like drawing lights fading in and out in green colour
|
||||
local coords = GetEntityCoords(obj)
|
||||
local radius = 10.0
|
||||
local intensity = 0.0
|
||||
local fadeSpeed = 0.005 -- Lower = slower fade
|
||||
local increasing = true
|
||||
|
||||
Citizen.CreateThread(function()
|
||||
while DoesEntityExist(obj) do
|
||||
-- Draw the light with current intensity
|
||||
DrawLightWithRangeAndShadow(
|
||||
coords.x,
|
||||
coords.y,
|
||||
coords.z,
|
||||
0, -- Red
|
||||
math.floor(intensity * 100), -- Green (0-100 range)
|
||||
0, -- Blue
|
||||
10.0,
|
||||
0.5, -- Light intensity
|
||||
1.0
|
||||
)
|
||||
|
||||
-- Update intensity
|
||||
if increasing then
|
||||
intensity = intensity + fadeSpeed
|
||||
if intensity >= 1.0 then
|
||||
intensity = 1.0
|
||||
increasing = false
|
||||
end
|
||||
else
|
||||
intensity = intensity - fadeSpeed
|
||||
if intensity <= 0.0 then
|
||||
intensity = 0.0
|
||||
increasing = true
|
||||
end
|
||||
end
|
||||
|
||||
Wait(0)
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
-- Make UFO fly in from high altitude, then start the abduction sequence
|
||||
local ufoEntityId = nil
|
||||
local ufoNetId = nil
|
||||
Citizen.SetTimeout(10000, function()
|
||||
local ufoModel = 'imp_prop_ship_01a'
|
||||
RequestModel(ufoModel)
|
||||
while not HasModelLoaded(ufoModel) do
|
||||
Wait(100)
|
||||
end
|
||||
|
||||
-- Start position high in the sky
|
||||
local startCoords = vector3(calloutDataClient.Coordinates.x + 50.0, calloutDataClient.Coordinates.y + 50.0, calloutDataClient.Coordinates.z + 150.0)
|
||||
local finalCoords = vector3(calloutDataClient.Coordinates.x, calloutDataClient.Coordinates.y, calloutDataClient.Coordinates.z + 30.0)
|
||||
local ufoHeading = math.random(360)
|
||||
|
||||
-- Create UFO at start position
|
||||
ufoEntityId = CreateObject(ufoModel, startCoords.x, startCoords.y, startCoords.z, true, true, true)
|
||||
while not DoesEntityExist(ufoEntityId) do
|
||||
Wait(100)
|
||||
end
|
||||
ufoNetId = NetworkGetNetworkIdFromEntity(ufoEntityId)
|
||||
|
||||
-- Play UFO approach sound
|
||||
PlaySoundFrontend(-1, "Object_Dropped_Remote", "GTAO_FM_Events_Soundset", true)
|
||||
|
||||
-- UFO arrival animation
|
||||
Citizen.CreateThread(function()
|
||||
local arrivalDuration = 5000 -- 5 seconds for arrival
|
||||
local startTime = GetGameTimer()
|
||||
|
||||
-- Add a slight hovering effect
|
||||
local hoverOffset = 0.0
|
||||
local hoverRate = 0.003 -- Reduced from 0.01 for slower hovering
|
||||
|
||||
-- Play arrival sequence
|
||||
while DoesEntityExist(ufoEntityId) do
|
||||
local currentTime = GetGameTimer()
|
||||
local timeElapsed = currentTime - startTime
|
||||
local t = math.min(timeElapsed / arrivalDuration, 1.0)
|
||||
|
||||
-- Use cubic easing for natural movement
|
||||
local tSquared = t * t
|
||||
local tCubed = tSquared * t
|
||||
local easedT = 1.0 - math.pow(1.0 - t, 3)
|
||||
|
||||
-- Calculate new position
|
||||
local newX = lerp(startCoords.x, finalCoords.x, easedT)
|
||||
local newY = lerp(startCoords.y, finalCoords.y, easedT)
|
||||
local newZ = lerp(startCoords.z, finalCoords.z, easedT)
|
||||
|
||||
-- Add hovering effect
|
||||
hoverOffset = math.sin(currentTime * hoverRate) * 0.5
|
||||
|
||||
-- Set UFO position
|
||||
SetEntityCoords(ufoEntityId, newX, newY, newZ + hoverOffset, false, false, false, false)
|
||||
|
||||
-- Rotate the UFO slightly as it comes in
|
||||
local currentHeading = GetEntityHeading(ufoEntityId)
|
||||
SetEntityHeading(ufoEntityId, currentHeading + 0.2)
|
||||
|
||||
-- If UFO reached final position, break the loop
|
||||
if t >= 1.0 then
|
||||
-- Play hovering sound when UFO is in position
|
||||
--PlaySoundFrontend(-1, "Altitude_Warning", "EXILE_1", true)
|
||||
PlaySoundFrontend(-1, "Object_Dropped_Remote", "GTAO_FM_Events_Soundset", true)
|
||||
break
|
||||
end
|
||||
|
||||
Wait(0)
|
||||
end
|
||||
|
||||
-- After arrival, continue with the spotlights and abduction
|
||||
local ufoCoords = GetEntityCoords(ufoEntityId)
|
||||
local isCalloutActive = true
|
||||
local isUFODeparting = false -- New flag to control hover effect
|
||||
|
||||
-- Create a thread to monitor callout status
|
||||
Citizen.CreateThread(function()
|
||||
while true do
|
||||
-- Check if callout is still active
|
||||
if not isAttachedToCallout then
|
||||
isCalloutActive = false
|
||||
|
||||
-- Clean up UFO if it exists
|
||||
if DoesEntityExist(ufoEntityId) then
|
||||
DeleteEntity(ufoEntityId)
|
||||
end
|
||||
|
||||
-- Break the monitoring loop
|
||||
break
|
||||
end
|
||||
Wait(1000) -- Check every second
|
||||
end
|
||||
end)
|
||||
|
||||
Citizen.CreateThread(function()
|
||||
-- Light pulsing variables
|
||||
local lightIntensity = 1.0
|
||||
local pulseRate = 0.005
|
||||
local minIntensity = 0.7
|
||||
local maxIntensity = 1.3
|
||||
|
||||
-- Play spotlight activation sound
|
||||
PlaySoundFrontend(-1, "Beep_Red", "DLC_HEIST_HACKING_SNAKE_SOUNDS", true)
|
||||
Wait(800)
|
||||
PlaySoundFrontend(-1, "CHECKPOINT_PERFECT", "HUD_MINI_GAME_SOUNDSET", true)
|
||||
|
||||
while DoesEntityExist(ufoEntityId) and isCalloutActive do
|
||||
local gameTime = GetGameTimer()
|
||||
|
||||
-- Only apply hover if not departing
|
||||
if not isUFODeparting then
|
||||
-- Update hover effect with slower rate
|
||||
hoverOffset = math.sin(gameTime * hoverRate) * 0.5
|
||||
SetEntityCoords(ufoEntityId, ufoCoords.x, ufoCoords.y, ufoCoords.z + hoverOffset, false, false, false, false)
|
||||
end
|
||||
|
||||
-- Calculate pulsing light intensity
|
||||
lightIntensity = lerp(minIntensity, maxIntensity, (math.sin(gameTime * pulseRate) + 1) * 0.5)
|
||||
|
||||
-- Draw spotlights only if not departing
|
||||
if not isUFODeparting then
|
||||
-- Draw the main red spotlight with pulsing intensity
|
||||
DrawSpotLightWithShadow(
|
||||
ufoCoords.x, ufoCoords.y, ufoCoords.z-3.0,
|
||||
0.0, 0.0, -1.0,
|
||||
255, 0, 0,
|
||||
100.0, lightIntensity, 0.0, 100.0, 1.0
|
||||
)
|
||||
|
||||
-- White spotlight remains consistent
|
||||
DrawSpotLightWithShadow(
|
||||
ufoCoords.x, ufoCoords.y, ufoCoords.z-3.0,
|
||||
0.0, 0.0, -1.0,
|
||||
255, 255, 255,
|
||||
100.0, 1.0, 0.0, 20.0, 1.0
|
||||
)
|
||||
end
|
||||
Wait(0)
|
||||
end
|
||||
end)
|
||||
|
||||
-- Create a forceful push away from eggs when player gets too close
|
||||
Citizen.CreateThread(function()
|
||||
while true do
|
||||
local playerPed = PlayerPedId()
|
||||
local playerCoords = GetEntityCoords(playerPed)
|
||||
|
||||
for _, eggObject in ipairs(eggObjects) do
|
||||
if DoesEntityExist(eggObject) then
|
||||
local eggCoords = GetEntityCoords(eggObject)
|
||||
local distance = #(playerCoords - eggCoords)
|
||||
|
||||
-- Strong repulsion when very close to eggs
|
||||
if distance < 8.0 then -- Reduced range for more dramatic effect
|
||||
-- Calculate direction AWAY from egg
|
||||
local force = (playerCoords - eggCoords)
|
||||
local magnitude = #force
|
||||
|
||||
if magnitude > 0 then
|
||||
-- Strong push at any time
|
||||
local pushStrength = 10.0
|
||||
|
||||
-- Ragdoll the player for dramatic effect
|
||||
SetPedGravity(playerPed, false)
|
||||
SetPedToRagdoll(playerPed, 1000, 1000, 0, 0, 0, 0)
|
||||
|
||||
-- Apply strong push force away from egg
|
||||
SetEntityVelocity(playerPed,
|
||||
force.x/magnitude * pushStrength,
|
||||
force.y/magnitude * pushStrength,
|
||||
pushStrength * 0.5) -- Upward component for dramatic effect
|
||||
|
||||
-- Small delay to prevent sound spam
|
||||
Wait(500)
|
||||
SetPedGravity(playerPed, true)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Wait(0)
|
||||
end
|
||||
end)
|
||||
|
||||
-- Make the objects fly up into the UFO and make the UFO fly away
|
||||
Citizen.CreateThread(function()
|
||||
local objectsRemaining = #objectList
|
||||
local lastObject = nil
|
||||
local shouldFlyAway = false -- New flag to control UFO departure
|
||||
|
||||
-- Handle each object in the list
|
||||
for _, eggObject in ipairs(eggObjects) do
|
||||
if DoesEntityExist(eggObject) and isCalloutActive then
|
||||
local startCoords = GetEntityCoords(eggObject)
|
||||
local endCoords = GetEntityCoords(ufoEntityId)
|
||||
local duration = 5000 -- 5 seconds for each object
|
||||
local startTime = GetGameTimer()
|
||||
|
||||
-- Animate each object
|
||||
while DoesEntityExist(ufoEntityId) and DoesEntityExist(eggObject) and isCalloutActive do
|
||||
local currentTime = GetGameTimer()
|
||||
local timeElapsed = currentTime - startTime
|
||||
|
||||
-- Calculate easing
|
||||
local t = math.min(timeElapsed / duration, 1.0)
|
||||
local tSquared = t * t
|
||||
local tCubed = tSquared * t
|
||||
local easedT = 3 * tSquared - 2 * tCubed
|
||||
|
||||
-- Calculate new position
|
||||
local newX = lerp(startCoords.x, endCoords.x, easedT)
|
||||
local newY = lerp(startCoords.y, endCoords.y, easedT)
|
||||
local newZ = lerp(startCoords.z, endCoords.z + 1.0, easedT)
|
||||
|
||||
-- Add some wobble to the movement
|
||||
local wobble = math.sin(timeElapsed * 0.01) * (1.0 - easedT) * 0.3
|
||||
|
||||
-- Set new position
|
||||
SetEntityCoords(eggObject, newX + wobble, newY + wobble, newZ, false, false, false, false)
|
||||
|
||||
-- Add rotation
|
||||
local currentRotation = GetEntityRotation(eggObject, 2)
|
||||
SetEntityRotation(eggObject,
|
||||
currentRotation.x + 2.0,
|
||||
currentRotation.y + 2.0,
|
||||
currentRotation.z + 2.0,
|
||||
2, true)
|
||||
|
||||
-- Draw laser beam from UFO to object
|
||||
local ufoPos = GetEntityCoords(ufoEntityId)
|
||||
local objPos = GetEntityCoords(eggObject)
|
||||
|
||||
-- Main laser beam
|
||||
DrawLine(
|
||||
ufoPos.x, ufoPos.y, ufoPos.z - 2.0, -- From bottom of UFO
|
||||
objPos.x, objPos.y, objPos.z, -- To object
|
||||
0, 255, 0, -- Green color
|
||||
255 -- Alpha
|
||||
)
|
||||
|
||||
-- Add some additional lines for thickness effect
|
||||
DrawLine(
|
||||
ufoPos.x + 0.05, ufoPos.y, ufoPos.z - 2.0,
|
||||
objPos.x + 0.05, objPos.y, objPos.z,
|
||||
0, 255, 0, 180
|
||||
)
|
||||
|
||||
DrawLine(
|
||||
ufoPos.x - 0.05, ufoPos.y, ufoPos.z - 2.0,
|
||||
objPos.x - 0.05, objPos.y, objPos.z,
|
||||
0, 255, 0, 180
|
||||
)
|
||||
|
||||
DrawLine(
|
||||
ufoPos.x, ufoPos.y + 0.05, ufoPos.z - 2.0,
|
||||
objPos.x, objPos.y + 0.05, objPos.z,
|
||||
0, 255, 0, 180
|
||||
)
|
||||
|
||||
DrawLine(
|
||||
ufoPos.x, ufoPos.y - 0.05, ufoPos.z - 2.0,
|
||||
objPos.x, objPos.y - 0.05, objPos.z,
|
||||
0, 255, 0, 180
|
||||
)
|
||||
|
||||
-- Add pulsing effect
|
||||
local pulseIntensity = math.sin(timeElapsed * 0.02) * 0.5 + 0.5
|
||||
DrawLine(
|
||||
ufoPos.x, ufoPos.y, ufoPos.z - 2.0,
|
||||
objPos.x, objPos.y, objPos.z,
|
||||
0, 255 * pulseIntensity, 0,
|
||||
200
|
||||
)
|
||||
|
||||
-- If object reached UFO
|
||||
if t >= 1.0 then
|
||||
-- Play object capture sound
|
||||
PlaySoundFrontend(-1, "CHECKPOINT_UNDER_THE_BRIDGE", "HUD_MINI_GAME_SOUNDSET", true)
|
||||
--print("Object reached UFO, remaining: " .. objectsRemaining) -- Debug print
|
||||
|
||||
objectsRemaining = objectsRemaining - 1
|
||||
|
||||
if DoesEntityExist(eggObject) then
|
||||
if objectsRemaining == 0 then
|
||||
--print("Last object captured, preparing UFO departure") -- Debug print
|
||||
lastObject = eggObject
|
||||
SetEntityVisible(eggObject, false, false)
|
||||
shouldFlyAway = true -- Set flag for UFO to fly away
|
||||
else
|
||||
ERS_DeleteEntityFromCallout(eggObject)
|
||||
end
|
||||
end
|
||||
break
|
||||
end
|
||||
|
||||
Wait(0)
|
||||
end
|
||||
|
||||
-- Small delay between objects
|
||||
if isCalloutActive and objectsRemaining > 0 then
|
||||
Wait(500)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- In the UFO departure sequence, set isUFODeparting = true before starting:
|
||||
if shouldFlyAway then
|
||||
--print("Starting UFO departure sequence") -- Debug print
|
||||
|
||||
-- Add a delay before departure
|
||||
Wait(2000)
|
||||
|
||||
-- Set departing flag to true
|
||||
isUFODeparting = true
|
||||
|
||||
-- Create new thread specifically for UFO departure
|
||||
Citizen.CreateThread(function()
|
||||
if DoesEntityExist(ufoEntityId) and isCalloutActive then
|
||||
--print("UFO exists and callout is active, beginning departure") -- Debug print
|
||||
|
||||
-- Play UFO departure sounds
|
||||
PlaySoundFrontend(-1, "Object_Dropped_Remote", "GTAO_FM_Events_Soundset", true)
|
||||
|
||||
local ufoStartCoords = GetEntityCoords(ufoEntityId)
|
||||
local ufoEndCoords = vector3(ufoStartCoords.x, ufoStartCoords.y, ufoStartCoords.z + 30.0)
|
||||
local ufoDuration = 8000
|
||||
local ufoStartTime = GetGameTimer()
|
||||
|
||||
while DoesEntityExist(ufoEntityId) and isCalloutActive do
|
||||
local currentTime = GetGameTimer()
|
||||
local timeElapsed = currentTime - ufoStartTime
|
||||
local t = math.min(timeElapsed / ufoDuration, 1.0)
|
||||
|
||||
-- Exponential easing for UFO departure
|
||||
local easedT = t * t
|
||||
|
||||
-- Move UFO up
|
||||
local newZ = lerp(ufoStartCoords.z, ufoEndCoords.z, easedT)
|
||||
--print("Moving UFO - Height: " .. newZ) -- Debug print
|
||||
|
||||
SetEntityCoords(ufoEntityId,
|
||||
ufoStartCoords.x,
|
||||
ufoStartCoords.y,
|
||||
newZ,
|
||||
false, false, false, false)
|
||||
|
||||
if t >= 1.0 then
|
||||
--print("UFO reached max height, cleaning up") -- Debug print
|
||||
TriggerServerEvent("ns_easter_egg:DeleteUFO", ufoNetId)
|
||||
|
||||
-- Small delay before ending callout
|
||||
Wait(1000)
|
||||
|
||||
if lastObject and DoesEntityExist(lastObject) then
|
||||
ERS_DeleteEntityFromCallout(lastObject)
|
||||
end
|
||||
break
|
||||
end
|
||||
|
||||
Wait(0)
|
||||
end
|
||||
end
|
||||
end)
|
||||
else
|
||||
--print("shouldFlyAway flag not set, UFO departure sequence skipped") -- Debug print
|
||||
end
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
||||
ERS_CreateTemporaryBlipForEntities(objectList, 30000)
|
||||
end,
|
||||
server = function(request, src, calloutData, pedList, vehicleList, objectList, propList, playersList, fireList, smokeList)
|
||||
local diameter = 10
|
||||
-- Build objects
|
||||
local alienEggObjects = {"prop_alien_egg_01"}
|
||||
local randomAmountOfObjects = math.random(1, 12)
|
||||
for i = 1, randomAmountOfObjects do
|
||||
local coords = ERS_GetRandomCoordinateWithinRangeOfCoordinate(calloutData.Coordinates, diameter)
|
||||
local objModel = ERS_GetRandomModel(alienEggObjects)
|
||||
local objCoords = vector3(coords.x, coords.y, coords.z+2.0)
|
||||
local objHeading = math.random(360)
|
||||
local objNetId = ERS_CreateObject(objModel, objCoords, objHeading)
|
||||
if objNetId then
|
||||
local obj = NetworkGetEntityFromNetworkId(objNetId)
|
||||
table.insert(objectList, objNetId)
|
||||
else
|
||||
DebugPrint("^1ERROR ^7Could not create object: "..objModel)
|
||||
end
|
||||
end
|
||||
|
||||
-- Create smoke (Optionally)
|
||||
-- -- Build a small sized fire
|
||||
-- if UsingSmartFires then
|
||||
-- -- Full version
|
||||
-- -- Build smoke
|
||||
-- local smokeSize = Config.RandomMediumFireOrSmokeSize[math.random(#Config.RandomMediumFireOrSmokeSize)]
|
||||
-- local smokeType = "foggy"
|
||||
-- local smokeId = exports['SmartFires']:CreateSmoke(vector3(calloutData.Coordinates.x, calloutData.Coordinates.y, calloutData.Coordinates.z-0.5), smokeSize, smokeType)
|
||||
-- DebugPrint("Created smoke with ID: "..smokeId)
|
||||
-- table.insert(smokeList, smokeId)
|
||||
-- else
|
||||
-- -- Lite version
|
||||
-- -- Build smoke
|
||||
-- local smokeSize = Config.RandomMediumFireOrSmokeSize[math.random(#Config.RandomMediumFireOrSmokeSize)]
|
||||
-- local smokeType = "normal"
|
||||
-- local smokeId = exports['SmartFiresLite']:CreateSmoke(vector3(calloutData.Coordinates.x, calloutData.Coordinates.y, calloutData.Coordinates.z-0.5), smokeSize, smokeType)
|
||||
-- DebugPrint("Created smoke with ID: "..smokeId)
|
||||
-- table.insert(smokeList, smokeId)
|
||||
-- end
|
||||
|
||||
|
||||
RegisterServerEvent("ns_easter_egg:DeleteUFO")
|
||||
AddEventHandler("ns_easter_egg:DeleteUFO", function(objNetId)
|
||||
local obj = NetworkGetEntityFromNetworkId(objNetId)
|
||||
if DoesEntityExist(obj) then
|
||||
DeleteEntity(obj)
|
||||
end
|
||||
end)
|
||||
|
||||
return true
|
||||
end
|
||||
}
|
||||
@@ -0,0 +1,272 @@
|
||||
|
||||
Config.Callouts["roxwood_race_crash"] = {
|
||||
Enabled = false,
|
||||
CalloutName = "Roxwood GP Race Crash",
|
||||
CalloutDescriptions = {
|
||||
"Reported road traffic collision, further details needed",
|
||||
"Collision involving vehicles, assess scene for safety",
|
||||
"Incident on road reported, extent of damage unclear",
|
||||
"Traffic incident with unknown injuries, approach carefully",
|
||||
"Vehicle collision reported, assistance required",
|
||||
"Accident scene identified, evaluate for emergency response",
|
||||
"Collision on roadway, prioritize safety and assistance",
|
||||
"Traffic incident reported, coordinate response accordingly",
|
||||
"Roadway blocked due to collision, assess for hazards",
|
||||
"Vehicle collision with unspecified injuries, response needed",
|
||||
-- Add more if you like.
|
||||
},
|
||||
CalloutUnitsRequired = {
|
||||
description = "Police, ambulance, fire, tow.",
|
||||
policeRequired = true,
|
||||
ambulanceRequired = true,
|
||||
fireRequired = true,
|
||||
towRequired = true,
|
||||
},
|
||||
CalloutLocations = {
|
||||
[1] = vector3(-2878.8276, 8350.8096, 37.0427),
|
||||
[2] = vector3(-3003.3206, 8421.5879, 37.0592),
|
||||
[3] = vector3(-3262.5945, 8667.0674, 37.1207),
|
||||
[4] = vector3(-3020.7278, 8711.4346, 46.1127),
|
||||
[5] = vector3(-2703.4087, 8518.3428, 44.1534),
|
||||
[6] = vector3(-2239.3889, 8563.3916, 47.5178),
|
||||
[7] = vector3(-2343.6777, 8891.8887, 51.0247),
|
||||
[8] = vector3(-2524.2251, 8750.5879, 45.5379),
|
||||
[9] = vector3(-2624.4514, 8621.4854, 47.0158),
|
||||
[10] = vector3(-2576.6099, 8060.3647, 46.6511),
|
||||
[11] = vector3(-3196.3193, 8153.2676, 47.0967),
|
||||
},
|
||||
PedChanceToFleeFromPlayer = 0, -- Value between 0 and 100 -> 0 is no chance. The lower the less chance.
|
||||
PedChanceToAttackPlayer = 0, -- Value between 0 and 100 -> 0 is no chance. The lower the less chance.
|
||||
PedChanceToSurrender = 0, -- Value between 0 and 100 -> 0 is no chance. The lower the less chance.
|
||||
PedChanceToObtainWeapons = 0, -- Value between 0 and 100 -> 0 is no chance. The lower the less chance.
|
||||
PedActionMinimumTimeoutInMs = 0, -- Milliseconds for the minimum timeout time to start the secondary action listed above.
|
||||
PedActionMaximumTimeoutInMs = 1000, -- Milliseconds for the maximum timeout time to start the secondary action. Must be a higher number than the minimum!
|
||||
PedActionOnNoActionFound = "none", -- When no action of the above options is found. It'll perform this action after the set timeout. Options: "none", "attack", "flee", "surrender"
|
||||
PedWeaponData = { -- The ped will be given one randomly selected weapon (in hand) from these weapons if PedChanceToObtainWeapons passed.
|
||||
"weapon_unarmed", -- Basically none.
|
||||
},
|
||||
client = function(plyPed, pedList, vehicleList, playersList, objectList, propList, fireList, smokeList, calloutDataClient)
|
||||
for index, vehNetId in pairs(vehicleList) do
|
||||
local veh = NetToVeh(vehNetId)
|
||||
if DoesEntityExist(veh) then
|
||||
ERS_RequestNetControlForEntity(veh)
|
||||
ERS_SetRandomDamageToVehicle(veh)
|
||||
end
|
||||
end
|
||||
|
||||
for index, pedNetId in pairs(pedList) do
|
||||
local ped = NetToPed(pedNetId)
|
||||
if DoesEntityExist(ped) then
|
||||
|
||||
ERS_RequestNetControlForEntity(ped)
|
||||
|
||||
local pedCoords = GetEntityCoords(ped)
|
||||
local chanceToSurvive = math.random(0, 1)
|
||||
|
||||
ERS_SetMovementAnimClipSetToPed(ped, "move_m@injured")
|
||||
|
||||
if chanceToSurvive < 1 then
|
||||
-- Dead
|
||||
SetEntityHealth(ped, 0)
|
||||
TaskSetBlockingOfNonTemporaryEvents(ped, true)
|
||||
ERS_ApplyBloodToPed(ped)
|
||||
SetPedKeepTask(ped, true)
|
||||
else
|
||||
-- Alive
|
||||
TaskSetBlockingOfNonTemporaryEvents(ped, true)
|
||||
ERS_SpawnConfiguredWeaponForPed(ped, calloutDataClient)
|
||||
if IsPedInAnyVehicle(ped, false) then
|
||||
TaskLeaveAnyVehicle(ped)
|
||||
Wait(500)
|
||||
end
|
||||
TaskSetBlockingOfNonTemporaryEvents(ped, true)
|
||||
SetPedKeepTask(ped, true)
|
||||
|
||||
ERS_ApplyBloodToPed(ped)
|
||||
|
||||
pedCoords = GetEntityCoords(ped)
|
||||
local bool, safeCoords = GetSafeCoordForPed(pedCoords.x, pedCoords.y, pedCoords.z, true, 16)
|
||||
if bool then
|
||||
if Config.Debug then
|
||||
print("Found safe coord for ped: "..safeCoords)
|
||||
end
|
||||
local xOffset= math.random(-2, 2)
|
||||
local yOffset= math.random(-2, 2)
|
||||
|
||||
if Config.Debug then
|
||||
print("Could not find safe coord for ped: "..safeCoords)
|
||||
end
|
||||
end
|
||||
|
||||
Citizen.SetTimeout(10000, function()
|
||||
if DoesEntityExist(ped) then
|
||||
if not IsPedDeadOrDying(ped, true) then
|
||||
ERS_RequestNetControlForEntity(ped)
|
||||
|
||||
TaskSetBlockingOfNonTemporaryEvents(ped, true)
|
||||
|
||||
local scenario = ERS_SelectRandomWoundedPersonScenario()
|
||||
TaskStartScenarioInPlace(ped, scenario, 0, true)
|
||||
|
||||
ERS_PerformTimedActionOnPed(calloutDataClient, pedList)
|
||||
|
||||
if Config.Debug then
|
||||
print("Blocking off non-temp events for ped at safe coords for ped: "..ped)
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for index, objNetId in pairs(objectList) do
|
||||
local obj = NetToObj(objNetId)
|
||||
if DoesEntityExist(obj) then
|
||||
ERS_RequestNetControlForEntity(obj)
|
||||
PlaceObjectOnGroundProperly(obj)
|
||||
end
|
||||
end
|
||||
|
||||
ERS_CreateTemporaryBlipForEntities(vehicleList, 15000)
|
||||
ERS_CreateTemporaryBlipForEntities(pedList, 15000)
|
||||
end,
|
||||
server = function(request, src, calloutData, pedList, vehicleList, objectList, propList, playersList, fireList, smokeList)
|
||||
local randomAmountOfVehicles = math.random(2,5)
|
||||
local randomAmountOfObjects = math.random(1,5)
|
||||
local randomAmountOfFires = math.random(1,3)
|
||||
local racePedModels = {
|
||||
"ig_trafficwarden", "player_zero", "ig_agatha",
|
||||
"hc_driver", "hc_gunman", "hc_hacker", "ig_abigail", "ig_agent",
|
||||
"ig_amandatownley", "ig_andreas", "ig_ashley", "ig_avon", "ig_ballasog",
|
||||
"ig_bankman", "ig_barry", "ig_benny", "ig_bestmen", "ig_beverly",
|
||||
"ig_brad", "ig_bride", "ig_car3guy1", "ig_car3guy2", "ig_casey",
|
||||
"ig_chef", "ig_chef2", "ig_chengsr", "ig_chrisformage", "ig_clay",
|
||||
"ig_claypain", "ig_cletus", "ig_dale", "ig_davenorton", "ig_denise",
|
||||
"ig_devin", "ig_dix", "ig_djblamadon", "ig_djblamrupert", "ig_djblamryans",
|
||||
"ig_djdixmanager", "ig_djgeneric_01", "ig_djsolfotios", "ig_djsoljakob",
|
||||
"ig_djsolmanager", "ig_djsolmike", "ig_djsolrobt", "ig_djtalaurelia",
|
||||
"ig_djtalignazio", "ig_dom", "ig_dreyfuss", "ig_drfriedlander",
|
||||
"ig_englishdave", "ig_fabien", "ig_fbisuit_01", "ig_floyd", "ig_g",
|
||||
"ig_groom", "ig_hao", "ig_hunter", "ig_janet", "ig_jay_norris",
|
||||
"ig_jewelass", "ig_jimmyboston", "ig_jimmyboston_02", "ig_jimmydisanto",
|
||||
"ig_joeminuteman", "ig_johnnyklebitz", "ig_josef", "ig_josh",
|
||||
"ig_karen_daniels", "ig_kerrymcintosh", "ig_kerrymcintosh_02",
|
||||
"ig_lacey_jones_02", "ig_lamardavis", "ig_lazlow", "ig_lazlow_2",
|
||||
"ig_lestercrest", "ig_lestercrest_2", "ig_lifeinvad_01", "ig_lifeinvad_02",
|
||||
"ig_magenta", "ig_malc", "ig_manuel", "ig_marnie", "ig_maryann",
|
||||
"ig_maude", "ig_michelle", "ig_milton", "ig_molly", "ig_money",
|
||||
"ig_mp_agent14", "ig_mrk", "ig_mrs_thornhill", "ig_mrsphillips",
|
||||
"ig_natalia", "ig_nervousron", "ig_nigel", "ig_old_man1a", "ig_old_man2",
|
||||
"ig_omega", "ig_oneil", "ig_orleans", "ig_ortega", "ig_paige", "ig_paper",
|
||||
"ig_patricia", "ig_popov", "ig_priest", "ig_prolsec_02", "ig_ramp_gang",
|
||||
"ig_ramp_hic", "ig_ramp_hipster", "ig_ramp_mex", "ig_rashcosvki",
|
||||
"ig_roccopelosi", "ig_russiandrunk", "ig_sacha", "ig_screen_writer",
|
||||
"ig_siemonyetarian", "ig_sol", "ig_solomon", "ig_stevehains", "ig_stretch",
|
||||
"ig_talcc", "ig_talina", "ig_talmm", "ig_tanisha", "ig_taocheng",
|
||||
"ig_taostranslator", "ig_tenniscoach", "ig_terry", "ig_tomepsilon",
|
||||
"ig_tonya", "ig_tonyprince", "ig_tracydisanto", "ig_trafficwarden",
|
||||
"ig_tylerdix", "ig_tylerdix_02", "ig_vagspeak", "ig_wade", "ig_zimbor",
|
||||
"player_one", "player_two", "player_zero", "ig_agatha", "ig_avery",
|
||||
"ig_brucie2", "ig_thornton", "ig_tomcasino", "ig_vincent"
|
||||
}
|
||||
local vehRaceModels = {"formula", "formula2", "openwheel1", "openwheel2"}
|
||||
local carPartObjects = {"prop_car_battery_01", "prop_car_exhaust_01", "prop_rub_carpart_04", "prop_rub_carpart_05", "prop_car_engine_01"}
|
||||
local diameter = 20
|
||||
|
||||
-- Car race or motorbike race chance
|
||||
local carRaceChance = math.random(0, 1)
|
||||
local vehType = "automobile"
|
||||
if carRaceChance == 0 then
|
||||
-- motorbike race
|
||||
vehRaceModels = {"bati2"}
|
||||
vehType = "bike"
|
||||
end
|
||||
|
||||
-- Build entities
|
||||
for i = 1, randomAmountOfVehicles do
|
||||
local coords = ERS_GetRandomCoordinateWithinRangeOfCoordinate(calloutData.Coordinates, diameter)
|
||||
|
||||
-- Build vehicle
|
||||
local vehModel = ERS_GetRandomModel(vehRaceModels)
|
||||
local vehCoords = vector3(coords.x, coords.y, coords.z)
|
||||
local vehHeading = math.random(360)
|
||||
local vehNetId = ERS_CreateVehicle(vehModel, vehType, vehCoords, vehHeading)
|
||||
local vehicle = NetworkGetEntityFromNetworkId(vehNetId)
|
||||
table.insert(vehicleList, vehNetId)
|
||||
|
||||
-- Build ped
|
||||
coords = ERS_GetRandomCoordinateWithinRangeOfCoordinate(calloutData.Coordinates, diameter)
|
||||
|
||||
local pedModel = ERS_GetRandomModel(racePedModels)
|
||||
local pedCoords = vector3(coords.x, coords.y, coords.z)
|
||||
local pedHeading = math.random(360)
|
||||
local pedNetId = ERS_CreatePed(pedModel, pedCoords, pedHeading)
|
||||
local ped = NetworkGetEntityFromNetworkId(pedNetId)
|
||||
SetPedIntoVehicle(ped, vehicle, -1)
|
||||
table.insert(pedList, pedNetId)
|
||||
|
||||
-- Break vehicle
|
||||
SetVehicleBodyHealth(vehicle, (math.random(1000) + 0.0))
|
||||
for i = 0, 5 do
|
||||
local broken = math.random(0, 1)
|
||||
if broken == 1 then
|
||||
SetVehicleDoorBroken(vehicle, i, false)
|
||||
end
|
||||
SetVehicleDirtLevel(vehicle, math.random(15) + 0.0)
|
||||
end
|
||||
end
|
||||
|
||||
-- Build objects
|
||||
for i = 1, randomAmountOfObjects do
|
||||
local coords = ERS_GetRandomCoordinateWithinRangeOfCoordinate(calloutData.Coordinates, diameter)
|
||||
|
||||
local objModel = ERS_GetRandomModel(carPartObjects)
|
||||
local objCoords = vector3(coords.x, coords.y, coords.z)
|
||||
local objHeading = math.random(360)
|
||||
local objNetId = ERS_CreateObject(objModel, objCoords, objHeading)
|
||||
if objNetId then
|
||||
local obj = NetworkGetEntityFromNetworkId(objNetId)
|
||||
table.insert(objectList, objNetId)
|
||||
else
|
||||
DebugPrint("^1ERROR ^7Could not create object: "..objModel)
|
||||
end
|
||||
end
|
||||
|
||||
for i = 1, randomAmountOfFires do
|
||||
local coords = ERS_GetRandomCoordinateWithinRangeOfCoordinate(calloutData.Coordinates, diameter)
|
||||
if UsingSmartFires then
|
||||
-- Full version
|
||||
local fireSize = Config.RandomLargeFireOrSmokeSize[math.random(#Config.RandomLargeFireOrSmokeSize)]
|
||||
local fireType = Config.NormalFireTypes[math.random(#Config.NormalFireTypes)]
|
||||
local fireId = exports['SmartFires']:CreateFire(vector3(coords.x, coords.y, coords.z+0.6), fireSize, fireType)
|
||||
DebugPrint("Created fire with ID: "..fireId)
|
||||
table.insert(fireList, fireId)
|
||||
|
||||
local smokeSize = Config.RandomMediumFireOrSmokeSize[math.random(#Config.RandomMediumFireOrSmokeSize)]
|
||||
local smokeType = Config.AllSmokeTypes[math.random(#Config.AllSmokeTypes)]
|
||||
local smokeId = exports['SmartFires']:CreateSmoke(vector3(coords.x, coords.y, coords.z-0.5), smokeSize, smokeType)
|
||||
DebugPrint("Created smoke particle with ID: "..smokeId)
|
||||
table.insert(smokeList, smokeId)
|
||||
else
|
||||
local chanceToCreateSmoke = math.random(0, 1) -- 50% chance to create smoke
|
||||
if chanceToCreateSmoke == 1 then
|
||||
-- Lite version
|
||||
local fireSize = Config.RandomLargeFireOrSmokeSize[math.random(#Config.RandomLargeFireOrSmokeSize)]
|
||||
local fireType = "normal"
|
||||
local fireId = exports['SmartFiresLite']:CreateFire(vector3(coords.x, coords.y, coords.z+0.6), fireSize, fireType)
|
||||
DebugPrint("Created fire with SmartFiresLite with ID: "..fireId)
|
||||
table.insert(fireList, fireId)
|
||||
|
||||
local smokeSize = Config.RandomMediumFireOrSmokeSize[math.random(#Config.RandomMediumFireOrSmokeSize)]
|
||||
local smokeType = "normal"
|
||||
local smokeId = exports['SmartFiresLite']:CreateSmoke(vector3(coords.x, coords.y, coords.z-0.5), smokeSize, smokeType)
|
||||
DebugPrint("Created smoke particle with ID: "..smokeId)
|
||||
table.insert(smokeList, smokeId)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
Config.Callouts["roxwood_racecar_theft"] = {
|
||||
Enabled = false,
|
||||
CalloutName = "Theft of a Racecar",
|
||||
CalloutDescriptions = {
|
||||
"High-performance racecar reported stolen from local track, immediate response required",
|
||||
"Professional racing vehicle theft in progress, suspect may be armed and dangerous",
|
||||
"Modified racing vehicle stolen during event preparations, high-value target",
|
||||
"Competition racecar reported missing from secured garage area",
|
||||
"Emergency: High-speed capable vehicle theft from racing complex",
|
||||
"Urgent: Racing team reports theft of competition vehicle, suspect fleeing area",
|
||||
"Track security reports unauthorized removal of professional racing vehicle",
|
||||
"High-priority: Racing prototype stolen, vehicle extremely valuable",
|
||||
"Alert: Competition vehicle theft from pit area, immediate response needed",
|
||||
"Racing team reports forced entry and theft of performance vehicle",
|
||||
},
|
||||
CalloutUnitsRequired = {
|
||||
description = "Police.",
|
||||
policeRequired = true,
|
||||
ambulanceRequired = false,
|
||||
fireRequired = false,
|
||||
towRequired = false,
|
||||
},
|
||||
CalloutLocations = {
|
||||
[1] = vector3(-2901.6108, 8056.7153, 44.8517),
|
||||
[2] = vector3(-2737.1699, 8028.4966, 49.4163),
|
||||
[3] = vector3(-2969.1304, 7983.6553, 44.8298),
|
||||
},
|
||||
PedChanceToFleeFromPlayer = 90, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedChanceToAttackPlayer = 10, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedChanceToSurrender = 10, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedChanceToObtainWeapons = 25, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedActionMinimumTimeoutInMs = 0, -- Milliseconds for the minimum timeout time to start the secondary action listed above.
|
||||
PedActionMaximumTimeoutInMs = 2000, -- Milliseconds for the maximum timeout time to start the secondary action. Must be a higher number than the minimum!
|
||||
PedActionOnNoActionFound = "flee", -- When no action of the above options is found. It'll perform this action after the set timeout. Options: "none", "attack", "flee", "surrender"
|
||||
PedWeaponData = { -- The ped will be given one randomly selected weapon (in hand) from these weapons if PedChanceToObtainWeapons passed.
|
||||
"weapon_knife",
|
||||
"weapon_pistol",
|
||||
},
|
||||
client = function(plyPed, pedList, vehicleList, playersList, objectList, propList, fireList, smokeList, calloutDataClient)
|
||||
local vehicle = nil
|
||||
local driver = nil
|
||||
|
||||
for index, vehNetId in pairs(vehicleList) do
|
||||
local veh = NetToVeh(vehNetId)
|
||||
if DoesEntityExist(veh) then
|
||||
vehicle = veh
|
||||
ERS_RequestNetControlForEntity(vehicle)
|
||||
end
|
||||
end
|
||||
|
||||
for index, pedNetId in pairs(pedList) do
|
||||
local ped = NetToPed(pedNetId)
|
||||
if DoesEntityExist(ped) then
|
||||
driver = ped
|
||||
ERS_RequestNetControlForEntity(driver)
|
||||
if not IsPedOnAnyBike(driver) then
|
||||
SmashVehicleWindow(vehicle, 0) -- break driver window
|
||||
end
|
||||
if not IsPedInAnyVehicle(driver, true) then
|
||||
TaskEnterVehicle(driver, vehicle, 5000, -1, 2.0, 1, 0)
|
||||
Wait(5000)
|
||||
ERS_SetPedToFleeFromPlayer(driver)
|
||||
else
|
||||
ERS_SetPedToFleeFromPlayer(driver)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ERS_CreateTemporaryBlipForEntities(vehicleList, 15000)
|
||||
ERS_CreateTemporaryBlipForEntities(pedList, 15000)
|
||||
|
||||
ERS_PerformTimedActionOnPed(calloutDataClient, pedList)
|
||||
end,
|
||||
server = function(request, src, calloutData, pedList, vehicleList, objectList, propList, playersList, fireList, smokeList)
|
||||
-- Build vehicle
|
||||
local vehRaceModels = {"formula", "formula2", "openwheel1", "openwheel2"}
|
||||
local vehModel = ERS_GetRandomModel(vehRaceModels)
|
||||
local vehType = "automobile"
|
||||
local vehCoords = vector3(calloutData.Coordinates.x, calloutData.Coordinates.y, calloutData.Coordinates.z)
|
||||
local vehHeading = math.random(360)
|
||||
local vehNetId = ERS_CreateVehicle(vehModel, vehType, vehCoords, vehHeading)
|
||||
local vehicle = NetworkGetEntityFromNetworkId(vehNetId)
|
||||
table.insert(vehicleList, vehNetId)
|
||||
|
||||
-- Build ped
|
||||
local pedModel = ERS_GetRandomModel(Config.randomPeds)
|
||||
local pedCoords = vector3(calloutData.Coordinates.x, calloutData.Coordinates.y, calloutData.Coordinates.z +1.0)
|
||||
local pedHeading = math.random(360)
|
||||
local pedNetId = ERS_CreatePed(pedModel, pedCoords, pedHeading)
|
||||
local ped = NetworkGetEntityFromNetworkId(pedNetId)
|
||||
SetPedIntoVehicle(ped, vehicle, -1)
|
||||
table.insert(pedList, pedNetId)
|
||||
|
||||
calloutBuilt = true
|
||||
|
||||
return true
|
||||
end
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
Config.Callouts["roxwood_reports_of_a_fire"] = {
|
||||
|
||||
Enabled = true,
|
||||
CalloutName = "Reports of a Fire",
|
||||
CalloutDescriptions = {
|
||||
"A fire has been reported, requiring immediate attention from fire services.",
|
||||
"Emergency services are needed to extinguish a reported fire.",
|
||||
"Reports indicate a fire has broken out, necessitating urgent firefighting intervention.",
|
||||
"A fire has been identified, and additional fire personnel are needed for containment and extinguishment.",
|
||||
"Emergency services have been requested to respond to a fire.",
|
||||
"A request for assistance has been made by authorities dealing with a fire.",
|
||||
"Additional units are required to support fire personnel managing a fire.",
|
||||
"Emergency backup is required to assist fire authorities in handling a fire.",
|
||||
"A call for assistance has been issued by responders dealing with a fire.",
|
||||
"Reports suggest a situation where immediate firefighting intervention is crucial to manage and address a fire.",
|
||||
},
|
||||
CalloutUnitsRequired = {
|
||||
description = "Fire",
|
||||
policeRequired = false,
|
||||
ambulanceRequired = false,
|
||||
fireRequired = true,
|
||||
towRequired = false,
|
||||
},
|
||||
CalloutLocations = {
|
||||
[1] = vector3(-2542.1089, 7467.2939, 40.1682),
|
||||
[2] = vector3(-2070.9167, 7103.6870, 28.5290),
|
||||
[3] = vector3(-2680.5420, 6456.3721, 28.7906),
|
||||
[4] = vector3(-2660.3013, 6341.2979, 20.9317),
|
||||
[5] = vector3(-2920.7075, 6240.0674, 12.7980),
|
||||
[6] = vector3(-2785.6145, 6105.6709, 7.2804),
|
||||
[7] = vector3(-2989.0220, 6141.8804, 4.8758),
|
||||
[8] = vector3(-3029.2122, 6094.7715, 16.5621),
|
||||
[9] = vector3(-3289.9795, 6187.9121, 13.7178),
|
||||
[10] = vector3(-3068.1689, 7862.0122, 59.1986),
|
||||
[11] = vector3(-2314.8447, 7807.0688, 38.4255),
|
||||
[12] = vector3(-2306.9417, 7822.5352, 44.2124),
|
||||
[13] = vector3(-2163.0261, 7998.2568, 44.3750),
|
||||
[14] = vector3(-2207.9578, 8031.9858, 44.2027),
|
||||
[15] = vector3(-2274.9910, 8146.1890, 34.1373),
|
||||
[16] = vector3(-1290.7288, 8218.0352, 12.9399),
|
||||
[17] = vector3(-606.0902, 7564.0142, 11.6405),
|
||||
[18] = vector3(-833.0021, 7150.1865, 104.5681),
|
||||
[19] = vector3(-380.6089, 7202.0557, 18.2214),
|
||||
[20] = vector3(-455.5331, 7737.0986, 6.2801),
|
||||
[21] = vector3(193.0212, 7768.1797, 6.4081),
|
||||
},
|
||||
PedChanceToFleeFromPlayer = 0, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedChanceToAttackPlayer = 0, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedChanceToSurrender = 0, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedChanceToObtainWeapons = 0, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedActionMinimumTimeoutInMs = 0, -- Milliseconds for the minimum timeout time to start the secondary action listed above.
|
||||
PedActionMaximumTimeoutInMs = 1000, -- Milliseconds for the maximum timeout time to start the secondary action. Must be a higher number than the minimum!
|
||||
PedActionOnNoActionFound = "none", -- When no action of the above options is found. It'll perform this action after the set timeout. Options: "none", "attack", "flee", "surrender"
|
||||
PedWeaponData = { -- The ped will be given one randomly selected weapon (in hand) from these weapons if PedChanceToObtainWeapons passed.
|
||||
"weapon_unarmed",
|
||||
},
|
||||
|
||||
client = function(plyPed, pedList, vehicleList, playersList, objectList, propList, fireList, smokeList, calloutDataClient)
|
||||
|
||||
for index, pedNetId in pairs(pedList) do
|
||||
local ped = NetToPed(pedNetId)
|
||||
if DoesEntityExist(ped) then
|
||||
ERS_RequestNetControlForEntity(ped)
|
||||
TaskSetBlockingOfNonTemporaryEvents(ped, true)
|
||||
PlayPain(ped, 8, 200)
|
||||
ERS_ApplyBloodToPed(ped)
|
||||
Wait(2500)
|
||||
SetEntityHealth(ped, 0)
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
ERS_CreateTemporaryBlipForEntities(pedList, 15000)
|
||||
|
||||
ERS_PerformTimedActionOnPed(calloutDataClient, pedList)
|
||||
|
||||
end,
|
||||
server = function(request, src, calloutData, pedList, vehicleList, objectList, propList, playersList, fireList, smokeList)
|
||||
|
||||
local diameter = 2
|
||||
local coords = ERS_GetRandomCoordinateWithinRangeOfCoordinate(calloutData.Coordinates, diameter)
|
||||
|
||||
-- Build a small sized fire
|
||||
if UsingSmartFires then
|
||||
-- Full version
|
||||
local fireSize = Config.RandomMediumFireOrSmokeSize[math.random(#Config.RandomMediumFireOrSmokeSize)]
|
||||
local fireType = Config.NormalFireTypes[math.random(#Config.NormalFireTypes)]
|
||||
local fireId = exports['SmartFires']:CreateFire(vector3(calloutData.Coordinates.x, calloutData.Coordinates.y, calloutData.Coordinates.z-0.5), fireSize, fireType)
|
||||
DebugPrint("Created fire with ID: "..fireId)
|
||||
table.insert(fireList, fireId)
|
||||
|
||||
-- Build smoke
|
||||
local chanceOnASmoke = 50
|
||||
if math.random(1, 100) <= chanceOnASmoke then
|
||||
local smokeSize = Config.RandomMediumFireOrSmokeSize[math.random(#Config.RandomMediumFireOrSmokeSize)]
|
||||
local smokeType = Config.AllSmokeTypes[math.random(#Config.AllSmokeTypes)]
|
||||
local smokeId = exports['SmartFires']:CreateSmoke(vector3(calloutData.Coordinates.x, calloutData.Coordinates.y, calloutData.Coordinates.z-0.5), smokeSize, smokeType)
|
||||
|
||||
DebugPrint("Created smoke with ID: "..smokeId)
|
||||
table.insert(smokeList, smokeId)
|
||||
end
|
||||
else
|
||||
-- Lite version
|
||||
local fireSize = Config.RandomSmallFireOrSmokeSize[math.random(#Config.RandomSmallFireOrSmokeSize)]
|
||||
local fireType = "normal"
|
||||
local fireId = exports['SmartFiresLite']:CreateFire(vector3(calloutData.Coordinates.x, calloutData.Coordinates.y, calloutData.Coordinates.z-0.5), fireSize, fireType)
|
||||
DebugPrint("Created fire with SmartFiresLite with ID: "..fireId)
|
||||
table.insert(fireList, fireId)
|
||||
|
||||
-- Build smoke
|
||||
local chanceOnASmoke = 50
|
||||
if math.random(1, 100) <= chanceOnASmoke then
|
||||
local smokeSize = Config.RandomMediumFireOrSmokeSize[math.random(#Config.RandomMediumFireOrSmokeSize)]
|
||||
local smokeType = "normal"
|
||||
local smokeId = exports['SmartFiresLite']:CreateSmoke(vector3(calloutData.Coordinates.x, calloutData.Coordinates.y, calloutData.Coordinates.z-0.5), smokeSize, smokeType)
|
||||
|
||||
DebugPrint("Created smoke with ID: "..smokeId)
|
||||
table.insert(smokeList, smokeId)
|
||||
end
|
||||
end
|
||||
|
||||
local chanceOnAVictim = 50
|
||||
if math.random(1, 100) <= chanceOnAVictim then
|
||||
-- Build victim
|
||||
local pedModel = ERS_GetRandomModel(Config.randomPeds)
|
||||
local pedCoords = vector3(coords.x, coords.y, coords.z)
|
||||
local pedHeading = math.random(360)
|
||||
local pedNetId = ERS_CreatePed(pedModel, pedCoords, pedHeading)
|
||||
local ped = NetworkGetEntityFromNetworkId(pedNetId)
|
||||
table.insert(pedList, pedNetId)
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
Config.Callouts["roxwood_reports_of_theft"] = {
|
||||
Enabled = false,
|
||||
CalloutName = "Reports of Theft",
|
||||
CalloutDescriptions = {
|
||||
"Reports of theft, details pending",
|
||||
"Suspected theft reported, further information needed",
|
||||
"Incident involving stolen vehicle, assess situation for safety",
|
||||
"Theft reported, prioritize response for recovery",
|
||||
"Reported theft of motor vehicle, investigate promptly",
|
||||
"Vehicle reported missing, coordinate search and recovery efforts",
|
||||
"Stolen reported, assess potential risks",
|
||||
"Suspected theft of vehicle, approach investigation with caution",
|
||||
"Reports of theft, prioritize response for recovery",
|
||||
"Theft incident reported, coordinate with authorities",
|
||||
},
|
||||
CalloutUnitsRequired = {
|
||||
description = "Police.",
|
||||
policeRequired = true,
|
||||
ambulanceRequired = false,
|
||||
fireRequired = false,
|
||||
towRequired = false,
|
||||
},
|
||||
CalloutLocations = {
|
||||
[1] = vector3(-906.1519, 6810.3047, 21.3176),
|
||||
[2] = vector3(-641.7461, 6866.0830, 24.2095),
|
||||
[3] = vector3(-629.4213, 6988.1577, 24.3153),
|
||||
[4] = vector3(-540.8360, 6718.5483, 21.2485),
|
||||
[5] = vector3(-263.4102, 7058.8438, 12.0184),
|
||||
[6] = vector3(-302.9133, 7167.9888, 6.3294),
|
||||
[7] = vector3(-289.1859, 7225.0986, 6.3294),
|
||||
[8] = vector3(-216.6804, 7675.9102, 6.3277),
|
||||
[9] = vector3(-1288.2164, 8249.0859, 12.0572),
|
||||
[10] = vector3(-2238.5459, 8170.4370, 33.1580),
|
||||
[11] = vector3(-2554.0913, 7474.7725, 28.6994),
|
||||
[12] = vector3(-3058.3174, 7338.7568, 44.0336),
|
||||
[13] = vector3(-3067.8191, 6315.9731, 8.8898),
|
||||
[14] = vector3(-2989.0806, 6175.4121, 8.4440),
|
||||
[15] = vector3(-3684.9780, 6187.1943, 24.5932),
|
||||
[16] = vector3(-3096.2888, 6538.0146, 23.5485),
|
||||
},
|
||||
PedChanceToFleeFromPlayer = 90, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedChanceToAttackPlayer = 10, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedChanceToSurrender = 10, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedChanceToObtainWeapons = 25, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedActionMinimumTimeoutInMs = 0, -- Milliseconds for the minimum timeout time to start the secondary action listed above.
|
||||
PedActionMaximumTimeoutInMs = 2000, -- Milliseconds for the maximum timeout time to start the secondary action. Must be a higher number than the minimum!
|
||||
PedActionOnNoActionFound = "flee", -- When no action of the above options is found. It'll perform this action after the set timeout. Options: "none", "attack", "flee", "surrender"
|
||||
PedWeaponData = { -- The ped will be given one randomly selected weapon (in hand) from these weapons if PedChanceToObtainWeapons passed.
|
||||
"weapon_knife",
|
||||
"weapon_pistol",
|
||||
},
|
||||
client = function(plyPed, pedList, vehicleList, playersList, objectList, propList, fireList, smokeList, calloutDataClient)
|
||||
local vehicle = nil
|
||||
local driver = nil
|
||||
|
||||
for index, vehNetId in pairs(vehicleList) do
|
||||
local veh = NetToVeh(vehNetId)
|
||||
if DoesEntityExist(veh) then
|
||||
vehicle = veh
|
||||
ERS_RequestNetControlForEntity(vehicle)
|
||||
end
|
||||
end
|
||||
|
||||
for index, pedNetId in pairs(pedList) do
|
||||
local ped = NetToPed(pedNetId)
|
||||
if DoesEntityExist(ped) then
|
||||
driver = ped
|
||||
ERS_RequestNetControlForEntity(driver)
|
||||
if not IsPedOnAnyBike(driver) then
|
||||
SmashVehicleWindow(vehicle, 0) -- break driver window
|
||||
end
|
||||
if not IsPedInAnyVehicle(driver, true) then
|
||||
TaskEnterVehicle(driver, vehicle, 5000, -1, 2.0, 1, 0)
|
||||
Wait(5000)
|
||||
ERS_SetPedToFleeFromPlayer(driver)
|
||||
else
|
||||
ERS_SetPedToFleeFromPlayer(driver)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ERS_CreateTemporaryBlipForEntities(vehicleList, 15000)
|
||||
ERS_CreateTemporaryBlipForEntities(pedList, 15000)
|
||||
|
||||
ERS_PerformTimedActionOnPed(calloutDataClient, pedList)
|
||||
end,
|
||||
server = function(request, src, calloutData, pedList, vehicleList, objectList, propList, playersList, fireList, smokeList)
|
||||
-- Build vehicle
|
||||
local vehModel = ERS_GetRandomModel(Config.randomVehicles)
|
||||
local vehType = "automobile"
|
||||
local vehCoords = vector3(calloutData.Coordinates.x, calloutData.Coordinates.y, calloutData.Coordinates.z)
|
||||
local vehHeading = math.random(360)
|
||||
local vehNetId = ERS_CreateVehicle(vehModel, vehType, vehCoords, vehHeading)
|
||||
local vehicle = NetworkGetEntityFromNetworkId(vehNetId)
|
||||
table.insert(vehicleList, vehNetId)
|
||||
|
||||
-- Build ped
|
||||
local pedModel = ERS_GetRandomModel(Config.randomPeds)
|
||||
local pedCoords = vector3(calloutData.Coordinates.x, calloutData.Coordinates.y, calloutData.Coordinates.z +1.0)
|
||||
local pedHeading = math.random(360)
|
||||
local pedNetId = ERS_CreatePed(pedModel, pedCoords, pedHeading)
|
||||
local ped = NetworkGetEntityFromNetworkId(pedNetId)
|
||||
SetPedIntoVehicle(ped, vehicle, -1)
|
||||
table.insert(pedList, pedNetId)
|
||||
|
||||
calloutBuilt = true
|
||||
|
||||
return true
|
||||
end
|
||||
}
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
Config.Callouts["roxwood_rubbish_washed_up_from_sea"] = {
|
||||
|
||||
Enabled = true,
|
||||
CalloutName = "Rubbish washed up from the sea",
|
||||
CalloutDescriptions = {
|
||||
"Emergency: respond to reports of debris washed up on the shoreline; assess environmental hazards.",
|
||||
"Urgent alert: marine debris reported on the beach requiring immediate cleanup response.",
|
||||
"Critical response required: investigate reports of sea waste washing up on the coast.",
|
||||
"Notice: significant amount of marine debris has washed ashore; environmental assessment needed.",
|
||||
"Alert: respond to reports of ocean waste on the beach; evaluate potential hazards.",
|
||||
"Incident reported: sea debris has washed up on the shoreline requiring immediate attention.",
|
||||
"Immediate action: address reports of marine waste on the beach; assess environmental impact.",
|
||||
"Situation alert: coastal cleanup needed for debris washed up from the ocean.",
|
||||
"Emergency response: handle reports of sea waste on the shoreline; ensure public safety.",
|
||||
"Response needed: investigate reports of marine debris washed ashore; assess and coordinate cleanup.",
|
||||
},
|
||||
CalloutUnitsRequired = {
|
||||
description = "Police, fire.",
|
||||
policeRequired = true,
|
||||
ambulanceRequired = false,
|
||||
fireRequired = true,
|
||||
towRequired = false,
|
||||
},
|
||||
CalloutLocations = {
|
||||
[1] = vector3(-176.0005, 7555.7231, 2.0013),
|
||||
[2] = vector3(-229.1338, 7345.6353, 4.2200),
|
||||
[3] = vector3(-3411.0190, 6075.2427, 2.6527),
|
||||
[4] = vector3(-783.9731, 6659.8804, 2.3201),
|
||||
[5] = vector3(-328.8283, 6974.1064, 2.4945),
|
||||
},
|
||||
PedChanceToFleeFromPlayer = 0, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedChanceToAttackPlayer = 0, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedChanceToSurrender = 0, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedChanceToObtainWeapons = 0, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedActionMinimumTimeoutInMs = 0, -- Milliseconds for the minimum timeout time to start the secondary action listed above.
|
||||
PedActionMaximumTimeoutInMs = 1000, -- Milliseconds for the maximum timeout time to start the secondary action. Must be a higher number than the minimum!
|
||||
PedActionOnNoActionFound = "none", -- When no action of the above options is found. It'll perform this action after the set timeout. Options: "none", "attack", "flee", "surrender"
|
||||
PedWeaponData = { -- The ped will be given one randomly selected weapon (in hand) from these weapons if PedChanceToObtainWeapons passed.
|
||||
"weapon_unarmed",
|
||||
},
|
||||
|
||||
client = function(plyPed, pedList, vehicleList, playersList, objectList, propList, fireList, smokeList, calloutDataClient)
|
||||
for index, objNetId in pairs(objectList) do
|
||||
local obj = NetToObj(objNetId)
|
||||
if DoesEntityExist(obj) then
|
||||
ERS_RequestNetControlForEntity(obj)
|
||||
PlaceObjectOnGroundProperly(obj)
|
||||
end
|
||||
end
|
||||
ERS_CreateTemporaryBlipForEntities(objectList, 30000)
|
||||
end,
|
||||
server = function(request, src, calloutData, pedList, vehicleList, objectList, propList, playersList, fireList, smokeList)
|
||||
local diameter = 10
|
||||
-- Build objects
|
||||
local rubbishObjects = {"prop_rub_buswreck_01", "prop_rub_carwreck_10", "prop_rub_carwreck_13", "prop_rub_pile_01", "prop_pile_dirt_04", "prop_pile_dirt_02", "prop_rub_buswreck_03", "prop_wrecked_buzzard"}
|
||||
local randomAmountOfObjects = math.random(1, 6)
|
||||
for i = 1, randomAmountOfObjects do
|
||||
local coords = ERS_GetRandomCoordinateWithinRangeOfCoordinate(calloutData.Coordinates, diameter)
|
||||
local objModel = ERS_GetRandomModel(rubbishObjects)
|
||||
local objCoords = vector3(coords.x, coords.y, coords.z+2.0)
|
||||
local objHeading = math.random(360)
|
||||
local objNetId = ERS_CreateObject(objModel, objCoords, objHeading)
|
||||
if objNetId then
|
||||
local obj = NetworkGetEntityFromNetworkId(objNetId)
|
||||
table.insert(objectList, objNetId)
|
||||
else
|
||||
DebugPrint("^1ERROR ^7Could not create object: "..objModel)
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
Config.Callouts["roxwood_shootout"] = {
|
||||
Enabled = true,
|
||||
CalloutName = "Roxwood Shootout",
|
||||
CalloutDescriptions = {
|
||||
"A violent shootout has erupted between two rival groups in Roxwood.",
|
||||
"Reports of gunfire exchanged between two factions, immediate response required.",
|
||||
"A shootout is underway in Roxwood, with multiple armed individuals involved.",
|
||||
"Two rival gangs are engaged in a firefight, posing a threat to public safety.",
|
||||
"Gunfire reported in Roxwood as two groups clash violently.",
|
||||
"Emergency services needed to contain a shootout between two armed groups.",
|
||||
"A dangerous shootout is occurring, requiring swift intervention from authorities.",
|
||||
"Two factions are exchanging gunfire, escalating tensions in the area.",
|
||||
"A shootout has broken out, with both sides heavily armed.",
|
||||
"Immediate action required to control a shootout between rival groups.",
|
||||
},
|
||||
CalloutUnitsRequired = {
|
||||
description = "Police.",
|
||||
policeRequired = true,
|
||||
ambulanceRequired = false,
|
||||
fireRequired = false,
|
||||
towRequired = false,
|
||||
},
|
||||
CalloutLocations = {
|
||||
[1] = vector3(-829.9780, 7158.2388, 99.7499),
|
||||
[2] = vector3(-455.7968, 7240.3081, 17.5236),
|
||||
[3] = vector3(-357.8293, 7197.4155, 6.3290),
|
||||
[4] = vector3(-362.7209, 7389.6875, 6.4129),
|
||||
[5] = vector3(-537.7283, 7538.1699, 6.7560),
|
||||
},
|
||||
PedChanceToFleeFromPlayer = 0, -- Lower chance to flee during a shootout.
|
||||
PedChanceToAttackPlayer = 100, -- High chance to attack during a shootout.
|
||||
PedChanceToSurrender = 0, -- No surrender during a shootout.
|
||||
PedChanceToObtainWeapons = 100, -- Ensure all peds are armed.
|
||||
PedActionMinimumTimeoutInMs = 0, -- Milliseconds for the minimum timeout time to start the secondary action listed above.
|
||||
PedActionMaximumTimeoutInMs = 1000, -- Milliseconds for the maximum timeout time to start the secondary action. Must be a higher number than the minimum!
|
||||
PedActionOnNoActionFound = "attack", -- When no action of the above options is found. It'll perform this action after the set timeout. Options: "none", "attack", "flee", "surrender"
|
||||
PedWeaponData = { -- Weapons for the shootout.
|
||||
"weapon_pistol",
|
||||
"weapon_smg",
|
||||
"weapon_assaultrifle",
|
||||
},
|
||||
|
||||
client = function(plyPed, pedList, vehicleList, playersList, objectList, propList, fireList, smokeList, calloutDataClient)
|
||||
local team1 = {}
|
||||
local team2 = {}
|
||||
|
||||
for index, pedNetId in pairs(pedList) do
|
||||
local ped = NetToPed(pedNetId)
|
||||
if DoesEntityExist(ped) then
|
||||
ERS_RequestNetControlForEntity(ped)
|
||||
local model = GetEntityModel(ped)
|
||||
|
||||
-- Randomly assign peds to one of the two teams
|
||||
if #team1 < 8 and (math.random(2) == 1 or #team2 >= 8) then
|
||||
table.insert(team1, ped)
|
||||
else
|
||||
table.insert(team2, ped)
|
||||
end
|
||||
|
||||
TaskSetBlockingOfNonTemporaryEvents(ped, true)
|
||||
Wait(100)
|
||||
ERS_SpawnConfiguredWeaponForPed(ped, calloutDataClient)
|
||||
end
|
||||
end
|
||||
|
||||
-- Function to make peds flee for this case
|
||||
local function makePedsFlee(peds)
|
||||
for _, ped in pairs(peds) do
|
||||
if DoesEntityExist(ped) and not IsPedDeadOrDying(ped, true) then
|
||||
TaskSmartFleePed(ped, plyPed, 100.0, -1, false, false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Monitor and update ped behavior
|
||||
Citizen.CreateThread(function()
|
||||
while true do
|
||||
Citizen.Wait(1000) -- Check every second
|
||||
|
||||
-- Remove dead peds from teams
|
||||
for i = #team1, 1, -1 do
|
||||
if IsPedDeadOrDying(team1[i], true) then
|
||||
table.remove(team1, i)
|
||||
end
|
||||
end
|
||||
|
||||
for i = #team2, 1, -1 do
|
||||
if IsPedDeadOrDying(team2[i], true) then
|
||||
table.remove(team2, i)
|
||||
end
|
||||
end
|
||||
|
||||
-- If a team is too small, make them flee
|
||||
if #team1 < 3 then
|
||||
makePedsFlee(team1)
|
||||
break
|
||||
end
|
||||
|
||||
if #team2 < 3 then
|
||||
makePedsFlee(team2)
|
||||
break
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
-- Initial combat setup
|
||||
if #team1 > 0 and #team2 > 0 then
|
||||
for _, ped in pairs(team1) do
|
||||
local randomTarget = team2[math.random(#team2)]
|
||||
TaskCombatPed(ped, randomTarget, 0, 16)
|
||||
if Config.Debug then
|
||||
print("Team 1 Ped "..ped.." is attacking ped "..randomTarget)
|
||||
end
|
||||
end
|
||||
|
||||
for _, ped in pairs(team2) do
|
||||
local randomTarget = team1[math.random(#team1)]
|
||||
TaskCombatPed(ped, randomTarget, 0, 16)
|
||||
if Config.Debug then
|
||||
print("Team 2 Ped "..ped.." is attacking ped "..randomTarget)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ERS_CreateTemporaryBlipForEntities(pedList, 15000)
|
||||
ERS_PerformTimedActionOnPed(calloutDataClient, pedList)
|
||||
end,
|
||||
|
||||
server = function(request, src, calloutData, pedList, vehicleList, objectList, propList, playersList, fireList, smokeList)
|
||||
local randomPeds = Config.randomGangPeds
|
||||
local totalPeds = math.random(10, 16) -- Total peds for both teams
|
||||
|
||||
for i = 1, totalPeds do
|
||||
-- Build peds
|
||||
local diameter = 20
|
||||
local pedModel = ERS_GetRandomModel(randomPeds)
|
||||
local pedCoords = ERS_GetRandomCoordinateWithinRangeOfCoordinate(calloutData.Coordinates, diameter)
|
||||
local pedHeading = math.random(360)
|
||||
local pedNetId = ERS_CreatePed(pedModel, pedCoords, pedHeading)
|
||||
local ped = NetworkGetEntityFromNetworkId(pedNetId)
|
||||
table.insert(pedList, pedNetId)
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
Config.Callouts["roxwood_silo_fire"] = {
|
||||
|
||||
Enabled = true,
|
||||
CalloutName = "Silo Fire",
|
||||
CalloutDescriptions = {
|
||||
"A fire has been reported in an agricultural silo, requiring immediate emergency response.",
|
||||
"Emergency services are needed to address a fire situation at a grain storage silo.",
|
||||
"Reports indicate a fire has broken out in a farm silo, necessitating urgent firefighting intervention.",
|
||||
"A silo fire has been identified, posing potential risks to stored agricultural products and nearby structures.",
|
||||
"Emergency services have been requested to respond to a fire at a storage silo facility.",
|
||||
"A request for assistance has been made by farm personnel dealing with a silo fire.",
|
||||
"Additional units are required to support fire personnel managing a dangerous silo fire.",
|
||||
"Emergency backup is needed to contain a fire that has broken out in an agricultural silo.",
|
||||
"First responders report an active fire situation at a grain storage silo.",
|
||||
"Reports indicate a critical fire situation at a farm silo requiring specialized firefighting equipment.",
|
||||
},
|
||||
CalloutUnitsRequired = {
|
||||
description = "Fire",
|
||||
policeRequired = false,
|
||||
ambulanceRequired = false,
|
||||
fireRequired = true,
|
||||
towRequired = false,
|
||||
},
|
||||
CalloutLocations = {
|
||||
[1] = vector3(-1650.7075, 6579.6846, 30.4142),
|
||||
[2] = vector3(-1757.1521, 6566.3809, 79.2261),
|
||||
[3] = vector3(-1666.2078, 6543.0640, 79.2194),
|
||||
[4] = vector3(-1660.5845, 6602.8188, 32.9437),
|
||||
[5] = vector3(-1680.0370, 6607.5435, 34.4462),
|
||||
[6] = vector3(-1707.4130, 6616.6157, 31.7320),
|
||||
[7] = vector3(-1724.4045, 6619.4497, 34.8395),
|
||||
[8] = vector3(-1737.7704, 6623.3125, 33.3164),
|
||||
[9] = vector3(175.7780, 7849.1553, 17.2202),
|
||||
[10] = vector3(175.9884, 7765.7866, 16.3057),
|
||||
[11] = vector3(21.9351, 7808.2656, 31.6843),
|
||||
[12] = vector3(-708.7509, 6809.5586, 35.5453),
|
||||
[13] = vector3(-713.1135, 6787.7432, 38.4738),
|
||||
[14] = vector3(-2898.8865, 8279.4307, 48.0824),
|
||||
},
|
||||
PedChanceToFleeFromPlayer = 0, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedChanceToAttackPlayer = 0, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedChanceToSurrender = 0, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedChanceToObtainWeapons = 0, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedActionMinimumTimeoutInMs = 0, -- Milliseconds for the minimum timeout time to start the secondary action listed above.
|
||||
PedActionMaximumTimeoutInMs = 1000, -- Milliseconds for the maximum timeout time to start the secondary action. Must be a higher number than the minimum!
|
||||
PedActionOnNoActionFound = "none", -- When no action of the above options is found. It'll perform this action after the set timeout. Options: "none", "attack", "flee", "surrender"
|
||||
PedWeaponData = { -- The ped will be given one randomly selected weapon (in hand) from these weapons if PedChanceToObtainWeapons passed.
|
||||
"weapon_unarmed",
|
||||
},
|
||||
|
||||
client = function(plyPed, pedList, vehicleList, playersList, objectList, propList, fireList, smokeList, calloutDataClient)
|
||||
|
||||
for index, pedNetId in pairs(pedList) do
|
||||
local ped = NetToPed(pedNetId)
|
||||
if DoesEntityExist(ped) then
|
||||
ERS_RequestNetControlForEntity(ped)
|
||||
TaskSetBlockingOfNonTemporaryEvents(ped, true)
|
||||
PlayPain(ped, 8, 200)
|
||||
ERS_ApplyBloodToPed(ped)
|
||||
Wait(2500)
|
||||
SetEntityHealth(ped, 0)
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
local chanceOfAnExplosion = 100
|
||||
if math.random(1, 100) <= chanceOfAnExplosion then
|
||||
Citizen.SetTimeout(math.random(5000, 10000), function()
|
||||
local explosionCoords = vector3(calloutDataClient.Coordinates.x, calloutDataClient.Coordinates.y, calloutDataClient.Coordinates.z)
|
||||
local explosionRadius = 10.0
|
||||
local explosionForce = 10.0
|
||||
local explosionValues = {
|
||||
0, -- GRENADE
|
||||
1, -- GRENADELAUNCHER
|
||||
2, -- STICKYBOMB
|
||||
3, -- MOLOTOV
|
||||
4, -- ROCKET
|
||||
5, -- TANKSHELL
|
||||
6, -- HI_OCTANE
|
||||
7, -- CAR
|
||||
8, -- PLANE
|
||||
9, -- PETROL_PUMP
|
||||
10, -- BIKE
|
||||
11, -- DIR_STEAM
|
||||
12, -- DIR_FLAME
|
||||
13, -- DIR_WATER_HYDRANT
|
||||
14, -- DIR_GAS_CANISTER
|
||||
15, -- BOAT
|
||||
16, -- SHIP_DESTROY
|
||||
17, -- TRUCK
|
||||
18, -- BULLET
|
||||
19, -- SMOKE_GRENADE_LAUNCHER
|
||||
20, -- SMOKE_GRENADE
|
||||
21, -- BZGAS
|
||||
22, -- FLARE
|
||||
23, -- GAS_CANISTER
|
||||
24, -- EXTINGUISHER
|
||||
25, -- PROGRAMMABLEAR
|
||||
26, -- TRAIN
|
||||
27, -- BARREL
|
||||
28, -- PROPANE
|
||||
29, -- BLIMP
|
||||
30, -- DIR_FLAME_EXPLODE
|
||||
31, -- TANKER
|
||||
74, -- BOMB water
|
||||
75, -- BOMB water secondary
|
||||
-- Only including explosion types that make sense for a silo fire
|
||||
}
|
||||
local explosionType = explosionValues[math.random(#explosionValues)]
|
||||
AddExplosion(explosionCoords.x, explosionCoords.y, explosionCoords.z-2.0, explosionType, explosionRadius, explosionForce, true, false, 1.0)
|
||||
end)
|
||||
end
|
||||
|
||||
ERS_CreateTemporaryBlipForEntities(pedList, 15000)
|
||||
|
||||
ERS_PerformTimedActionOnPed(calloutDataClient, pedList)
|
||||
|
||||
end,
|
||||
server = function(request, src, calloutData, pedList, vehicleList, objectList, propList, playersList, fireList, smokeList)
|
||||
|
||||
local diameter = 2
|
||||
local coords = ERS_GetRandomCoordinateWithinRangeOfCoordinate(calloutData.Coordinates, diameter)
|
||||
|
||||
-- Build a medium sized fire
|
||||
if UsingSmartFires then
|
||||
-- Full version
|
||||
local fireSize = Config.RandomMediumFireOrSmokeSize[math.random(#Config.RandomMediumFireOrSmokeSize)]
|
||||
local fireType = Config.NormalFireTypes[math.random(#Config.NormalFireTypes)]
|
||||
local fireId = exports['SmartFires']:CreateFire(vector3(calloutData.Coordinates.x, calloutData.Coordinates.y, calloutData.Coordinates.z-0.5), fireSize, fireType)
|
||||
DebugPrint("Created fire with ID: "..fireId)
|
||||
table.insert(fireList, fireId)
|
||||
|
||||
-- Build smoke
|
||||
local chanceOnASmoke = 50
|
||||
if math.random(1, 100) <= chanceOnASmoke then
|
||||
local smokeSize = Config.RandomMediumFireOrSmokeSize[math.random(#Config.RandomMediumFireOrSmokeSize)]
|
||||
local smokeType = Config.AllSmokeTypes[math.random(#Config.AllSmokeTypes)]
|
||||
local smokeId = exports['SmartFires']:CreateSmoke(vector3(calloutData.Coordinates.x, calloutData.Coordinates.y, calloutData.Coordinates.z-0.5), smokeSize, smokeType)
|
||||
|
||||
DebugPrint("Created smoke with ID: "..smokeId)
|
||||
table.insert(smokeList, smokeId)
|
||||
end
|
||||
else
|
||||
-- Lite version
|
||||
local fireSize = Config.RandomSmallFireOrSmokeSize[math.random(#Config.RandomSmallFireOrSmokeSize)]
|
||||
local fireType = "normal"
|
||||
local fireId = exports['SmartFiresLite']:CreateFire(vector3(calloutData.Coordinates.x, calloutData.Coordinates.y, calloutData.Coordinates.z-0.5), fireSize, fireType)
|
||||
DebugPrint("Created fire with SmartFiresLite with ID: "..fireId)
|
||||
table.insert(fireList, fireId)
|
||||
|
||||
-- Build smoke
|
||||
local chanceOnASmoke = 50
|
||||
if math.random(1, 100) <= chanceOnASmoke then
|
||||
local smokeSize = Config.RandomMediumFireOrSmokeSize[math.random(#Config.RandomMediumFireOrSmokeSize)]
|
||||
local smokeType = "normal"
|
||||
local smokeId = exports['SmartFiresLite']:CreateSmoke(vector3(calloutData.Coordinates.x, calloutData.Coordinates.y, calloutData.Coordinates.z-0.5), smokeSize, smokeType)
|
||||
|
||||
DebugPrint("Created smoke with ID: "..smokeId)
|
||||
table.insert(smokeList, smokeId)
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
Config.Callouts["roxwood_waterpark_incident"] = {
|
||||
|
||||
Enabled = true,
|
||||
CalloutName = "Waterpark Incident",
|
||||
CalloutDescriptions = {
|
||||
"Emergency response needed at the waterpark; individual requiring immediate medical attention.",
|
||||
"Alert: medical emergency reported at waterpark facilities; units requested for immediate response.",
|
||||
"Units needed: incident reported at waterpark involving an injured person.",
|
||||
"Emergency situation at waterpark; medical assistance required for park visitor.",
|
||||
"Alert: waterpark incident in progress; medical response team needed on scene.",
|
||||
"First responders requested at waterpark location; medical emergency reported.",
|
||||
"Respond to waterpark emergency; coordinate with on-site staff for immediate assistance.",
|
||||
"Situation alert: medical incident at waterpark facilities requiring urgent response.",
|
||||
"Emergency services needed at waterpark; injured person requiring immediate attention.",
|
||||
"Response needed: waterpark incident involving injured visitor; medical assistance required.",
|
||||
},
|
||||
CalloutUnitsRequired = {
|
||||
description = "Ambulance.",
|
||||
policeRequired = false,
|
||||
ambulanceRequired = true,
|
||||
fireRequired = false,
|
||||
towRequired = false,
|
||||
},
|
||||
CalloutLocations = {
|
||||
[1] = vector3(-283.4168, 7742.1196, 4.7899),
|
||||
[2] = vector3(-355.4387, 7813.5391, 4.4505),
|
||||
[3] = vector3(-285.5687, 7806.6489, 6.3981),
|
||||
[4] = vector3(-294.5287, 7814.0903, 6.4198),
|
||||
[5] = vector3(-253.2503, 7772.4219, 6.4892),
|
||||
[6] = vector3(-207.7762, 7791.9185, 11.1117),
|
||||
[7] = vector3(-314.7422, 7720.8774, 6.3765),
|
||||
[8] = vector3(-372.0792, 7815.6128, 6.3837),
|
||||
[9] = vector3(-314.7273, 7838.0542, 27.3287),
|
||||
[10] = vector3(-260.1914, 7839.4521, 14.3411),
|
||||
|
||||
},
|
||||
PedChanceToFleeFromPlayer = 0, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedChanceToAttackPlayer = 0, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedChanceToSurrender = 0, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedChanceToObtainWeapons = 0, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedActionMinimumTimeoutInMs = 0, -- Milliseconds for the minimum timeout time to start the secondary action listed above.
|
||||
PedActionMaximumTimeoutInMs = 1000, -- Milliseconds for the maximum timeout time to start the secondary action. Must be a higher number than the minimum!
|
||||
PedActionOnNoActionFound = "none", -- When no action of the above options is found. It'll perform this action after the set timeout. Options: "none", "attack", "flee", "surrender"
|
||||
PedWeaponData = { -- The ped will be given one randomly selected weapon (in hand) from these weapons if PedChanceToObtainWeapons passed.
|
||||
"weapon_unarmed",
|
||||
},
|
||||
|
||||
client = function(plyPed, pedList, vehicleList, playersList, objectList, propList, fireList, smokeList, calloutDataClient)
|
||||
|
||||
for index, pedNetId in pairs(pedList) do
|
||||
local ped = NetToPed(pedNetId)
|
||||
if DoesEntityExist(ped) then
|
||||
ERS_RequestNetControlForEntity(ped)
|
||||
SetEntityHealth(ped, 0)
|
||||
end
|
||||
end
|
||||
|
||||
ERS_CreateTemporaryBlipForEntities(pedList, 15000)
|
||||
ERS_PerformTimedActionOnPed(calloutDataClient, pedList)
|
||||
|
||||
end,
|
||||
server = function(request, src, calloutData, pedList, vehicleList, objectList, propList, playersList, fireList, smokeList)
|
||||
|
||||
-- Build ped`
|
||||
local bathingPedModels = {"a_f_m_beach_01", "a_f_m_bodybuild_01", "a_f_m_fatcult_01", "a_f_y_beach_01", "a_m_m_tranvest_01", "a_m_y_acult_02", "a_m_y_jetski_01", "a_m_y_musclbeac_01", "a_m_y_stwhi_01"}
|
||||
local pedModel = bathingPedModels[math.random(1, #bathingPedModels)]
|
||||
local pedCoords = vector3(calloutData.Coordinates.x, calloutData.Coordinates.y, calloutData.Coordinates.z+1.0)
|
||||
local pedHeading = math.random(360)
|
||||
local pedNetId = ERS_CreatePed(pedModel, pedCoords, pedHeading)
|
||||
local ped = NetworkGetEntityFromNetworkId(pedNetId)
|
||||
table.insert(pedList, pedNetId)
|
||||
|
||||
return true
|
||||
end
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
Config.Callouts["roxwood_wounded_adventurer"] = {
|
||||
|
||||
Enabled = true,
|
||||
CalloutName = "Wounded adventurer",
|
||||
CalloutDescriptions = {
|
||||
"Emergency responders have located a wounded adventurer and are providing assistance.",
|
||||
"Authorities report that a wounded adventurer has been found, requiring immediate medical attention.",
|
||||
"A wounded adventurer has been located, necessitating urgent action to ensure their safety.",
|
||||
"Critical situation with a wounded adventurer located; medical personnel are needed for support.",
|
||||
"Immediate response needed to provide medical assistance to the wounded adventurer.",
|
||||
"A wounded adventurer has been found, posing a severe threat to their health; medical reinforcements are necessary.",
|
||||
"Emergency crews are requesting medical backup to assist in providing care to the wounded adventurer.",
|
||||
"An urgent call for help has been issued to handle a wounded adventurer and ensure their well-being.",
|
||||
"Responders are on the scene with a wounded adventurer and need extra support to provide necessary care.",
|
||||
"A serious emergency involving a wounded adventurer demands swift action to provide medical attention and ensure their recovery.",
|
||||
},
|
||||
CalloutUnitsRequired = {
|
||||
description = "Police, Ambulance, Fire.",
|
||||
policeRequired = true,
|
||||
ambulanceRequired = true,
|
||||
fireRequired = true,
|
||||
towRequired = false,
|
||||
},
|
||||
CalloutLocations = {
|
||||
[1] = vector3(-2018.5511, 7298.9761, 33.5327),
|
||||
[2] = vector3(-1760.0613, 7586.3652, 144.0277),
|
||||
[3] = vector3(-1436.0414, 7666.9263, 322.1493),
|
||||
[4] = vector3(-1310.2694, 7819.0005, 112.6630),
|
||||
[5] = vector3(-1512.3247, 8080.1509, 42.6374),
|
||||
[6] = vector3(-1986.1616, 8326.9473, 53.5735),
|
||||
[7] = vector3(-2109.8350, 8310.7412, 39.0122),
|
||||
[8] = vector3(-2905.3364, 7596.4253, 14.0765),
|
||||
[9] = vector3(-3712.5322, 7523.3833, 30.1363),
|
||||
[10] = vector3(-3044.6580, 7873.9575, 57.8766),
|
||||
},
|
||||
PedChanceToFleeFromPlayer = 0, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedChanceToAttackPlayer = 0, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedChanceToSurrender = 0, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedChanceToObtainWeapons = 0, -- Value between 0 and 100 -> Lower is less chance.
|
||||
PedActionMinimumTimeoutInMs = 0, -- Milliseconds for the minimum timeout time to start the secondary action listed above.
|
||||
PedActionMaximumTimeoutInMs = 1000, -- Milliseconds for the maximum timeout time to start the secondary action. Must be a higher number than the minimum!
|
||||
PedActionOnNoActionFound = "none", -- When no action of the above options is found. It'll perform this action after the set timeout. Options: "none", "attack", "flee", "surrender"
|
||||
PedWeaponData = { -- The ped will be given one randomly selected weapon (in hand) from these weapons if PedChanceToObtainWeapons passed.
|
||||
"weapon_unarmed",
|
||||
},
|
||||
client = function(plyPed, pedList, vehicleList, playersList, objectList, propList, fireList, smokeList, calloutDataClient)
|
||||
for index, pedNetId in pairs(pedList) do
|
||||
local ped = NetToPed(pedNetId)
|
||||
if DoesEntityExist(ped) then
|
||||
ERS_RequestNetControlForEntity(ped)
|
||||
TaskSetBlockingOfNonTemporaryEvents(ped, true)
|
||||
ERS_ApplyBloodToPed(ped)
|
||||
local scenario = ERS_SelectRandomWoundedPersonScenario()
|
||||
TaskStartScenarioInPlace(ped, scenario, 0, true)
|
||||
end
|
||||
end
|
||||
|
||||
ERS_CreateTemporaryBlipForEntities(pedList, 5000) -- short, to make it harder to find. :)
|
||||
ERS_PerformTimedActionOnPed(calloutDataClient, pedList)
|
||||
end,
|
||||
server = function(request, src, calloutData, pedList, vehicleList, objectList, propList, playersList, fireList, smokeList)
|
||||
-- Build ped
|
||||
local pedModel = ERS_GetRandomModel(Config.randomPeds)
|
||||
local pedCoords = vector3(calloutData.Coordinates.x, calloutData.Coordinates.y, calloutData.Coordinates.z)
|
||||
local pedHeading = math.random(360)
|
||||
local pedNetId = ERS_CreatePed(pedModel, pedCoords, pedHeading)
|
||||
local ped = NetworkGetEntityFromNetworkId(pedNetId)
|
||||
table.insert(pedList, pedNetId)
|
||||
|
||||
return true
|
||||
end
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -30,10 +30,10 @@ Config = {
|
||||
KMHorMPH = "MPH", -- "KMH" or "MPH"
|
||||
|
||||
Enable_Discord_API = true, -- You need the discord API for this script, otherwise it will not work https://store.nights-software.com/package/5035729 [FREE] Included in the Tebex package.
|
||||
Enable_Nearest_Postal = true, -- Nearest-postal integration, if false it will always return "Unknown" on postals. (CFX Post: https://forum.cfx.re/t/release-nearest-postal-script/293511) Edit getPostal(x,y) in c_functions.lua if you desire to integrate your own postal system.
|
||||
Enable_MDT_Battery_System = false, -- Set to false to disable the battery system, if disabled it'll always stay 100%. Charging can be done in vehicles and interiors
|
||||
Enable_Nearest_Postal = false, -- Nearest-postal integration, if false it will always return "Unknown" on postals. (CFX Post: https://forum.cfx.re/t/release-nearest-postal-script/293511) Edit getPostal(x,y) in c_functions.lua if you desire to integrate your own postal system.
|
||||
Enable_MDT_Battery_System = true, -- Set to false to disable the battery system, if disabled it'll always stay 100%. Charging can be done in vehicles and interiors
|
||||
DefaultSoundVolume = 0.15, -- Used for notifications. Higher than 0.5 will set it to 0.25, limited to protect ears
|
||||
Enable_Discord_Webhooks = false, -- Set your webhook URL in s_functions.lua, edit your preferences for these messages in c_functions.lua and s_functions.lua
|
||||
Enable_Discord_Webhooks = true, -- Set your webhook URL in s_functions.lua, edit your preferences for these messages in c_functions.lua and s_functions.lua
|
||||
Enable_Blips = true, -- Allow this system to add blips for backup requests, panic buttons, sighting reports, ANPR hits etc.
|
||||
Enable_Unit_Blips = true, -- Allow this system to add blips for active units on map.
|
||||
Enable_Save_Callsigns = true, -- If true it will set the last used callsign. If false it will use the config pre-set callsigns for departments & sub-departments.
|
||||
@@ -50,7 +50,7 @@ Config = {
|
||||
Enable_Commands = true, -- Allow Commands?
|
||||
Commands = {
|
||||
MobileDataTerminal = "mdt", -- Syntax: /mdt | Open the MDT
|
||||
CallEmergencies = "911", -- Syntax: /999 | Open emergency hotline call system
|
||||
CallEmergencies = "999", -- Syntax: /999 | Open emergency hotline call system
|
||||
ChargeMDT = "chargemdt", -- Syntax: /chargemdt | Charges the MDT, can be done in vehicles and interiors
|
||||
StatusChange = "status", -- Syntax: /status 10-42 or /status 2, depends on what you define as statuses.
|
||||
ForceCloseMDT = "forceclosemdt", -- Syntax: /forceclosemdt or use F8 and type it without the slash.
|
||||
|
||||
@@ -6,9 +6,9 @@ Config.MobileDataTerminal = Config.MobileDataTerminal or {}
|
||||
-- Misplaced brackets and/or commas can break your script. https://code.visualstudio.com/download
|
||||
|
||||
-- [IMPORTANT] Edit these roles to match your Discord API.
|
||||
Config.MobileDataTerminal.DiscordGuildNames = {"Elite Gaming RP"} -- It checks whether the user is in any of these Discord servers and checks for the roles the user has in these Discord servers. Match these names to your Discord API. The first guild defined is where it fetches the Discord member data from (avatar, nickname etc.).
|
||||
Config.MobileDataTerminal.RolesWithAccessToMDT = {"First Responders", "Civilian I", "EG | Owner", "EG | Server Developer", "EG | Head of Staff", "EG | Sr. Admin", "EG | Admin", "EG | Sr. Moderator", "EG | Moderator", "EG | Sr. Staff", "EG | Staff", "EG | Helper"} -- Edit these to match your roles (role names) from Night Discord API [FREE] https://store.nights-software.com/package/5035729
|
||||
Config.MobileDataTerminal.ManagementRoles = {"EG | Owner" "EG | Server Developer" "EG | Head of Staff" "EG | Sr. Admin" "EG | Admin" "EG | Sr. Moderator" "EG | Moderator" "EG | Sr. Staff" "EG | Staff" "EG | Helper"}
|
||||
Config.MobileDataTerminal.DiscordGuildNames = {"Your_Discord_Community_Name"} -- It checks whether the user is in any of these Discord servers and checks for the roles the user has in these Discord servers. Match these names to your Discord API. The first guild defined is where it fetches the Discord member data from (avatar, nickname etc.).
|
||||
Config.MobileDataTerminal.RolesWithAccessToMDT = {"Your_Police_Role", "Your_Ambulance_Role", "Your_Fire_Role", "Your_Tow_Role", "Your_Civilian_Role"} -- Edit these to match your roles (role names) from Night Discord API [FREE] https://store.nights-software.com/package/5035729
|
||||
Config.MobileDataTerminal.ManagementRoles = {"Your_Management_Role"}
|
||||
|
||||
-- [IMPORTANT] Edit the department list below and make sure each department has a main role, used for the department, first rank and first sub-department.
|
||||
Config.MobileDataTerminal.DepartmentList = {
|
||||
@@ -16,19 +16,19 @@ Config.MobileDataTerminal.DepartmentList = {
|
||||
-- [IMPORTANT] ORDER department index numbers. Example: [1] = police, [2] = ambulance, [3] = fire, [4] = tow, [5] = civilians, this must be in a counting order or it will bug out the script!
|
||||
-- [IMPORTANT] Provide the main department role to at least: the DepartmentRoleName, the first rank and the first SubDepartmentRoleName.
|
||||
[1] = {
|
||||
DepartmentName = "First Responders",
|
||||
DepartmentName = "Metropolitan Police Service",
|
||||
DepartmentLogo = "home_met.png", -- NUI/images/home_met.png
|
||||
DepartmentDescription = "The Metropolitan Police Service (MPS), formerly and still commonly known as the Metropolitan Police (and informally as the Met Police, the Met, Scotland Yard, or the Yard), is the territorial police force responsible for law enforcement and the prevention of crime in Greater London.",
|
||||
DepartmentFooterText = "Select to enter the shift menu.",
|
||||
DepartmentShortName = "MET",
|
||||
DepartmentRoleName = "First Responders", -- Match to the role name in the Discord API config.lua!
|
||||
DepartmentRoleName = "Your_Police_Role", -- Match to the role name in the Discord API config.lua!
|
||||
DepartmentCallsignPrefix = "CW-",
|
||||
DepartmentType = "police", -- This defines the emergency service type, options: police | ambulance | fire | tow
|
||||
DepartmentShiftAccess = true, -- Is this department allowed to use the Shift system?
|
||||
DepartmentPoliceComputerAccess = true, -- Is this department allowed to access the Police Computer?
|
||||
DepartmentOperationsAccess = true, -- Is this department allowed to access operation reports?
|
||||
DepartmentRanksAndRoles = { -- Match to the role name in the Discord API config.lua!
|
||||
[1] = {RankName = "Officer", RoleName = "First Responders", AccessLevel = 1}, -- Access levels MUST go from lower, to equal or higher as you add ranks.
|
||||
[1] = {RankName = "Student Police Constable", RoleName = "Your_Police_Role", AccessLevel = 1}, -- Access levels MUST go from lower, to equal or higher as you add ranks.
|
||||
[2] = {RankName = "Police Constable", RoleName = "Police_Constable", AccessLevel = 2}, -- Add ranks, low to high (top to bottom) as in the example here.
|
||||
[3] = {RankName = "Sergeant", RoleName = "Sergeant", AccessLevel = 2},
|
||||
[4] = {RankName = "Inspector", RoleName = "Inspector", AccessLevel = 3},
|
||||
@@ -46,7 +46,7 @@ Config.MobileDataTerminal.DepartmentList = {
|
||||
[1] = {
|
||||
SubDepartmentName = "Emergency Response & Patrol Team", -- Full sub-department name
|
||||
SubDepartmentShortName = "ERPT", -- Just a shortname used to display, keep it short!
|
||||
SubDepartmentRoleName = "First Responders", -- Match to the role name in the Discord API config.lua!
|
||||
SubDepartmentRoleName = "Your_Police_Role", -- Match to the role name in the Discord API config.lua!
|
||||
SubDepartmentCallsignPrefix = "CW-", -- Example: Server ID 1 will be 'CW-01'
|
||||
SubDepartmentBlipData = { -- Blips: https://docs.fivem.net/docs/game-references/blips/
|
||||
SubSpriteID = 1,
|
||||
@@ -145,31 +145,31 @@ Config.MobileDataTerminal.DepartmentList = {
|
||||
},
|
||||
},
|
||||
[2] = {
|
||||
DepartmentName = "First Responders",
|
||||
DepartmentName = "London Ambulance Service",
|
||||
DepartmentLogo = "home_las.png", -- NUI/images/mylogo.png
|
||||
DepartmentDescription = "Our main role is to respond to emergency 999 calls, providing medical care to patients across the capital, 24-hours a day, 365 days a year. Other services we offer include providing pre-arranged patient transport and finding hospital beds",
|
||||
DepartmentFooterText = "Select to enter the shift menu.",
|
||||
DepartmentShortName = "LAS",
|
||||
DepartmentRoleName = "First Responders", -- Match to the role name in the Discord API config.lua!
|
||||
DepartmentRoleName = "Your_Ambulance_Role", -- Match to the role name in the Discord API config.lua!
|
||||
DepartmentCallsignPrefix = "BS-",
|
||||
DepartmentType = "ambulance", -- This defines the emergency service type, options: police | ambulance | fire | tow
|
||||
DepartmentShiftAccess = true, -- Is this department allowed to use the Shift system?
|
||||
DepartmentPoliceComputerAccess = true, -- Is this department allowed to access the Police Computer?
|
||||
DepartmentOperationsAccess = true, -- Is this department allowed to access operation reports?
|
||||
DepartmentRanksAndRoles = { -- Match to the role name in the Discord API config.lua!
|
||||
[1] = {RankName = "Paramedic", RoleName = "First Responders", AccessLevel = 1},
|
||||
[2] = {RankName = "Paramedic", RoleName = "First Responders", AccessLevel = 2},
|
||||
[3] = {RankName = "Advanced Paramedic", RoleName = "First Responders", AccessLevel = 3},
|
||||
[4] = {RankName = "Care Clinician", RoleName = "First Responders", AccessLevel = 4},
|
||||
[5] = {RankName = "Advanced Care Clinician", RoleName = "First Responders", AccessLevel = 5},
|
||||
[6] = {RankName = "Deputy Director of Ambulance", RoleName = "First Responders", AccessLevel = 6},
|
||||
[7] = {RankName = "Director of Ambulance", RoleName = "First Responders", AccessLevel = 7},
|
||||
[1] = {RankName = "Student Paramedic", RoleName = "Your_Ambulance_Role", AccessLevel = 1},
|
||||
[2] = {RankName = "Paramedic", RoleName = "Ambu_Paramedic", AccessLevel = 2},
|
||||
[3] = {RankName = "Advanced Paramedic", RoleName = "Ambu_Senior_Paramedic", AccessLevel = 3},
|
||||
[4] = {RankName = "Care Clinician", RoleName = "Ambu_Advanced_Paramedic", AccessLevel = 4},
|
||||
[5] = {RankName = "Advanced Care Clinician", RoleName = "Ambu_Leading_Operations_Manager", AccessLevel = 5},
|
||||
[6] = {RankName = "Deputy Director of Ambulance", RoleName = "Ambu_Deputy_Director", AccessLevel = 6},
|
||||
[7] = {RankName = "Director of Ambulance", RoleName = "Ambu_Director", AccessLevel = 7},
|
||||
},
|
||||
SubDepartments = { -- At least 1 sub-department!
|
||||
[1] = {
|
||||
SubDepartmentName = "Rapid Response",
|
||||
SubDepartmentShortName = "RRV",
|
||||
SubDepartmentRoleName = "First Responders",
|
||||
SubDepartmentRoleName = "Your_Ambulance_Role",
|
||||
SubDepartmentCallsignPrefix = "BS-",
|
||||
SubDepartmentBlipData = {
|
||||
SubSpriteID = 1,
|
||||
@@ -180,7 +180,7 @@ Config.MobileDataTerminal.DepartmentList = {
|
||||
[2] = {
|
||||
SubDepartmentName = "Helicopter Emergency Medical Services",
|
||||
SubDepartmentShortName = "HEMS",
|
||||
SubDepartmentRoleName = "First Responders",
|
||||
SubDepartmentRoleName = "HEMS",
|
||||
SubDepartmentCallsignPrefix = "HO-",
|
||||
SubDepartmentBlipData = {
|
||||
SubSpriteID = 1,
|
||||
@@ -191,7 +191,7 @@ Config.MobileDataTerminal.DepartmentList = {
|
||||
[3] = {
|
||||
SubDepartmentName = "Hazardous Area Response Team",
|
||||
SubDepartmentShortName = "HART",
|
||||
SubDepartmentRoleName = "First Responders",
|
||||
SubDepartmentRoleName = "HART",
|
||||
SubDepartmentCallsignPrefix = "HA-",
|
||||
SubDepartmentBlipData = {
|
||||
SubSpriteID = 1,
|
||||
@@ -202,19 +202,19 @@ Config.MobileDataTerminal.DepartmentList = {
|
||||
},
|
||||
},
|
||||
[3] = {
|
||||
DepartmentName = "First Responders",
|
||||
DepartmentName = "London Fire Brigade",
|
||||
DepartmentLogo = "home_lfb.png", -- NUI/images/mylogo.png
|
||||
DepartmentDescription = "As well as firefighting, the LFB also responds to road traffic collisions, floods, shut-in-lift releases, and other incidents such as those involving hazardous materials or major transport accidents. It also conducts emergency planning and performs fire safety inspections and education.",
|
||||
DepartmentFooterText = "Select to enter the shift menu.",
|
||||
DepartmentShortName = "LFB",
|
||||
DepartmentRoleName = "First Responders", -- Match to the role name in the Discord API config.lua!
|
||||
DepartmentRoleName = "Your_Fire_Role", -- Match to the role name in the Discord API config.lua!
|
||||
DepartmentCallsignPrefix = "PL-",
|
||||
DepartmentType = "fire", -- This defines the emergency service type, options: police | ambulance | fire | tow
|
||||
DepartmentShiftAccess = true, -- Is this department allowed to use the Shift system?
|
||||
DepartmentPoliceComputerAccess = true, -- Is this department allowed to access the Police Computer?
|
||||
DepartmentOperationsAccess = true, -- Is this department allowed to access operation reports?
|
||||
DepartmentRanksAndRoles = { -- Match to the role name in the Discord API config.lua!
|
||||
[1] = {RankName = "Firefighter", RoleName = "First Responders", AccessLevel = 2},
|
||||
[1] = {RankName = "Firefighter", RoleName = "Your_Fire_Role", AccessLevel = 2},
|
||||
[2] = {RankName = "Leading Firefighter", RoleName = "Lead_Firefighter", AccessLevel = 3},
|
||||
[3] = {RankName = "Sub-Officer", RoleName = "Sub_Manager", AccessLevel = 3},
|
||||
[4] = {RankName = "Station Officer", RoleName = "Station_Officer", AccessLevel = 4},
|
||||
@@ -227,9 +227,9 @@ Config.MobileDataTerminal.DepartmentList = {
|
||||
},
|
||||
SubDepartments = { -- At least 1 sub-department!
|
||||
[1] = {
|
||||
SubDepartmentName = "First Responders,
|
||||
SubDepartmentName = "London Fire & Rescue",
|
||||
SubDepartmentShortName = "F&R",
|
||||
SubDepartmentRoleName = "First Responders",
|
||||
SubDepartmentRoleName = "Your_Fire_Role",
|
||||
SubDepartmentCallsignPrefix = "PL-",
|
||||
SubDepartmentBlipData = {
|
||||
SubSpriteID = 1,
|
||||
@@ -240,7 +240,7 @@ Config.MobileDataTerminal.DepartmentList = {
|
||||
[2] = {
|
||||
SubDepartmentName = "Heathrow Airport Fire & Rescue",
|
||||
SubDepartmentShortName = "AFR",
|
||||
SubDepartmentRoleName = "First Responders",
|
||||
SubDepartmentRoleName = "heathrowfire",
|
||||
SubDepartmentCallsignPrefix = "HF-",
|
||||
SubDepartmentBlipData = {
|
||||
SubSpriteID = 1,
|
||||
@@ -251,7 +251,7 @@ Config.MobileDataTerminal.DepartmentList = {
|
||||
[3] = {
|
||||
SubDepartmentName = "Marine Unit",
|
||||
SubDepartmentShortName = "MARU",
|
||||
SubDepartmentRoleName = "First Responders",
|
||||
SubDepartmentRoleName = "Marine",
|
||||
SubDepartmentCallsignPrefix = "MA-",
|
||||
SubDepartmentBlipData = {
|
||||
SubSpriteID = 1,
|
||||
@@ -262,25 +262,25 @@ Config.MobileDataTerminal.DepartmentList = {
|
||||
},
|
||||
},
|
||||
[4] = {
|
||||
DepartmentName = "tow Responders",
|
||||
DepartmentName = "Tow Service",
|
||||
DepartmentLogo = "home_tow.png", -- NUI/images/mylogo.png
|
||||
DepartmentDescription = "AA Towing is a trusted and efficient service that offers prompt assistance to stranded vehicles. With a fleet of well-equipped tow trucks and skilled operators, they excel at rescuing vehicles from breakdowns, accidents, and challenging situations. Whether it's on-site repairs, safe towing to service centers, or long-distance transportation, AA Towing ensures reliable and professional service to keep the roads running smoothly.",
|
||||
DepartmentFooterText = "Start your career as a towing service operator.",
|
||||
DepartmentShortName = "TOW",
|
||||
DepartmentRoleName = "Civilian I", -- Match to the role name in the Discord API config.lua!
|
||||
DepartmentRoleName = "Your_Tow_Role", -- Match to the role name in the Discord API config.lua!
|
||||
DepartmentCallsignPrefix = "AA-",
|
||||
DepartmentType = "tow", -- This defines the emergency service type, options: police | ambulance | fire | tow (civilian is a placeholder)
|
||||
DepartmentShiftAccess = true, -- Is this department allowed to access the Shift system?
|
||||
DepartmentPoliceComputerAccess = false, -- Is this department allowed to access the Police Computer?
|
||||
DepartmentOperationsAccess = false, -- Is this department allowed to access Operation reports?
|
||||
DepartmentRanksAndRoles = { -- Match to the role name in the Discord API config.lua!
|
||||
[1] = {RankName = "Recovery Operator", RoleName = "Civilian I", AccessLevel = 7},
|
||||
[1] = {RankName = "Recovery Operator", RoleName = "Your_Tow_Role", AccessLevel = 7},
|
||||
},
|
||||
SubDepartments = {
|
||||
[1] = {
|
||||
SubDepartmentName = "tow Responders",
|
||||
SubDepartmentName = "AA Towing Service",
|
||||
SubDepartmentShortName = "AA",
|
||||
SubDepartmentRoleName = "Civilian I",
|
||||
SubDepartmentRoleName = "Your_Tow_Role",
|
||||
SubDepartmentCallsignPrefix = "AA-",
|
||||
SubDepartmentBlipData = {
|
||||
SubSpriteID = 317,
|
||||
@@ -298,14 +298,14 @@ Config.MobileDataTerminal.DepartmentList = {
|
||||
DepartmentDescription = "Be free and play whoever you want to be as a civilian. Legal or illegal? It's all up to you.",
|
||||
DepartmentFooterText = "Select to get access to the DVLA & Council.",
|
||||
DepartmentShortName = "CIV",
|
||||
DepartmentRoleName = "Civilian I", -- Match to the role name in the Discord API config.lua!
|
||||
DepartmentRoleName = "Your_Civilian_Role", -- Match to the role name in the Discord API config.lua!
|
||||
DepartmentCallsignPrefix = "NONE",
|
||||
DepartmentType = "civilian", -- This defines the emergency service type, options: civilian
|
||||
DepartmentShiftAccess = false, -- Is this department allowed to access the Shift system?
|
||||
DepartmentPoliceComputerAccess = false, -- Is this department allowed to access the Police Computer?
|
||||
DepartmentOperationsAccess = false, -- Is this department allowed to access Operation reports?
|
||||
DepartmentRanksAndRoles = { -- Match to the role name in the Discord API config.lua!
|
||||
[1] = {RankName = "Civilian", RoleName = "Civilian I", AccessLevel = 1},
|
||||
[1] = {RankName = "Civilian", RoleName = "Your_Civilian_Role", AccessLevel = 1},
|
||||
},
|
||||
SubDepartments = {}, -- Leave this empty, for other departments you must add at least one sub-department, see examples in the other departments.
|
||||
},
|
||||
|
||||
@@ -4,7 +4,7 @@ Config = Config or {}
|
||||
|
||||
Config.MobileDataTerminal = {
|
||||
|
||||
MDTName = "Elite Gaming RP MDT", -- Title at the top of the MDT UI, to hide the title set it to an empty string: "",
|
||||
MDTName = "MOBILE DATA TERMINAL", -- Title at the top of the MDT UI, to hide the title set it to an empty string: "",
|
||||
|
||||
--====================== Intervals ===================--
|
||||
|
||||
@@ -39,10 +39,10 @@ Config.MobileDataTerminal = {
|
||||
-- All
|
||||
[1] = {MenuName = "HOME", RequiredAccessLevel = 1, Show = true}, -- Department/civ selection (Always show)
|
||||
-- Emergency services
|
||||
[2] = {MenuName = "Patrol Panel", RequiredAccessLevel = 1, Show = true}, -- Status panel and shift toggling (Always show)
|
||||
[2] = {MenuName = "SHIFT", RequiredAccessLevel = 1, Show = true}, -- Status panel and shift toggling (Always show)
|
||||
[3] = {MenuName = "EMERGENCY HOTLINE", RequiredAccessLevel = 1, Show = true}, -- Add menu: Active calls, Archived calls. EDIT CALLS LAYOUT TO WIDER CARD AND LIST UNDERNEATH EACHOTHER
|
||||
-- Police
|
||||
[4] = {MenuName = "NCIC Search", RequiredAccessLevel = 1, Show = true}, -- Police National Computer (Search registrations of vehicles, civilians, fines and criminal records) Only police can access this.
|
||||
[4] = {MenuName = "PNC", RequiredAccessLevel = 1, Show = true}, -- Police National Computer (Search registrations of vehicles, civilians, fines and criminal records) Only police can access this.
|
||||
-- Emergency services
|
||||
[5] = {MenuName = "UNIT OVERVIEW", RequiredAccessLevel = 1, Show = true}, -- Overview of active units & locations, backup requests (You could name this Control / Dispatch)
|
||||
[6] = {MenuName = "OPERATIONS", RequiredAccessLevel = 2, Show = true}, -- Memos, Report forms (medical report, fire incident, police incident)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,6 +1,6 @@
|
||||
Config = {}
|
||||
|
||||
Config.Flagger = {
|
||||
[`autoflagger`] = false
|
||||
[`autoflagger`] = true
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
+140
-84
@@ -4,13 +4,14 @@ local helicopter = {}
|
||||
local movementInput = false
|
||||
local isMarkersThreadActive = false
|
||||
local lastRappelKeyPress = 0
|
||||
local rappelNotifId = 0
|
||||
local pauseMenu = false
|
||||
local visionState = 0
|
||||
local currentFov = 0.0
|
||||
local fov = Config.Camera.Zoom.Max
|
||||
local tabletObj = nil
|
||||
local tabletObj = 0
|
||||
local cameraAction = false
|
||||
local instScaleform = nil
|
||||
local instScaleform = 0
|
||||
local submix = false
|
||||
local postalsActive = Config.ShowPostalCodes
|
||||
local spotlights = {}
|
||||
@@ -22,7 +23,7 @@ local markerBlips = {}
|
||||
local blipStateBagHandlers = {}
|
||||
-- 16 = INPUT_SELECT_NEXT_WEAPON, 17 = INPUT_SELECT_PREV_WEAPON, 75 = INPUT_VEH_EXIT, 80 = INPUT_VEH_CIN_CAM,
|
||||
-- 81 = INPUT_VEH_NEXT_RADIO, 82 = INPUT_VEH_PREV_RADIO, 85 = INPUT_VEH_RADIO_WHEEL, 99 = INPUT_VEH_SELECT_NEXT_WEAPON
|
||||
local controlActions = {
|
||||
local controlActions <const> = {
|
||||
16, 17, 75, 80, 81, 82, 85, 99
|
||||
}
|
||||
local sounds = {
|
||||
@@ -73,12 +74,14 @@ local camera = {
|
||||
bearing = 0
|
||||
}
|
||||
|
||||
local DrawSpotLightWithShadow = DrawSpotLightWithShadow
|
||||
local DrawCorona = Config.DrawCorona and DrawCorona or function() end -- Lazy solution
|
||||
|
||||
-- Utils --
|
||||
local function DisplayNotification(msg)
|
||||
BeginTextCommandThefeedPost("STRING")
|
||||
AddTextComponentSubstringPlayerName(msg)
|
||||
EndTextCommandThefeedPostTicker(false, false)
|
||||
return EndTextCommandThefeedPostTicker(false, false)
|
||||
|
||||
-- Comment out above and add custom notification below:
|
||||
--exports.mythic_notify:SendAlert('error', msg)
|
||||
@@ -98,12 +101,12 @@ local function DoesHelicopterHaveCamera(model, vehicle)
|
||||
end
|
||||
|
||||
local function GetHeliCameraOffset(model)
|
||||
return (Config.Helicopters[model] and Config.Helicopters[model].offset) or Config.Helicopters.default.offset
|
||||
return Config.Helicopters[model]?.offset or Config.Helicopters.default.offset
|
||||
end
|
||||
|
||||
local function CanPlayerUseCameraFromCurrentSeat(playerPed, heli, model)
|
||||
local policy = Config.PassengerOnly
|
||||
if Config.Helicopters[model] and Config.Helicopters[model].passengerOnly ~= nil then
|
||||
if Config.Helicopters[model]?.passengerOnly ~= nil then
|
||||
policy = Config.Helicopters[model].passengerOnly
|
||||
end
|
||||
|
||||
@@ -155,16 +158,11 @@ local function GetHeadingBetweenCoords(from, to)
|
||||
return heading
|
||||
end
|
||||
|
||||
---Converts `rotation` to world heading
|
||||
---@param rotation number
|
||||
---@return number heading
|
||||
local function RotationToHeading(rotation)
|
||||
local heading = rotation
|
||||
if heading < 0 then
|
||||
heading = heading*-1
|
||||
heading = heading + math.abs(heading - 180.0)*2
|
||||
end
|
||||
|
||||
heading = (heading - 360) *-1
|
||||
|
||||
return heading
|
||||
return ((rotation % 360) - 360.0) * -1
|
||||
end
|
||||
|
||||
local function RotAnglesToVec(rot)
|
||||
@@ -223,24 +221,26 @@ end
|
||||
|
||||
local function GetOffsetFromCoordsInWorldCoords(position, rotation, offset)
|
||||
local rotX, rotY, rotZ = math.rad(rotation.x), math.rad(rotation.y), math.rad(rotation.z)
|
||||
local cosX, cosY, cosZ = math.cos(rotX), math.cos(rotY), math.cos(rotZ)
|
||||
local sinX, sinY, sinZ = math.sin(rotX), math.sin(rotY), math.sin(rotZ)
|
||||
local matrix = {}
|
||||
|
||||
matrix[1] = {}
|
||||
matrix[1][1] = math.cos(rotZ) * math.cos(rotY) - math.sin(rotZ) * math.sin(rotX) * math.sin(rotY)
|
||||
matrix[1][2] = math.cos(rotY) * math.sin(rotZ) + math.cos(rotZ) * math.sin(rotX) * math.sin(rotY)
|
||||
matrix[1][3] = -math.cos(rotX) * math.sin(rotY)
|
||||
matrix[1][1] = cosZ * cosY - sinZ * sinX * sinY
|
||||
matrix[1][2] = cosY * sinZ + cosZ * sinX * sinY
|
||||
matrix[1][3] = -cosX * sinY
|
||||
matrix[1][4] = 1
|
||||
|
||||
matrix[2] = {}
|
||||
matrix[2][1] = -math.cos(rotX) * math.sin(rotZ)
|
||||
matrix[2][2] = math.cos(rotZ) * math.cos(rotX)
|
||||
matrix[2][3] = math.sin(rotX)
|
||||
matrix[2][1] = -cosX * sinZ
|
||||
matrix[2][2] = cosZ * cosX
|
||||
matrix[2][3] = sinX
|
||||
matrix[2][4] = 1
|
||||
|
||||
matrix[3] = {}
|
||||
matrix[3][1] = math.cos(rotZ) * math.sin(rotY) + math.cos(rotY) * math.sin(rotZ) * math.sin(rotX)
|
||||
matrix[3][2] = math.sin(rotZ) * math.sin(rotY) - math.cos(rotZ) * math.cos(rotY) * math.sin(rotX)
|
||||
matrix[3][3] = math.cos(rotX) * math.cos(rotY)
|
||||
matrix[3][1] = cosZ * sinY + cosY * sinZ * sinX
|
||||
matrix[3][2] = sinZ * sinY - cosZ * cosY * sinX
|
||||
matrix[3][3] = cosX * cosY
|
||||
matrix[3][4] = 1
|
||||
|
||||
matrix[4] = {}
|
||||
@@ -316,12 +316,12 @@ end
|
||||
local function LoadPostalFile(resource, file)
|
||||
local resourceState = GetResourceState(resource)
|
||||
if resourceState ~= "started" then
|
||||
print(string.format("^1ERROR: Postal resource %s was not started! It MUST be started before helicam for the postals to work! (Resource state: %s)^7", resource, resourceState))
|
||||
Config.ShowPostalCodes = false
|
||||
error(string.format("Postal resource %s was not started! It MUST be started before helicam for the postals to work! (Resource state: %s)", resource, resourceState))
|
||||
else
|
||||
local jsonFile = LoadResourceFile(resource, file)
|
||||
if jsonFile == nil then
|
||||
print(string.format("^1ERROR: The script was not able to load postals file %s from postals resource %s! Make sure that the file is loaded in the postals resource.^7", file, resource))
|
||||
error(string.format("The script was not able to load postals file %s from postals resource %s! Make sure that the file is loaded in the postals resource.", file, resource))
|
||||
else
|
||||
postals = json.decode(jsonFile)
|
||||
end
|
||||
@@ -334,17 +334,22 @@ local function SetCameraLabel()
|
||||
label = Config.ForceCameraLabel
|
||||
else
|
||||
local livery = GetVehicleLivery(helicopter.entity)
|
||||
if livery == -1 then
|
||||
livery = GetVehicleMod(helicopter.entity, 48) -- VMT_LIVERY_MOD
|
||||
end
|
||||
|
||||
local heliConfig = Config.Helicopters[helicopter.model]
|
||||
if heliConfig and heliConfig.labels then
|
||||
if heliConfig?.labels then
|
||||
if heliConfig.labels[livery] then
|
||||
label = heliConfig.labels[livery]
|
||||
else
|
||||
label = heliConfig.labels[0]
|
||||
label = heliConfig.labels[-1] or Config.Helicopters.default.labels[0]
|
||||
end
|
||||
else
|
||||
label = Config.Helicopters.default.labels[0]
|
||||
end
|
||||
end
|
||||
|
||||
SendNUIMessage({ action = 'setCameraLabel', label = label })
|
||||
end
|
||||
|
||||
@@ -359,7 +364,7 @@ end
|
||||
|
||||
local function GetHelicopterTimecycle(model)
|
||||
local heliConfig = Config.Helicopters[model]
|
||||
if heliConfig and heliConfig.timecycle ~= nil then
|
||||
if heliConfig?.timecycle ~= nil then
|
||||
return heliConfig.timecycle, heliConfig.timecycleStrength or Config.DefaultCameraTimecycleStrength
|
||||
end
|
||||
|
||||
@@ -370,9 +375,13 @@ local function DeleteTablet()
|
||||
local playerPed = PlayerPedId()
|
||||
ClearPedSecondaryTask(playerPed)
|
||||
Wait(100)
|
||||
DetachEntity(tabletObj, true, false)
|
||||
DeleteEntity(tabletObj)
|
||||
tabletObj = nil
|
||||
|
||||
if DoesEntityExist(tabletObj) then
|
||||
DetachEntity(tabletObj, true, false)
|
||||
DeleteEntity(tabletObj)
|
||||
end
|
||||
|
||||
tabletObj = 0
|
||||
end
|
||||
|
||||
local function CreateTablet()
|
||||
@@ -383,11 +392,21 @@ local function CreateTablet()
|
||||
Wait(0)
|
||||
end
|
||||
|
||||
if tablet.model then
|
||||
RequestModel(tablet.model)
|
||||
while not HasModelLoaded(tablet.model) do
|
||||
Wait(0)
|
||||
end
|
||||
end
|
||||
|
||||
local playerPed = PlayerPedId()
|
||||
local boneIndex = GetPedBoneIndex(playerPed, tablet.bone)
|
||||
|
||||
tabletObj = CreateObject(tablet.model, 0.0, 0.0, 0.0, true, true, false)
|
||||
AttachEntityToEntity(tabletObj, playerPed, boneIndex, tablet.offset.x, tablet.offset.y, tablet.offset.z, tablet.rotation.x, tablet.rotation.y, tablet.rotation.z, false, true, false, true, 1, true)
|
||||
if tablet.model then
|
||||
tabletObj = CreateObject(tablet.model, 0.0, 0.0, 0.0, true, true, false)
|
||||
AttachEntityToEntity(tabletObj, playerPed, boneIndex, tablet.offset.x, tablet.offset.y, tablet.offset.z, tablet.rotation.x, tablet.rotation.y, tablet.rotation.z, false, true, false, true, 1, true)
|
||||
SetModelAsNoLongerNeeded(tablet.model)
|
||||
end
|
||||
|
||||
TaskPlayAnim(playerPed, tablet.anim.dict, tablet.anim.name, 2.0, 2.0, -1, 49, 1.0, false, false, false)
|
||||
|
||||
@@ -396,8 +415,11 @@ local function CreateTablet()
|
||||
if not IsEntityPlayingAnim(playerPed, tablet.anim.dict, tablet.anim.name, 3) then
|
||||
TaskPlayAnim(playerPed, tablet.anim.dict, tablet.anim.name, 2.0, 2.0, -1, 49, 1.0, false, false, false)
|
||||
end
|
||||
|
||||
Wait(500)
|
||||
end
|
||||
|
||||
RemoveAnimDict(tablet.anim.dict)
|
||||
end)
|
||||
end
|
||||
|
||||
@@ -408,9 +430,8 @@ local function GetStreetAndAreaNames(streetHash, coords)
|
||||
end
|
||||
|
||||
local function SetZoomBarLevel()
|
||||
local range = Config.Camera.Zoom.Max - Config.Camera.Zoom.Min
|
||||
local percentage = (fov - Config.Camera.Zoom.Min) / range * 100
|
||||
percentage = (percentage - 100) *-1 -- Flip the values around
|
||||
-- Inverse lerp
|
||||
local percentage = (fov - Config.Camera.Zoom.Max) / (Config.Camera.Zoom.Min - Config.Camera.Zoom.Max) * 100
|
||||
|
||||
SendNUIMessage({action = 'setZoomBarLevel', percentage = percentage})
|
||||
end
|
||||
@@ -418,10 +439,23 @@ end
|
||||
local function HandleZoomInput()
|
||||
if spotlight.adjustingBrightness or spotlight.adjustingRadius then return end
|
||||
|
||||
if GetDisabledControlNormal(0, 40) ~= 0.0 then -- Zoom in
|
||||
local controls = {
|
||||
zoomIn = 40,
|
||||
zoomOut = 41
|
||||
}
|
||||
|
||||
-- Dirty fix allowing pilots to steer while using the camera on controllers
|
||||
if not IsUsingKeyboard(0) and GetPedInVehicleSeat(helicopter.entity, -1) == PlayerPedId() then
|
||||
controls = {
|
||||
zoomIn = 42,
|
||||
zoomOut = 43
|
||||
}
|
||||
end
|
||||
|
||||
if GetDisabledControlNormal(0, controls.zoomIn) ~= 0.0 then -- Zoom in
|
||||
fov = math.max(fov - Config.Camera.Zoom.Speed, Config.Camera.Zoom.Min)
|
||||
SetZoomBarLevel()
|
||||
elseif GetDisabledControlNormal(0, 41) ~= 0.0 then -- Zoom out
|
||||
elseif GetDisabledControlNormal(0, controls.zoomOut) ~= 0.0 then -- Zoom out
|
||||
fov = math.min(fov + Config.Camera.Zoom.Speed, Config.Camera.Zoom.Max)
|
||||
SetZoomBarLevel()
|
||||
end
|
||||
@@ -525,7 +559,7 @@ end
|
||||
|
||||
local function CanHelicopterUseCameraVision(model, type)
|
||||
local configAllowed = (type == "nightvision" and Config.AllowNightVision) or Config.AllowThermal
|
||||
if (configAllowed and (Config.Helicopters[model] and Config.Helicopters[model][type] ~= false)) or (Config.Helicopters[model] and Config.Helicopters[model][type]) then
|
||||
if (configAllowed and Config.Helicopters[model]?[type] ~= false) or (Config.Helicopters[model]?[type]) then
|
||||
return true
|
||||
end
|
||||
|
||||
@@ -543,7 +577,7 @@ local function EnableThermal()
|
||||
-- Reset the seethrough values
|
||||
SeethroughReset()
|
||||
|
||||
-- Big thanks goes to BrD for making the black & white thermal posible!
|
||||
-- Big thanks goes to BrD for making the black & white thermal possible!
|
||||
if Config.ThermalOptions.CustomColours then
|
||||
-- Some of these are relative to eachother
|
||||
SetVisualSettingFloat("seeThrough.ColorVisibleHot.red", Config.ThermalOptions.Colours.VisibleHot.R)
|
||||
@@ -793,22 +827,39 @@ local function AttemptRappel(wasKeyPress)
|
||||
return
|
||||
end
|
||||
|
||||
local coords = GetEntityCoords(helicopter.entity)
|
||||
local foundHeight, groundZ = GetGroundZFor_3dCoord(coords.x, coords.y, coords.z, false)
|
||||
if not foundHeight or coords.z - groundZ > Config.MaxRappellingHight then
|
||||
DisplayNotification(Config.Localisation.Notification.ToHighToRappel)
|
||||
if GetEntitySpeed(helicopter.entity) > Config.MaxHeliSpeedRappel then
|
||||
DisplayNotification(Config.Localisation.Notification.TooFastToRappel)
|
||||
return
|
||||
end
|
||||
|
||||
local taskStatus = GetScriptTaskStatus(playerPed, `SCRIPT_TASK_RAPPEL_FROM_HELI`)
|
||||
if taskStatus == 0 or taskStatus == 1 then
|
||||
DisplayNotification(Config.Localisation.Notification.AlreadyRappelling)
|
||||
return
|
||||
end
|
||||
|
||||
if GetEntityHeightAboveGround(helicopter.entity) > Config.MaxRappellingHight then
|
||||
DisplayNotification(Config.Localisation.Notification.TooHighToRappel)
|
||||
return
|
||||
end
|
||||
|
||||
-- TODO: Add option to hold down x, rather then having to press it twice
|
||||
if wasKeyPress and (lastRappelKeyPress == 0 or (lastRappelKeyPress + Config.RappellingTimeout < GetGameTimer())) then
|
||||
lastRappelKeyPress = GetGameTimer()
|
||||
DisplayNotification(Config.Localisation.Notification.ConfirmRappel)
|
||||
rappelNotifId = DisplayNotification(Config.Localisation.Notification.ConfirmRappel)
|
||||
else
|
||||
lastRappelKeyPress = 0
|
||||
|
||||
if rappelNotifId and rappelNotifId ~= 0 then
|
||||
ThefeedRemoveItem(rappelNotifId)
|
||||
rappelNotifId = 0
|
||||
end
|
||||
|
||||
EmitSound(sounds.rappel, "SELECT", "HUD_FRONTEND_DEFAULT_SOUNDSET")
|
||||
DisplayNotification(Config.Localisation.Notification.Rappelling)
|
||||
|
||||
TaskRappelFromHeli(playerPed, 1)
|
||||
ClearPedTasks(playerPed)
|
||||
TaskRappelFromHeli(playerPed, 10)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -879,7 +930,7 @@ local function DoesAnyHeliHaveSpotlightOverwrite()
|
||||
end
|
||||
|
||||
local function CanHelicopterUseSpotlight(model)
|
||||
if (Config.AllowSpotlight and (Config.Helicopters[model] and Config.Helicopters[model].spotlight ~= false)) or (Config.Helicopters[model] and Config.Helicopters[model].spotlight) then
|
||||
if (Config.AllowSpotlight and Config.Helicopters[model]?.spotlight ~= false) or Config.Helicopters[model]?.spotlight then
|
||||
return true
|
||||
end
|
||||
|
||||
@@ -937,6 +988,7 @@ local function SpotlightThread()
|
||||
position = camCoords + direction
|
||||
|
||||
DrawSpotLightWithShadow(position.x, position.y, position.z, direction.x, direction.y, direction.z, Config.Spotlight.Colour.R, Config.Spotlight.Colour.G, Config.Spotlight.Colour.B, Config.Spotlight.MaxDistance, spotlight.brightness, Config.Spotlight.Roundness, spotlight.radius, Config.Spotlight.Falloff, 0)
|
||||
DrawCorona(position.x, position.y, position.z, Config.Corona.Size, Config.Corona.Colour.R, Config.Corona.Colour.G, Config.Corona.Colour.B, Config.Corona.Colour.A, Config.Corona.Intensity, Config.Corona.ZBias, direction.x, direction.y, direction.z, Config.Corona.ViewThreshold, Config.Corona.InnerAngle, Config.Corona.OuterAngle, Config.Corona.Flags)
|
||||
Wait(0)
|
||||
end
|
||||
end)
|
||||
@@ -1003,6 +1055,7 @@ local function ForeignSpotlightThread()
|
||||
while not IsTableEmpty(spotlights) do
|
||||
for _netId, data in pairs(spotlights) do
|
||||
DrawSpotLightWithShadow(data.position.x, data.position.y, data.position.z, data.direction.x, data.direction.y, data.direction.z, Config.Spotlight.Colour.R, Config.Spotlight.Colour.G, Config.Spotlight.Colour.B, Config.Spotlight.MaxDistance, data.brightness+0.0, Config.Spotlight.Roundness, data.radius+0.0, Config.Spotlight.Falloff, 0)
|
||||
DrawCorona(data.position.x, data.position.y, data.position.z, Config.Corona.Size, Config.Corona.Colour.R, Config.Corona.Colour.G, Config.Corona.Colour.B, Config.Corona.Colour.A, Config.Corona.Intensity, Config.Corona.ZBias, data.direction.x, data.direction.y, data.direction.z, Config.Corona.ViewThreshold, Config.Corona.InnerAngle, Config.Corona.OuterAngle, Config.Corona.Flags)
|
||||
end
|
||||
Wait(0)
|
||||
end
|
||||
@@ -1181,27 +1234,21 @@ local function FetchAndApplyBlipStateBags(heliEntity)
|
||||
end
|
||||
end
|
||||
|
||||
local function RegisterBlipStateBags()
|
||||
local function RegisterBlipStateBags(netId)
|
||||
local bagFilter = 'entity:'..netId
|
||||
|
||||
if Config.TargetBlip.Display then
|
||||
blipStateBagHandlers.heliCamTargetBlip = AddStateBagChangeHandler('heliCamTargetBlip', nil, function(bagName, key, value, _unused, replicated)
|
||||
local entity = GetEntityFromStateBagName(bagName)
|
||||
local vehicle = helicopter.entity or GetVehiclePedIsIn(PlayerPedId(), false)
|
||||
if entity == vehicle then
|
||||
HandleTargetBlip(value)
|
||||
end
|
||||
blipStateBagHandlers.heliCamTargetBlip = AddStateBagChangeHandler('heliCamTargetBlip', bagFilter, function(bagName, key, value, _unused, replicated)
|
||||
HandleTargetBlip(value)
|
||||
end)
|
||||
end
|
||||
|
||||
if Config.AllowMarkers then
|
||||
blipStateBagHandlers.heliCamMarkers = AddStateBagChangeHandler('heliCamMarkers', nil, function(bagName, key, value, _unused, replicated)
|
||||
local entity = GetEntityFromStateBagName(bagName)
|
||||
local vehicle = helicopter.entity or GetVehiclePedIsIn(PlayerPedId(), false)
|
||||
if entity == vehicle then
|
||||
markers = value
|
||||
UpdateMarkerBlips()
|
||||
if not isMarkersThreadActive then
|
||||
MarkersThread()
|
||||
end
|
||||
blipStateBagHandlers.heliCamMarkers = AddStateBagChangeHandler('heliCamMarkers', bagFilter, function(bagName, key, value, _unused, replicated)
|
||||
markers = value
|
||||
UpdateMarkerBlips()
|
||||
if not isMarkersThreadActive then
|
||||
MarkersThread()
|
||||
end
|
||||
end)
|
||||
end
|
||||
@@ -1238,7 +1285,7 @@ local function ExitHeliCamera()
|
||||
-- Close NUI
|
||||
SendNUIMessage({ action = 'close' })
|
||||
|
||||
-- Disable night-/therma-vision if enabled
|
||||
-- Disable night-/thermal-vision if enabled
|
||||
if visionState ~= 0 then
|
||||
DisableVision()
|
||||
end
|
||||
@@ -1250,6 +1297,7 @@ local function ExitHeliCamera()
|
||||
|
||||
if Config.InstructionButtons then
|
||||
SetScaleformMovieAsNoLongerNeeded(instScaleform)
|
||||
instScaleform = 0
|
||||
end
|
||||
|
||||
if not submix and Config.NoSubmixInCamera then
|
||||
@@ -1344,6 +1392,7 @@ local function OnEnteredVehicle(vehicle)
|
||||
while helicopter.entity ~= nil and helicopter.entity ~= 0 do
|
||||
Wait(0)
|
||||
end
|
||||
|
||||
Wait(100)
|
||||
end
|
||||
|
||||
@@ -1351,7 +1400,7 @@ local function OnEnteredVehicle(vehicle)
|
||||
helicopter.netId = VehToNet(vehicle)
|
||||
helicopter.model = model
|
||||
|
||||
RegisterBlipStateBags()
|
||||
RegisterBlipStateBags(helicopter.netId)
|
||||
FetchAndApplyBlipStateBags(vehicle)
|
||||
InHelicopterThread()
|
||||
end)
|
||||
@@ -1391,6 +1440,9 @@ local function CollectAndSendData()
|
||||
local minute = GetClockMinutes()
|
||||
|
||||
info.time = ("%.2d"):format((hour == 0) and 12 or hour) .. ":" .. ("%.2d"):format(minute)
|
||||
else
|
||||
-- Force update time
|
||||
info.time = false
|
||||
end
|
||||
|
||||
local setData = {}
|
||||
@@ -1555,13 +1607,11 @@ local function CollectAndSendData()
|
||||
end
|
||||
end
|
||||
|
||||
if not IsTableEmpty(info) or not IsTableEmpty(setData) then
|
||||
SendNUIMessage({
|
||||
action = 'updateData',
|
||||
info = info,
|
||||
set = setData
|
||||
})
|
||||
end
|
||||
SendNUIMessage({
|
||||
action = 'updateData',
|
||||
info = info,
|
||||
set = setData
|
||||
})
|
||||
end
|
||||
|
||||
local function UpdateUIHeadingPitchAndBearing()
|
||||
@@ -1631,7 +1681,7 @@ end
|
||||
local function PostalLoop()
|
||||
CreateThread(function()
|
||||
while inHeliCam and postalsActive do
|
||||
local coords = cache.target.position and cache.target.position.xy or cache.helicopter.coords.xy
|
||||
local coords = cache.target.position?.xy or cache.helicopter.coords.xy
|
||||
local inDistance = {}
|
||||
|
||||
for _index, data in pairs(postals) do
|
||||
@@ -1706,7 +1756,11 @@ end
|
||||
|
||||
local function UseHeliCamera()
|
||||
if helicopter.model == nil or helicopter.entity == nil then
|
||||
print("^1ERROR: helicopter model or entity was nil, this is fatal and will cause issues!^7")
|
||||
error("helicopter model or entity was nil, this is fatal and will cause issues!")
|
||||
end
|
||||
|
||||
if not DoesEntityExist(helicopter.entity) then
|
||||
return warn("helicopter entity does not exist, aborting entering camera")
|
||||
end
|
||||
|
||||
cameraAction = true
|
||||
@@ -1778,8 +1832,7 @@ end
|
||||
|
||||
|
||||
-- Events --
|
||||
RegisterNetEvent('helicam:enterCamera')
|
||||
AddEventHandler('helicam:enterCamera', function(state)
|
||||
RegisterNetEvent('helicam:enterCamera', function(state)
|
||||
if state then
|
||||
UseHeliCamera()
|
||||
else
|
||||
@@ -1856,14 +1909,15 @@ if Config.AllowMarkers then
|
||||
end
|
||||
|
||||
if Config.AllowRappelling then
|
||||
RegisterKeyMapping('+rappel', Config.Localisation.KeyMapping.Rappel, Config.Keybinds.Rappel.Type, Config.Keybinds.Rappel.Key)
|
||||
RegisterCommand('rappel', function()
|
||||
AttemptRappel(false)
|
||||
end, false)
|
||||
RegisterCommand('+rappel', function()
|
||||
|
||||
RegisterKeyMapping('+helicam_rappel', Config.Localisation.KeyMapping.Rappel, Config.Keybinds.Rappel.Type, Config.Keybinds.Rappel.Key)
|
||||
RegisterCommand('+helicam_rappel', function()
|
||||
AttemptRappel(true)
|
||||
end, false)
|
||||
RegisterCommand('-rappel', function()
|
||||
RegisterCommand('-helicam_rappel', function()
|
||||
-- This is just a place holder to prevent "unknown command" messages in chat
|
||||
end, false)
|
||||
end
|
||||
@@ -1950,7 +2004,9 @@ CreateThread(function()
|
||||
|
||||
if Config.AddChatSuggestions then
|
||||
TriggerEvent('chat:addSuggestion', '/helicam', Config.Localisation.ChatSuggestions.ToggleCamera)
|
||||
TriggerEvent('chat:addSuggestion', '/rappel', Config.Localisation.ChatSuggestions.Rappel)
|
||||
if Config.AllowRappelling then
|
||||
TriggerEvent('chat:addSuggestion', '/rappel', Config.Localisation.ChatSuggestions.Rappel)
|
||||
end
|
||||
end
|
||||
|
||||
if Config.ShowPostalCodes then
|
||||
@@ -1958,7 +2014,7 @@ CreateThread(function()
|
||||
end
|
||||
|
||||
if type(Config.DefaultCameraTimecycleStrength) ~= "number" then
|
||||
print(string.format("^1ERROR: Config.DefaultCameraTimecycleStrength is invalid, it needs to be a number! Current type: %s, current value: %s.^7", type(Config.DefaultCameraTimecycleStrength), Config.CameraTimecycleStrength))
|
||||
warn(string.format("Config.DefaultCameraTimecycleStrength is invalid, it must be a number! Current type: %s, current value: %s.", type(Config.DefaultCameraTimecycleStrength), Config.CameraTimecycleStrength))
|
||||
Config.DefaultCameraTimecycleStrength = 0.5
|
||||
end
|
||||
|
||||
@@ -2009,11 +2065,11 @@ AddEventHandler('onResourceStop', function(resourceName)
|
||||
return
|
||||
end
|
||||
|
||||
if DoesEntityExist(tabletObj) then
|
||||
if tabletObj ~= 0 and DoesEntityExist(tabletObj) then
|
||||
ClearPedSecondaryTask(PlayerPedId())
|
||||
DetachEntity(tabletObj, true, false)
|
||||
DeleteEntity(tabletObj)
|
||||
tabletObj = nil
|
||||
tabletObj = 0
|
||||
end
|
||||
|
||||
if inHeliCam then
|
||||
|
||||
+119
-28
@@ -50,8 +50,9 @@ Config.NoSubmixInCamera = false -- Only applys if Config.UseSubmix is set to tru
|
||||
|
||||
-- If true, players will be able to rappel from helicopters that support it.
|
||||
Config.AllowRappelling = true
|
||||
Config.RappellingTimeout = 1000 -- The time in ms that you have to press the rappel button again (so people don't accidentally rappel)
|
||||
Config.MaxRappellingHight = 35.0 -- At any higher then 35.0 players might fall off the rope as the game has a hardcoded cap around 30.0 - 40.0 meters.
|
||||
Config.RappellingTimeout = 1500 -- The time in ms that you have to press the rappel button again (so people don't accidentally rappel)
|
||||
Config.MaxRappellingHight = 35.0 -- At any higher then ~35.0 players might fall off the rope as the game has a hardcoded cap around 30.0 - 40.0 meters (set to 40 in decomplied scripts).
|
||||
Config.MaxHeliSpeedRappel = 10.0 -- The maximum speed the helicopter can travel and still allow people to start rappeling
|
||||
|
||||
-- If the script should add chat suggestions for some of the chat commands.
|
||||
Config.AddChatSuggestions = true
|
||||
@@ -74,6 +75,23 @@ Config.Spotlight = {
|
||||
Falloff = 200.0, --
|
||||
}
|
||||
|
||||
-- Corona
|
||||
-- true or false, if we should draw a corona at the spotlight position
|
||||
-- Please note that the corona can look a little off from certian angles. It's just how it is until I rework the entire spotlight system.
|
||||
Config.DrawCorona = true
|
||||
|
||||
-- See https://docs.fivem.net/natives/?_0xFF44780E for documentation
|
||||
Config.Corona = {
|
||||
Size = 10.0,
|
||||
Colour = { R = 255, G = 255, B = 255, A = 255 },
|
||||
Intensity = 600.0,
|
||||
ZBias = 0.9,
|
||||
ViewThreshold = 600.0,
|
||||
InnerAngle = 0.0,
|
||||
OuterAngle = 90.0,
|
||||
Flags = 2
|
||||
}
|
||||
|
||||
Config.HideMinimap = false
|
||||
Config.ZoomBarOffset = 20 -- The offset in % from the bottom of the screen the zoom bar will be when the minimap is enabled. (If you have something on the top of your minimap then setting it to 25 usally works well)
|
||||
Config.TargetBlip = {
|
||||
@@ -126,7 +144,7 @@ Config.Marker = {
|
||||
|
||||
Config.UseAnimProp = true -- If true, players will have a tablet in their hands while using the camera
|
||||
Config.Tablet = {
|
||||
model = -1585232418, -- prop_cs_tablet
|
||||
model = `prop_cs_tablet`,
|
||||
anim = {
|
||||
dict = "amb@world_human_seat_wall_tablet@female@base",
|
||||
name = "base"
|
||||
@@ -145,7 +163,7 @@ Config.InstructionButtons = {
|
||||
-- [2] = { control = "~INPUT_DB481F5~", label = "Lock Camera" }, -- This doesn't work for some reason...
|
||||
[0] = { control = "~INPUT_662F7BF5~", label = "Add/Remove Marker" },
|
||||
[1] = { control = "~INPUT_DB471A88~", label = "Cycle Vision" },
|
||||
[2] = { control = "~INPUT_51D50495~", label = "Spotlight" },
|
||||
[2] = { control = "~INPUT_EED83822~", label = "Spotlight" },
|
||||
[3] = { control = "~INPUT_5D25DCCD~", label = "Exit Camera" }
|
||||
}
|
||||
|
||||
@@ -239,7 +257,9 @@ Config.Localisation = {
|
||||
SpotlightGlobalLimit = "The global spotlight limit has been reached!",
|
||||
CannotRappelFromHeli = "This helicopter does not support rappelling!",
|
||||
CannotRappelFromSeat = "You cannot rappel from this seat!",
|
||||
ToHighToRappel = "The helicopter is to far up to rappel!",
|
||||
TooFastToRappel = "The helicopter is traveling too fast for you to rappel!",
|
||||
TooHighToRappel = "The helicopter is too far up to rappel!",
|
||||
AlreadyRappelling = "You are already rappelling!",
|
||||
ConfirmRappel = "Are you sure you want to rappel? (Press again to confirm)",
|
||||
Rappelling = "Rappelling!"
|
||||
},
|
||||
@@ -280,66 +300,137 @@ Config.Helicopters = {
|
||||
offset = vector3(0.0, 0.0, -1.0),
|
||||
-- nightvision = true, -- These are only needed/used if Config.AllowNightVision or Config.AllowThermal is set to false
|
||||
-- thermalvision = true, -- You can add these to each and every model, adding these and setting them to false disables the vision even if Config.AllowThermal etc. is set to true
|
||||
-- spotlight = true, -- Allows yo overwrite Config.AllowSpotlight on a helicopter to helicopter basis.
|
||||
-- spotlight = true, -- Allows you overwrite Config.AllowSpotlight on a helicopter-to-helicopter basis.
|
||||
-- passengerOnly = false, -- Set's who can use the camera based on the seat they are in. (see Config.PassengerOnly)
|
||||
-- disableRappelling = false, -- Disables rappelling for the helicopter model, will only make a diffrence when set to true. The helicopter also needs the "FLAG_ALLOWS_RAPPEL" flag too allow you to rappel out of it.
|
||||
-- timecycle = "CAMERA_BW", -- The timecycle modifer name (can be set to false if you want to disable it)
|
||||
-- timecycleStrength = 0.5, -- The strength of the timecycle, defaults to Config.DefaultCameraTimecycleStrength if not included.
|
||||
labels = {
|
||||
[0] = "FLIR SYSTEMS"
|
||||
[0] = "FLARE SYSTEMS"
|
||||
}
|
||||
},
|
||||
-- Police Maverick (polmav)
|
||||
[353883353] = {
|
||||
-- Police Maverick
|
||||
[`polmav`] = {
|
||||
offset = vector3(0.0, 2.65, -1.0),
|
||||
labels = { -- Liveries
|
||||
[0] = "LOS SANTOS POLICE DEPARTMENT", -- 0 is default
|
||||
[1] = "AIR AMBULANCE"
|
||||
}
|
||||
},
|
||||
-- Maverick (maverick)
|
||||
[-1660661558] = {
|
||||
-- Maverick
|
||||
[`maverick`] = {
|
||||
offset = vector3(0.0, 3.45, -0.65)
|
||||
},
|
||||
-- Buzzard Attack Chopper (buzzard)
|
||||
[788747387] = {
|
||||
-- Higgins Helitours Maverick
|
||||
[`maverick2`] = {
|
||||
offset = vector3(0.0, 3.45, -0.65),
|
||||
labels = {
|
||||
[-1] = "HIGGINS HELITOURS",
|
||||
}
|
||||
},
|
||||
-- Buzzard Attack Chopper
|
||||
[`buzzard`] = {
|
||||
offset = vector3(0.0, 2.15, -0.35)
|
||||
},
|
||||
-- Buzzard (buzzard2)
|
||||
[745926877] = {
|
||||
-- Buzzard
|
||||
[`buzzard2`] = {
|
||||
offset = vector3(0.0, 2.15, -0.35)
|
||||
},
|
||||
-- Frogger (frogger)
|
||||
[744705981] = {
|
||||
-- Frogger
|
||||
[`frogger`] = {
|
||||
offset = vector3(0.0, 3.0, -0.35)
|
||||
},
|
||||
-- TPI/FIB Frogger (frogger2)
|
||||
[1949211328] = {
|
||||
-- TPI/FIB Frogger
|
||||
[`frogger2`] = {
|
||||
offset = vector3(0.0, 3.0, -0.35),
|
||||
labels = { -- Liveries
|
||||
[0] = "FEDERAL INVESTIGATION BUREAU",
|
||||
[1] = "TREVOR PHILIPS ENTERPRISES"
|
||||
}
|
||||
},
|
||||
-- Annihilator/Patriotism and Immigration Authority (annihilator)
|
||||
[837858166] = {
|
||||
-- Annihilator/Patriotism and Immigration Authority
|
||||
[`annihilator`] = {
|
||||
offset = vector3(-0.5, 4.0, -0.35),
|
||||
labels = { -- Liveries
|
||||
[0] = "NATIONAL OFFICE OF SECURITY ENFORCMENT"
|
||||
[-1] = "NATIONAL OFFICE OF SECURITY ENFORCMENT"
|
||||
}
|
||||
},
|
||||
-- Valkyrie (valkyrie)
|
||||
[-1600252419] = {
|
||||
-- Valkyrie
|
||||
[`valkyrie`] = {
|
||||
offset = vector3(0.0, 4.0, -1.15),
|
||||
labels = { -- Liveries
|
||||
[0] = "UNITED STATES ARMY"
|
||||
[-1] = "UNITED STATES ARMY"
|
||||
}
|
||||
},
|
||||
-- Avenger (avenger)
|
||||
[-2118308144] = {
|
||||
-- Avenger
|
||||
[`avenger`] = {
|
||||
offset = vector3(0.0, 9.45, -2.45),
|
||||
labels = { -- Liveries
|
||||
[0] = "UNITED STATES MARINES"
|
||||
[-1] = "UNITED STATES MARINES"
|
||||
}
|
||||
},
|
||||
-- Avenger
|
||||
[`avenger2`] = {
|
||||
offset = vector3(0.0, 9.45, -2.45),
|
||||
labels = { -- Liveries
|
||||
[-1] = "UNITED STATES MARINES"
|
||||
}
|
||||
},
|
||||
-- Avenger
|
||||
[`avenger3`] = {
|
||||
offset = vector3(0.0, 9.45, -2.45),
|
||||
labels = { -- Liveries
|
||||
[-1] = "UNITED STATES MARINES"
|
||||
}
|
||||
},
|
||||
-- Akula
|
||||
[`akula`] = {
|
||||
offset = vector3(0.0, 8.55, -1.05),
|
||||
labels = { -- Liveries
|
||||
[-1] = "BOEHHO-ВОЗДУШНЫЕ СИЛЫ CCCP"
|
||||
}
|
||||
},
|
||||
-- Weaponized Conada
|
||||
[`conada2`] = {
|
||||
offset = vector3(0.0, 2.65, -0.60),
|
||||
labels = {
|
||||
[1] = "LOS SANTOS NATIONAL FORCES",
|
||||
[2] = "AIR FORCE",
|
||||
[4] = "UNITED STATES ARMY",
|
||||
[8] = "FORT ZANCUDO AIR FORCE",
|
||||
[13] = "UNITED STATES AIR FORCE",
|
||||
[14] = "UNITED STATES AIR FORCE",
|
||||
[15] = "LOS SANTOS NATIONAL FORCES",
|
||||
[17] = "UNITED STATES AIR FORCE",
|
||||
[19] = "UNITED STATES ARMY"
|
||||
}
|
||||
},
|
||||
-- DH-7 Iron Mule
|
||||
[`cargobob5`] = {
|
||||
offset = vector3(-1.25, 5.1, -0.40),
|
||||
labels = {
|
||||
[0] = "MERRYWEATHER SECURITY",
|
||||
[1] = "NATIONAL COAST GUARD",
|
||||
[2] = "UNITED STATES NAVY",
|
||||
[3] = "UNITED STATES MARINES"
|
||||
}
|
||||
},
|
||||
-- Duster 300-H
|
||||
[`duster2`] = {
|
||||
offset = vector3(0.0, 0.8, -0.75),
|
||||
labels = {
|
||||
[1] = "FORT ZANCUDO AIR FORCE"
|
||||
}
|
||||
},
|
||||
-- Titan 250 D
|
||||
[`titan2`] = {
|
||||
offset = vector3(0.0, 7.15, -1.85),
|
||||
labels = {
|
||||
[2] = "UNITED STATES AIR FORCE",
|
||||
[3] = "UNITED STATES AIR FORCE",
|
||||
[4] = "UNITED STATES AIR FORCE",
|
||||
[5] = "PIßWASSER",
|
||||
[7] = "COAST GUARD",
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
if GetResourceState('es_extended') ~= 'started' then return end
|
||||
|
||||
ESX = exports.es_extended:getSharedObject()
|
||||
local ESX = exports.es_extended:getSharedObject()
|
||||
|
||||
function JobCheck()
|
||||
if Config.WhitelistedJobs == false then
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
if GetResourceState('qb-core') ~= 'started' then return end
|
||||
|
||||
QBCore = exports['qb-core']:GetCoreObject()
|
||||
local QBCore = exports['qb-core']:GetCoreObject()
|
||||
|
||||
function JobCheck()
|
||||
if Config.WhitelistedJobs == false then
|
||||
|
||||
@@ -4,41 +4,41 @@ lua54 'yes'
|
||||
|
||||
author 'Mads'
|
||||
description 'Helicam'
|
||||
version '1.0.9'
|
||||
version '1.1.0'
|
||||
|
||||
client_scripts {
|
||||
'config.lua',
|
||||
'numberplates.lua',
|
||||
'framework/standalone.lua',
|
||||
'framework/esx.lua',
|
||||
'framework/qb.lua',
|
||||
'client.lua'
|
||||
'config.lua',
|
||||
'numberplates.lua',
|
||||
'framework/standalone.lua',
|
||||
'framework/esx.lua',
|
||||
'framework/qb.lua',
|
||||
'client.lua'
|
||||
}
|
||||
|
||||
server_script 'server.lua'
|
||||
|
||||
escrow_ignore {
|
||||
'config.lua',
|
||||
'numberplates.lua',
|
||||
'framework/standalone.lua',
|
||||
'framework/esx.lua',
|
||||
'framework/qb.lua',
|
||||
'client.lua',
|
||||
'server.lua'
|
||||
'config.lua',
|
||||
'numberplates.lua',
|
||||
'framework/standalone.lua',
|
||||
'framework/esx.lua',
|
||||
'framework/qb.lua',
|
||||
'client.lua',
|
||||
'server.lua'
|
||||
}
|
||||
|
||||
ui_page('html/index.html')
|
||||
|
||||
files {
|
||||
'html/index.html',
|
||||
'html/script.js',
|
||||
'html/style.css',
|
||||
'html/images/*.svg'
|
||||
'html/index.html',
|
||||
'html/script.js',
|
||||
'html/style.css',
|
||||
'html/images/*.svg',
|
||||
}
|
||||
|
||||
dependencies {
|
||||
'/server:5181',
|
||||
'/gameBuild:2060' -- Needed due to usage of game events.
|
||||
'/server:5181',
|
||||
'/gameBuild:2060' -- Needed due to usage of game events.
|
||||
}
|
||||
|
||||
dependency '/assetpacks'
|
||||
@@ -4,7 +4,8 @@ window.onload = (e) => {
|
||||
|
||||
let config = {
|
||||
timeFormat: 0,
|
||||
dateFormat: 0
|
||||
dateFormat: 0,
|
||||
showLicensePlate: true
|
||||
};
|
||||
let lastZoomBarLength = 243; // (243px, default for 1920:1080)
|
||||
const months = {
|
||||
@@ -81,8 +82,8 @@ function onMessageRecieved(event) {
|
||||
if (data.info.numberplate == false) {
|
||||
$("#numberplate-wrapper").hide();
|
||||
} else if (data.info.numberplate != undefined) {
|
||||
$("#ta-numberplate").text(data.info.numberplate);
|
||||
if (!$("#numberplate-wrapper").is(":visible")) {
|
||||
if (config.showLicensePlate) {
|
||||
$("#ta-numberplate").text(data.info.numberplate);
|
||||
$("#numberplate-wrapper").show();
|
||||
};
|
||||
};
|
||||
@@ -177,6 +178,7 @@ function onMessageRecieved(event) {
|
||||
};
|
||||
|
||||
if (data.showLicensePlate == false) {
|
||||
config.showLicensePlate = false;
|
||||
$("#numberplate-wrapper").hide();
|
||||
};
|
||||
|
||||
|
||||
@@ -358,7 +358,3 @@ Note: if you are going to change the colour, remember to also change it inside t
|
||||
|
||||
position: absolute;
|
||||
} */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,9 +1,22 @@
|
||||
-- Yes, I went trough every single GTA 5 vehicle, please send help.
|
||||
local vehicleNumberPlates = {
|
||||
['default'] = {
|
||||
-- Used with GetVehiclePlateType, so just ignore --
|
||||
[0] = {
|
||||
front = { static = true },
|
||||
rear = { static = true }
|
||||
},
|
||||
[1] = {
|
||||
front = { static = true },
|
||||
rear = false
|
||||
},
|
||||
[2] = {
|
||||
front = false,
|
||||
rear = { static = true }
|
||||
},
|
||||
[3] = {
|
||||
front = false,
|
||||
rear = false
|
||||
},
|
||||
|
||||
-- Commercials --
|
||||
-- Benson (benson)
|
||||
@@ -11,6 +24,11 @@ local vehicleNumberPlates = {
|
||||
front = { onBumper = true },
|
||||
rear = false
|
||||
},
|
||||
-- Benson (Cluckin' Bell)
|
||||
[`benson2`] = {
|
||||
front = { onBumper = true },
|
||||
rear = false
|
||||
},
|
||||
-- Biff (biff)
|
||||
[850991848] = {
|
||||
front = { onBumper = true },
|
||||
@@ -81,6 +99,11 @@ local vehicleNumberPlates = {
|
||||
front = { onBumper = true },
|
||||
rear = { static = true }
|
||||
},
|
||||
-- Phantom
|
||||
[`phantom4`] = {
|
||||
front = { onBumper = true },
|
||||
rear = { static = true }
|
||||
},
|
||||
-- Pounder (pounder)
|
||||
[2112052861] = {
|
||||
front = { onBumper = true },
|
||||
@@ -240,6 +263,11 @@ local vehicleNumberPlates = {
|
||||
front = false,
|
||||
rear = { onTrunk = true }
|
||||
},
|
||||
-- FR36
|
||||
[`fr36`] = {
|
||||
front = false,
|
||||
rear = { onBumper = true }
|
||||
},
|
||||
-- Jackal
|
||||
[-624529134] = {
|
||||
front = false,
|
||||
@@ -337,6 +365,11 @@ local vehicleNumberPlates = {
|
||||
front = { onBumper = true },
|
||||
rear = { onBumper = true }
|
||||
},
|
||||
-- Gauntlet Interceptor
|
||||
[`polgauntlet`] = {
|
||||
front = false,
|
||||
rear = { onBumper = true }
|
||||
},
|
||||
-- Police Cruiser (police)
|
||||
[2046537925] = {
|
||||
front = { onBumper = true },
|
||||
@@ -357,6 +390,11 @@ local vehicleNumberPlates = {
|
||||
front = { onBumper = true },
|
||||
rear = { static = true }
|
||||
},
|
||||
-- Stanier LE Cruiser
|
||||
[`police5`] = {
|
||||
front = { onBumper = true },
|
||||
rear = { static = true }
|
||||
},
|
||||
-- Police Rancher (policeold1)
|
||||
[-1536924937] = {
|
||||
front = { onBumper = true },
|
||||
@@ -840,6 +878,11 @@ local vehicleNumberPlates = {
|
||||
front = { onBumper = true },
|
||||
rear = { onBumper = true }
|
||||
},
|
||||
-- Brigham
|
||||
[`brigham`] = {
|
||||
front = { onBumper = true },
|
||||
rear = { onBumper = true }
|
||||
},
|
||||
-- Broadway (broadway)
|
||||
[-1933242328] = {
|
||||
front = { onBumper = true },
|
||||
@@ -860,6 +903,11 @@ local vehicleNumberPlates = {
|
||||
front = false,
|
||||
rear = { onBumper = true }
|
||||
},
|
||||
-- Buffalo EVX
|
||||
[`buffalo5`] = {
|
||||
front = false,
|
||||
rear = { onBumper = true }
|
||||
},
|
||||
-- Chino
|
||||
[349605904] = {
|
||||
front = { onBumper = true },
|
||||
@@ -875,6 +923,11 @@ local vehicleNumberPlates = {
|
||||
front = false,
|
||||
rear = { onTrunk = true }
|
||||
},
|
||||
-- Clique Wagon
|
||||
[`clique2`] = {
|
||||
front = false,
|
||||
rear = { onTrunk = true }
|
||||
},
|
||||
-- Deviant (deviant)
|
||||
[1279262537] = {
|
||||
front = false,
|
||||
@@ -920,6 +973,11 @@ local vehicleNumberPlates = {
|
||||
front = false,
|
||||
rear = { onBumper = true }
|
||||
},
|
||||
-- Dominator GT
|
||||
[`dominator9`] = {
|
||||
front = false,
|
||||
rear = { onBumper = true }
|
||||
},
|
||||
-- Dukes
|
||||
[723973206] = {
|
||||
front = false,
|
||||
@@ -985,6 +1043,11 @@ local vehicleNumberPlates = {
|
||||
front = false,
|
||||
rear = { static = true }
|
||||
},
|
||||
-- Hotring Hellfire
|
||||
[`gauntlet6`] = {
|
||||
front = false,
|
||||
rear = false
|
||||
},
|
||||
-- Greenwood (greenwood)
|
||||
[40817712] = {
|
||||
front = false,
|
||||
@@ -1025,6 +1088,16 @@ local vehicleNumberPlates = {
|
||||
front = false,
|
||||
rear = { onBumper = true }
|
||||
},
|
||||
-- Impaler
|
||||
[`impaler5`] = {
|
||||
front = false,
|
||||
rear = { static = true }
|
||||
},
|
||||
-- Impaler LX
|
||||
[`impaler6`] = {
|
||||
front = { onBumper = true },
|
||||
rear = { static = true }
|
||||
},
|
||||
-- Apocalypse Imperator (imperator)
|
||||
[444994115] = {
|
||||
front = false,
|
||||
@@ -1181,15 +1254,20 @@ local vehicleNumberPlates = {
|
||||
rear = { onBumper = true }
|
||||
},
|
||||
-- Vigero
|
||||
[-825837129] = {
|
||||
front = { static = true },
|
||||
rear = false
|
||||
[`vigero`] = {
|
||||
front = false,
|
||||
rear = { static = true }
|
||||
},
|
||||
-- Vigero ZX (vigero2)
|
||||
[-1758379524] = {
|
||||
front = false,
|
||||
rear = { onBumper = true }
|
||||
},
|
||||
-- Vigero ZX Convertible
|
||||
[`vigero3`] = {
|
||||
front = false,
|
||||
rear = { onBumper = true }
|
||||
},
|
||||
-- Virgo
|
||||
[-498054846] = {
|
||||
front = { onBumper = true },
|
||||
@@ -1402,6 +1480,11 @@ local vehicleNumberPlates = {
|
||||
front = { onBumper = true },
|
||||
rear = { onBumper = true }
|
||||
},
|
||||
-- Walton L35
|
||||
[`l35`] = {
|
||||
front = false,
|
||||
rear = { onBumper = true }
|
||||
},
|
||||
-- Lguard
|
||||
[469291905] = {
|
||||
front = false,
|
||||
@@ -1432,6 +1515,11 @@ local vehicleNumberPlates = {
|
||||
front = false,
|
||||
rear = { static = true }
|
||||
},
|
||||
-- MonstroCiti
|
||||
[`monstrociti`] = {
|
||||
front = { onBumper = true },
|
||||
rear = { onTrunk = true }
|
||||
},
|
||||
-- Liberator (monster)
|
||||
[-845961253] = {
|
||||
front = false,
|
||||
@@ -1472,6 +1560,11 @@ local vehicleNumberPlates = {
|
||||
front = { onBumper = true },
|
||||
rear = { onBumper = true }
|
||||
},
|
||||
-- Ratel
|
||||
[`ratel`] = {
|
||||
front = false,
|
||||
rear = false
|
||||
},
|
||||
-- RC Bandito (rcbandito)
|
||||
[-286046740] = {
|
||||
front = false,
|
||||
@@ -1522,6 +1615,11 @@ local vehicleNumberPlates = {
|
||||
front = { onBumper = true },
|
||||
rear = false
|
||||
},
|
||||
-- Terminus
|
||||
[`terminus`] = {
|
||||
front = false,
|
||||
rear = { onBumper = true }
|
||||
},
|
||||
-- TrophyTruck
|
||||
[101905590] = {
|
||||
front = false,
|
||||
@@ -1554,6 +1652,11 @@ local vehicleNumberPlates = {
|
||||
},
|
||||
|
||||
-- SUV's --
|
||||
-- Aleutian
|
||||
[`aleutian`] = {
|
||||
front = { onBumper = true },
|
||||
rear = { onTrunk = true }
|
||||
},
|
||||
-- Astron (astron)
|
||||
[629969764] = {
|
||||
front = false,
|
||||
@@ -1599,6 +1702,11 @@ local vehicleNumberPlates = {
|
||||
front = false,
|
||||
rear = { onTrunk = true }
|
||||
},
|
||||
-- Baller ST-D
|
||||
[`baller8`] = {
|
||||
front = false,
|
||||
rear = { onTrunk = true }
|
||||
},
|
||||
-- Cavalcade
|
||||
[2006918058] = {
|
||||
front = false,
|
||||
@@ -1609,11 +1717,21 @@ local vehicleNumberPlates = {
|
||||
front = false,
|
||||
rear = { onTrunk = true }
|
||||
},
|
||||
-- Cavalcade XL
|
||||
[`cavalcade3`] = {
|
||||
front = false,
|
||||
rear = { onTrunk = true }
|
||||
},
|
||||
-- Contender
|
||||
[683047626] = {
|
||||
front = false,
|
||||
rear = { onBumper = true }
|
||||
},
|
||||
-- Dorado
|
||||
[`dorado`] = {
|
||||
front = { onBumper = true },
|
||||
rear = { onTrunk = true }
|
||||
},
|
||||
-- Dubsta
|
||||
[1177543287] = {
|
||||
front = false,
|
||||
@@ -1734,6 +1852,11 @@ local vehicleNumberPlates = {
|
||||
front = false,
|
||||
rear = { onTrunk = true }
|
||||
},
|
||||
-- Vivanite
|
||||
[`vivanite`] = {
|
||||
front = false,
|
||||
rear = { onTrunk = true }
|
||||
},
|
||||
-- Toros (toros)
|
||||
[-1168952148] = {
|
||||
front = false,
|
||||
@@ -1766,6 +1889,11 @@ local vehicleNumberPlates = {
|
||||
front = { onBumper = true },
|
||||
rear = { onTrunk = true }
|
||||
},
|
||||
-- Asterope GZ
|
||||
[`asterope2`] = {
|
||||
front = false,
|
||||
rear = { onTrunk = true }
|
||||
},
|
||||
-- Cog55
|
||||
[906642318] = {
|
||||
front = { onBumper = true },
|
||||
@@ -2080,6 +2208,11 @@ local vehicleNumberPlates = {
|
||||
front = false,
|
||||
rear = { static = true }
|
||||
},
|
||||
-- La Coureuse
|
||||
[`coureur`] = {
|
||||
front = false,
|
||||
rear = { onTrunk = true }
|
||||
},
|
||||
-- Cypher
|
||||
[1755697647] = {
|
||||
front = false,
|
||||
@@ -2405,6 +2538,11 @@ local vehicleNumberPlates = {
|
||||
front = false,
|
||||
rear = { static = true }
|
||||
},
|
||||
-- Itali GTO Stinger TT
|
||||
[`stingertt`] = {
|
||||
front = false,
|
||||
rear = { onBumper = true }
|
||||
},
|
||||
-- Streiter (streiter)
|
||||
[1741861769] = {
|
||||
front = { onBumper = true },
|
||||
@@ -2924,6 +3062,11 @@ local vehicleNumberPlates = {
|
||||
front = false,
|
||||
rear = { static = true }
|
||||
},
|
||||
-- Turismo Omaggio
|
||||
[`turismo3`] = {
|
||||
front = false,
|
||||
rear = { onBumper = true }
|
||||
},
|
||||
-- Turismor
|
||||
[408192225] = {
|
||||
front = false,
|
||||
@@ -3026,6 +3169,16 @@ local vehicleNumberPlates = {
|
||||
front = false,
|
||||
rear = false
|
||||
},
|
||||
-- Boat Trailer
|
||||
[`boattrailer2`] = {
|
||||
front = false,
|
||||
rear = false
|
||||
},
|
||||
-- Boat Trailer
|
||||
[`boattrailer3`] = {
|
||||
front = false,
|
||||
rear = false
|
||||
},
|
||||
-- CableCar
|
||||
[-960289747] = {
|
||||
front = false,
|
||||
@@ -3081,6 +3234,11 @@ local vehicleNumberPlates = {
|
||||
front = false,
|
||||
rear = false
|
||||
},
|
||||
-- Trailer
|
||||
[`tvtrailer2`] = {
|
||||
front = false,
|
||||
rear = false
|
||||
},
|
||||
-- Tanker
|
||||
[-730904777] = {
|
||||
front = false,
|
||||
@@ -3186,7 +3344,17 @@ local vehicleNumberPlates = {
|
||||
-- TowTruck2
|
||||
[-442313018] = {
|
||||
front = { onBumper = true },
|
||||
rear = { onBumper = true }
|
||||
rear = { static = true }
|
||||
},
|
||||
-- Towtruck
|
||||
[`towtruck3`] = {
|
||||
front = { onBumper = true },
|
||||
rear = { static = true }
|
||||
},
|
||||
-- Towtruck
|
||||
[`towtruck4`] = {
|
||||
front = { onBumper = true },
|
||||
rear = { static = true }
|
||||
},
|
||||
-- Tractor
|
||||
[1641462412] = {
|
||||
@@ -3208,11 +3376,16 @@ local vehicleNumberPlates = {
|
||||
front = false,
|
||||
rear = { static = true }
|
||||
},
|
||||
-- TrailerS4
|
||||
-- Trailers4
|
||||
[-1100548694] = {
|
||||
front = false,
|
||||
rear = false
|
||||
},
|
||||
-- Trailer
|
||||
[`trailers5`] = {
|
||||
front = false,
|
||||
rear = false
|
||||
},
|
||||
-- UtilliTruck
|
||||
[516990260] = {
|
||||
front = false,
|
||||
@@ -3275,6 +3448,11 @@ local vehicleNumberPlates = {
|
||||
front = false,
|
||||
rear = { static = true }
|
||||
},
|
||||
-- Boxville (LSDS)
|
||||
[`boxville6`] = {
|
||||
front = false,
|
||||
rear = { static = true }
|
||||
},
|
||||
-- Burrito
|
||||
[-1346687836] = {
|
||||
front = { onBumper = true },
|
||||
@@ -3380,6 +3558,11 @@ local vehicleNumberPlates = {
|
||||
front = { onBumper = true },
|
||||
rear = { onDoor = 3 }
|
||||
},
|
||||
--Speedo Custom
|
||||
[`speedo5`] = {
|
||||
front = { onBumper = true },
|
||||
rear = { onDoor = 3 }
|
||||
},
|
||||
-- Surfer (surfer)
|
||||
[699456151] = {
|
||||
front = { onBumper = true },
|
||||
@@ -3419,6 +3602,289 @@ local vehicleNumberPlates = {
|
||||
[1486521356] = {
|
||||
front = false,
|
||||
rear = { onTrunk = true }
|
||||
},
|
||||
|
||||
-- Uncategorized --
|
||||
-- I'm too lazy to add these into the categories. Deal with it.
|
||||
[`driftjester`] = {
|
||||
front = false,
|
||||
rear = { static = true }
|
||||
},
|
||||
[`barracks3`] = {
|
||||
front = false,
|
||||
rear = false
|
||||
},
|
||||
[`polfaction2`] = {
|
||||
front = { onBumper = true },
|
||||
rear = { static = true }
|
||||
},
|
||||
[`driftremus`] = {
|
||||
front = { onBumper = true },
|
||||
rear = { onBumper = true }
|
||||
},
|
||||
[`rapidgt4`] = {
|
||||
front = false,
|
||||
rear = { static = true }
|
||||
},
|
||||
[`pipistrello`] = {
|
||||
front = false,
|
||||
rear = { static = true }
|
||||
},
|
||||
[`niobe`] = {
|
||||
front = false,
|
||||
rear = { static = true }
|
||||
},
|
||||
[`hardy`] = {
|
||||
front = { onBumper = true },
|
||||
rear = { onBumper = true }
|
||||
},
|
||||
[`polcaracara`] = {
|
||||
front = false,
|
||||
rear = { static = true }
|
||||
},
|
||||
[`woodlander`] = {
|
||||
front = { onBumper = true },
|
||||
rear = { onTrunk = true }
|
||||
},
|
||||
[`ztype`] = {
|
||||
front = false,
|
||||
rear = { static = true }
|
||||
},
|
||||
[`policet3`] = {
|
||||
front = { onBumper = true },
|
||||
rear = { onBumper = true }
|
||||
},
|
||||
[`drifthardy`] = {
|
||||
front = { onBumper = true },
|
||||
rear = { onBumper = true }
|
||||
},
|
||||
[`flatbed2`] = {
|
||||
front = { onBumper = true },
|
||||
rear = false
|
||||
},
|
||||
[`l352`] = {
|
||||
front = false,
|
||||
rear = { onBumper = true }
|
||||
},
|
||||
[`l3driftl35252`] = {
|
||||
front = false,
|
||||
rear = { onBumper = true }
|
||||
},
|
||||
[`policeb2`] = {
|
||||
front = false,
|
||||
rear = { static = true }
|
||||
},
|
||||
[`tulip2`] = {
|
||||
front = { onBumper = true },
|
||||
rear = { static = true }
|
||||
},
|
||||
[`cheetah3`] = {
|
||||
front = { onBumper = true },
|
||||
rear = { onBumper = true }
|
||||
},
|
||||
[`driftcypher`] = {
|
||||
front = false,
|
||||
rear = { onTrunk = true }
|
||||
},
|
||||
[`gt500`] = {
|
||||
front = false,
|
||||
rear = { onTrunk = true }
|
||||
},
|
||||
[`diablous2`] = {
|
||||
front = false,
|
||||
rear = false
|
||||
},
|
||||
[`driftfr36`] = {
|
||||
front = false,
|
||||
rear = { onBumper = true }
|
||||
},
|
||||
[`chavosv6`] = {
|
||||
front = { onBumper = true },
|
||||
rear = { onTrunk = true }
|
||||
},
|
||||
[`driftchavosv6`] = {
|
||||
front = { onBumper = true },
|
||||
rear = { onTrunk = true }
|
||||
},
|
||||
[`youga5`] = {
|
||||
front = false,
|
||||
rear = { onTrunk = true }
|
||||
},
|
||||
[`pizzaboy`] = {
|
||||
front = false,
|
||||
rear = { static = true }
|
||||
},
|
||||
[`wastelander`] = {
|
||||
front = false,
|
||||
rear = false
|
||||
},
|
||||
[`minimus`] = {
|
||||
front = { onBumper = true },
|
||||
rear = { onTrunk = true }
|
||||
},
|
||||
[`uranus`] = {
|
||||
front = { onBumper = true },
|
||||
rear = { static = true }
|
||||
},
|
||||
[`polterminus`] = {
|
||||
front = false,
|
||||
rear = { onBumper = true }
|
||||
},
|
||||
[`everon3`] = {
|
||||
front = false,
|
||||
rear = { static = true }
|
||||
},
|
||||
[`riot2`] = {
|
||||
front = false,
|
||||
rear = { static = true }
|
||||
},
|
||||
[`polgreenwood`] = {
|
||||
front = false,
|
||||
rear = { onBumper = true }
|
||||
},
|
||||
[`mule5`] = {
|
||||
front = { false },
|
||||
rear = { static = true }
|
||||
},
|
||||
[`banshee3`] = {
|
||||
front = false,
|
||||
rear = { static = true }
|
||||
},
|
||||
[`driftcheburek`] = {
|
||||
front = false,
|
||||
rear = { static = true }
|
||||
},
|
||||
[`driftyosemite`] = {
|
||||
front = { onBumper = true },
|
||||
rear = { onBumper = true }
|
||||
},
|
||||
[`polimpaler6`] = {
|
||||
front = { onBumper = true },
|
||||
rear = { static = true }
|
||||
},
|
||||
[`zr350`] = {
|
||||
front = false,
|
||||
rear = { onBumper = true }
|
||||
},
|
||||
[`driftjester3`] = {
|
||||
front = false,
|
||||
rear = { static = true }
|
||||
},
|
||||
[`driftfuto2`] = {
|
||||
front = { onBumper = true },
|
||||
rear = { static = true }
|
||||
},
|
||||
[`envisage`] = {
|
||||
front = false,
|
||||
rear = { static = true }
|
||||
},
|
||||
[`driftfuto`] = {
|
||||
front = { onBumper = true },
|
||||
rear = { static = true }
|
||||
},
|
||||
[`stockade4`] = {
|
||||
front = false,
|
||||
rear = { static = true }
|
||||
},
|
||||
[`drifteuros`] = {
|
||||
front = false,
|
||||
rear = { static = true }
|
||||
},
|
||||
[`drifttampa`] = {
|
||||
front = false,
|
||||
rear = { onBumper = true }
|
||||
},
|
||||
[`driftzr350`] = {
|
||||
front = false,
|
||||
rear = { onBumper = true }
|
||||
},
|
||||
[`dominator10`] = {
|
||||
front = false,
|
||||
rear = { static = true }
|
||||
},
|
||||
[`poldominator10`] = {
|
||||
front = false,
|
||||
rear = { static = true }
|
||||
},
|
||||
[`driftdominator10`] = {
|
||||
front = false,
|
||||
rear = { static = true }
|
||||
},
|
||||
[`yosemite1500`] = {
|
||||
front = { onBumper = true },
|
||||
rear = { onBumper = true }
|
||||
},
|
||||
[`poldorado`] = {
|
||||
front = { onBumper = true },
|
||||
rear = { onTrunk = true }
|
||||
},
|
||||
[`paragon3`] = {
|
||||
front = false,
|
||||
rear = { static = true }
|
||||
},
|
||||
[`eurosX32`] = {
|
||||
front = { onBumper = true },
|
||||
rear = { static = true }
|
||||
},
|
||||
[`castigator`] = {
|
||||
front = false,
|
||||
rear = { onTrunk = true }
|
||||
},
|
||||
[`polimpaler5`] = {
|
||||
front = false,
|
||||
rear = { static = true }
|
||||
},
|
||||
[`driftnebula`] = {
|
||||
front = { onBumper = true },
|
||||
rear = { static = true }
|
||||
},
|
||||
[`driftsentinel`] = {
|
||||
front = { onBumper = true },
|
||||
rear = { onTrunk = true }
|
||||
},
|
||||
[`vorschlaghammer`] = {
|
||||
front = { onBumper = true },
|
||||
rear = { onTrunk = true }
|
||||
},
|
||||
[`driftvorschlag`] = {
|
||||
front = { onBumper = true },
|
||||
rear = { onTrunk = true }
|
||||
},
|
||||
[`coquette5`] = {
|
||||
front = false,
|
||||
rear = { static = true }
|
||||
},
|
||||
[`coquette6`] = {
|
||||
front = false,
|
||||
rear = { static = true }
|
||||
},
|
||||
[`firebolt`] = {
|
||||
front = false,
|
||||
rear = { onBumper = true }
|
||||
},
|
||||
[`polcoquette4`] = {
|
||||
front = false,
|
||||
rear = { static = true }
|
||||
},
|
||||
[`jester5`] = {
|
||||
front = false,
|
||||
rear = { static = true }
|
||||
},
|
||||
[`suzume`] = {
|
||||
front = false,
|
||||
rear = { static = true }
|
||||
},
|
||||
[`tampa4`] = {
|
||||
front = { onBumper = true },
|
||||
rear = { onBumper = true }
|
||||
},
|
||||
[`driftgauntlet4`] = {
|
||||
front = false,
|
||||
rear = { onBumper = true }
|
||||
},
|
||||
[`sentinel5`] = {
|
||||
front = false,
|
||||
rear = { onTrunk = true }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3453,24 +3919,17 @@ local function IsPlateVisible(vehicle, plate, type, vehicleRotation, cameraRotat
|
||||
end
|
||||
|
||||
if plate.onBumper then
|
||||
local bumperBone = nil
|
||||
if type == 'rear' then
|
||||
bumperBone = "bumper_r"
|
||||
else
|
||||
bumperBone = "bumper_f"
|
||||
end
|
||||
|
||||
local isBumperAttached = IsBoneAttachedToVehicle(vehicle, bumperBone)
|
||||
local isBumperAttached = not IsVehicleBumperBrokenOff(vehicle, type == 'front')
|
||||
if not isBumperAttached then
|
||||
return false
|
||||
end
|
||||
elseif plate.onTrunk then
|
||||
local isTrunkAttached = IsBoneAttachedToVehicle(vehicle, "boot")
|
||||
local isTrunkAttached = IsBoneAttachedToVehicle(vehicle, 'boot')
|
||||
if not isTrunkAttached then
|
||||
return false
|
||||
end
|
||||
elseif plate.onHood then
|
||||
local isHoodAttached = IsBoneAttachedToVehicle(vehicle, "bonnet")
|
||||
local isHoodAttached = IsBoneAttachedToVehicle(vehicle, 'bonnet')
|
||||
if not isHoodAttached then
|
||||
return false
|
||||
end
|
||||
@@ -3508,6 +3967,12 @@ local function IsPlateVisible(vehicle, plate, type, vehicleRotation, cameraRotat
|
||||
return true
|
||||
end
|
||||
|
||||
-- Not that reliable, but better then nothing!
|
||||
local function GetVehiclePlateBestGuess(vehicle)
|
||||
local plateType = GetVehiclePlateType(vehicle)
|
||||
return vehicleNumberPlates[plateType] or vehicleNumberPlates[0]
|
||||
end
|
||||
|
||||
function GetVehicleNumberPlate(vehicle, vehicleRotation, cameraRotation)
|
||||
local class = GetVehicleClass(vehicle)
|
||||
if noPlateClasses[class] then
|
||||
@@ -3516,11 +3981,12 @@ function GetVehicleNumberPlate(vehicle, vehicleRotation, cameraRotation)
|
||||
|
||||
local model = GetEntityModel(vehicle)
|
||||
local plate = vehicleNumberPlates[model]
|
||||
|
||||
if not plate then
|
||||
plate = vehicleNumberPlates['default']
|
||||
plate = GetVehiclePlateBestGuess(vehicle)
|
||||
if not noModelCache[model] then
|
||||
noModelCache[model] = true
|
||||
print("^3No plate data was found for vehicle model: "..model..", please add it to the numberplates.lua file.^0")
|
||||
warn("No plate data was found for vehicle model: "..model..", please add it to the numberplates.lua file.")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
local whitelistedStateBags <const> = {
|
||||
['heliCamMarkers'] = true,
|
||||
['heliCamTargetBlip'] = true,
|
||||
['heliCamInUse'] = true
|
||||
}
|
||||
|
||||
local helicopters = {}
|
||||
GlobalState.heliSpotlightsActive = 0
|
||||
|
||||
RegisterServerEvent('helicam:enterCamera')
|
||||
AddEventHandler('helicam:enterCamera', function(heliNetId)
|
||||
RegisterServerEvent('helicam:enterCamera', function(heliNetId)
|
||||
local helicopter = Entity(NetworkGetEntityFromNetworkId(heliNetId))
|
||||
if helicopter and not helicopter.state.heliCamInUse then
|
||||
helicopter.state.heliCamInUse = true
|
||||
@@ -18,8 +23,7 @@ AddEventHandler('helicam:enterCamera', function(heliNetId)
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterServerEvent('helicam:leaveCamera')
|
||||
AddEventHandler('helicam:leaveCamera', function(heliNetId)
|
||||
RegisterServerEvent('helicam:leaveCamera', function(heliNetId)
|
||||
local helicopter = Entity(NetworkGetEntityFromNetworkId(heliNetId))
|
||||
helicopter.state.heliCamInUse = false
|
||||
helicopter.state.heliCamTargetBlip = nil
|
||||
@@ -28,14 +32,17 @@ AddEventHandler('helicam:leaveCamera', function(heliNetId)
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterServerEvent('helicam:setStateBag')
|
||||
AddEventHandler('helicam:setStateBag', function(heliNetId, bagName, value)
|
||||
RegisterServerEvent('helicam:setStateBag', function(heliNetId, bagName, value)
|
||||
-- This prevents cheaters from using this event to set other state bags than the onces intended to be used in this script
|
||||
if not whitelistedStateBags[bagName] then
|
||||
return
|
||||
end
|
||||
|
||||
local helicopter = Entity(NetworkGetEntityFromNetworkId(heliNetId))
|
||||
helicopter.state[bagName] = value
|
||||
end)
|
||||
|
||||
RegisterServerEvent('helicam:toggleSpotlight')
|
||||
AddEventHandler('helicam:toggleSpotlight', function(state)
|
||||
RegisterServerEvent('helicam:toggleSpotlight', function(state)
|
||||
if state then
|
||||
GlobalState.heliSpotlightsActive += 1
|
||||
else
|
||||
@@ -44,7 +51,7 @@ AddEventHandler('helicam:toggleSpotlight', function(state)
|
||||
end)
|
||||
|
||||
-- If a player crashes/leaves while in the camera
|
||||
AddEventHandler('playerDropped', function(reason)
|
||||
AddEventHandler('playerDropped', function(_reason)
|
||||
if helicopters[source] then
|
||||
TriggerEvent('helicam:leaveCamera', helicopters[source])
|
||||
Player(source).state.heliCamSpotlightData = { position = false, helicopter = helicopters[source] }
|
||||
|
||||
Binary file not shown.
@@ -1,2 +1 @@
|
||||
|
||||
Do not rename the resource to jraxion_handlingeditor, it will break the resource.
|
||||
Make sure the resource name is jraxion_handlingeditor, it will break the resource if you rename it.
|
||||
|
||||
Binary file not shown.
@@ -1,5 +1,15 @@
|
||||
Config = {}
|
||||
|
||||
-- Make sure the resource name is jraxion_handlingeditor, it will break the resource if you rename it.
|
||||
|
||||
Config.isAllowed = function(source) --server side. most frameworks already have this.
|
||||
-- if you know what you are doing, edit server/server.lua to change the permission.
|
||||
if IsPlayerAceAllowed(source, 'admin') or IsPlayerAceAllowed(source, 'command') then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
Config.Precision = 10000.0
|
||||
|
||||
Config.Values = {
|
||||
|
||||
@@ -15,6 +15,7 @@ client_scripts {
|
||||
}
|
||||
|
||||
server_scripts {
|
||||
'config.lua',
|
||||
'server/server.lua'
|
||||
}
|
||||
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
|
||||
while GetCurrentResourceName() ~= "jraxion_handlingeditor" do
|
||||
Wait(2000)
|
||||
print("Please do not rename the resource to jraxion_handlingeditor, it will break the resource.")
|
||||
print("Make sure the resource name is jraxion_handlingeditor, it will break the resource if you rename it.")
|
||||
end
|
||||
|
||||
RegisterCommand('staffhandlingeditor', function(source, args, rawCommand)
|
||||
RegisterCommand('handlingeditor', function(source, args, rawCommand)
|
||||
-- Add your permission system here.
|
||||
|
||||
if IsPlayerAceAllowed(source, 'admin') or IsPlayerAceAllowed(source, 'command') then
|
||||
if Config.isAllowed(source) then
|
||||
TriggerClientEvent('jraxion_handlingeditor:openHandlingEditor', source)
|
||||
else
|
||||
print('No permission')
|
||||
end
|
||||
end)
|
||||
end, false)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,10 +1,10 @@
|
||||
setr scully:uniqueKvpId "Elite Gaming" # Set to something unique.
|
||||
setr scully:uniqueKvpId "change-me" # Set to something unique.
|
||||
|
||||
set scully:webhook:duty "false" # To enable this log replace "false" with "webhook url"
|
||||
set scully:webhook:action "false" # To enable this log replace "false" with "webhook url"
|
||||
set scully:webhook:jail "false" # To enable this log replace "false" with "webhook url"
|
||||
|
||||
set scully_lawenforcement:enablePermissions "false" # Set to "false" to allow anyone to use the menu.
|
||||
set scully_lawenforcement:enablePermissions "true" # Set to "false" to allow anyone to use the menu.
|
||||
set scully_lawenforcement:enableDutyBlips "true" # Set to "false" to disable the duty blips.
|
||||
set scully_lawenforcement:cadUrl "https://example.com/cad" # The url for your CAD website.
|
||||
set scully_lawenforcement:reviveEvent "scully_lawenforcement:revivePlayer" # Change the client event if you wish to use a different revive system.
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,5 +1,5 @@
|
||||
Scully = {
|
||||
KVPHandle = 'Elite Gaming', -- Change this to something unique such as your server name.
|
||||
KVPHandle = 'Elite Gaming RP', -- Change this to something unique such as your server name.
|
||||
RadioColour = 'default', -- Options are default, blue, brown, cherry, coral, cyan, green, mint, orange, pink, purple, red, white and yellow
|
||||
AllowColours = true, -- Disable if you don't want people to be able to change their radio colour in-game
|
||||
ColourCommand = 'rcolor', -- Set to '' if you don't want to allow changing with a command, command is /rcolour 1-11
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user