fixing ers
This commit is contained in:
@@ -1,92 +0,0 @@
|
||||
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
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
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
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
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
|
||||
}
|
||||
@@ -1,154 +0,0 @@
|
||||
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
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
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
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
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
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
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
|
||||
}
|
||||
@@ -1,112 +0,0 @@
|
||||
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
|
||||
}
|
||||
@@ -1,117 +0,0 @@
|
||||
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
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
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
|
||||
}
|
||||
@@ -1,516 +0,0 @@
|
||||
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
|
||||
}
|
||||
@@ -1,272 +0,0 @@
|
||||
|
||||
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
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
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
|
||||
}
|
||||
@@ -1,135 +0,0 @@
|
||||
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
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
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
@@ -1,72 +0,0 @@
|
||||
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
|
||||
}
|
||||
@@ -1,146 +0,0 @@
|
||||
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
|
||||
}
|
||||
@@ -1,165 +0,0 @@
|
||||
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
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
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
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
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.
@@ -1 +0,0 @@
|
||||
Make sure the resource name is jraxion_handlingeditor, it will break the resource if you rename it.
|
||||
Binary file not shown.
@@ -1,424 +0,0 @@
|
||||
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 = {
|
||||
-- Physical
|
||||
fMass = {
|
||||
name = "Vehicle Mass",
|
||||
type = "float",
|
||||
change = 100.0,
|
||||
min = 100.0,
|
||||
max = 5000.0,
|
||||
description = "Vehicle weight in kilograms. Affects collision physics."
|
||||
},
|
||||
fInitialDragCoeff = {
|
||||
name = "Drag Coefficient",
|
||||
type = "float",
|
||||
change = 1,
|
||||
min = 10.0,
|
||||
max = 120.0,
|
||||
description = "Aerodynamic drag coefficient. Higher values increase air resistance."
|
||||
},
|
||||
fPopUpLightRotation = {
|
||||
name = "Pop-up Light Rotation",
|
||||
type = "float",
|
||||
change = 1.0,
|
||||
min = 0.0,
|
||||
max = 90.0,
|
||||
description = "Angle of pop-up headlights when deployed"
|
||||
},
|
||||
fPercentSubmerged = {
|
||||
name = "Submersion Percentage",
|
||||
type = "float",
|
||||
change = 5.0,
|
||||
min = 0.0,
|
||||
max = 100.0,
|
||||
description = "Percentage of vehicle that must be submerged before sinking. Default is 85%."
|
||||
},
|
||||
vecCentreOfMassOffset = {
|
||||
name = "Centre of Mass Offset",
|
||||
type = "vector",
|
||||
change = 0.1,
|
||||
min = -2.0,
|
||||
max = 2.0,
|
||||
description = "Center of mass offset from vehicle origin",
|
||||
components = {
|
||||
x = {name = "X Offset", description = "Left/Right offset"},
|
||||
y = {name = "Y Offset", description = "Front/Back offset"},
|
||||
z = {name = "Z Offset", description = "Up/Down offset"}
|
||||
}
|
||||
},
|
||||
vecInertiaMultiplier = {
|
||||
name = "Inertia Multiplier",
|
||||
type = "vector",
|
||||
change = 0.1,
|
||||
min = 0.0,
|
||||
max = 3.0,
|
||||
description = "Inertia multiplier for each axis",
|
||||
components = {
|
||||
x = {name = "X Multiplier", description = "Roll inertia"},
|
||||
y = {name = "Y Multiplier", description = "Pitch inertia"},
|
||||
z = {name = "Z Multiplier", description = "Yaw inertia"}
|
||||
}
|
||||
},
|
||||
fSeatOffsetDistX = {
|
||||
name = "Seat X Offset",
|
||||
type = "float",
|
||||
change = 0.1,
|
||||
min = -2.0,
|
||||
max = 2.0,
|
||||
description = "Driver seat left/right offset"
|
||||
},
|
||||
fSeatOffsetDistY = {
|
||||
name = "Seat Y Offset",
|
||||
type = "float",
|
||||
change = 0.1,
|
||||
min = -2.0,
|
||||
max = 2.0,
|
||||
description = "Driver seat front/back offset"
|
||||
},
|
||||
fSeatOffsetDistZ = {
|
||||
name = "Seat Z Offset",
|
||||
type = "float",
|
||||
change = 0.1,
|
||||
min = -2.0,
|
||||
max = 2.0,
|
||||
description = "Driver seat up/down offset"
|
||||
},
|
||||
|
||||
-- Transmission
|
||||
fDriveBiasFront = {
|
||||
name = "Drive Type",
|
||||
type = "float",
|
||||
change = 0.05,
|
||||
min = 0.0,
|
||||
max = 1.0,
|
||||
description = "Drive type: 0.0 = RWD, 1.0 = FWD, 0.5 = balanced 4WD"
|
||||
},
|
||||
nInitialDriveGears = {
|
||||
name = "Number of Gears",
|
||||
type = "int",
|
||||
change = 1,
|
||||
min = 1,
|
||||
max = 8,
|
||||
description = "Number of forward gears in the transmission"
|
||||
},
|
||||
fInitialDriveForce = {
|
||||
name = "Engine Power",
|
||||
type = "float",
|
||||
change = 0.1,
|
||||
min = 0.01,
|
||||
max = 2.0,
|
||||
description = "Engine power multiplier. Higher values increase acceleration."
|
||||
},
|
||||
fDriveInertia = {
|
||||
name = "Engine Rev Speed",
|
||||
type = "float",
|
||||
change = 1,
|
||||
min = 0.01,
|
||||
max = 2.0,
|
||||
description = "Engine rev speed. Higher values make engine reach redline faster."
|
||||
},
|
||||
fClutchChangeRateScaleUpShift = {
|
||||
name = "Upshift Speed",
|
||||
type = "float",
|
||||
change = 0.5,
|
||||
min = 0.1,
|
||||
max = 10.0,
|
||||
description = "Upshift speed multiplier. Higher values = faster shifts."
|
||||
},
|
||||
fClutchChangeRateScaleDownShift = {
|
||||
name = "Downshift Speed",
|
||||
type = "float",
|
||||
change = 0.5,
|
||||
min = 0.1,
|
||||
max = 10.0,
|
||||
description = "Downshift speed multiplier. Higher values = faster shifts."
|
||||
},
|
||||
fInitialDriveMaxFlatVel = {
|
||||
name = "Top Speed",
|
||||
type = "float",
|
||||
change = 5.0,
|
||||
min = 0.0,
|
||||
max = 500.0,
|
||||
description = "Top speed at redline in highest gear (multiply by 0.82 for MPH)"
|
||||
},
|
||||
|
||||
-- Brakes
|
||||
fBrakeForce = {
|
||||
name = "Brake Power",
|
||||
type = "float",
|
||||
change = 0.2,
|
||||
min = 0.01,
|
||||
max = 2.0,
|
||||
description = "Brake power multiplier. Higher values increase braking force."
|
||||
},
|
||||
fBrakeBiasFront = {
|
||||
name = "Brake Balance",
|
||||
type = "float",
|
||||
change = 0.1,
|
||||
min = 0.0,
|
||||
max = 1.0,
|
||||
description = "Brake distribution: 0.0 = rear only, 1.0 = front only, 0.5 = balanced"
|
||||
},
|
||||
fHandBrakeForce = {
|
||||
name = "Handbrake Power",
|
||||
type = "float",
|
||||
change = 0.2,
|
||||
min = 0.0,
|
||||
max = 5.0,
|
||||
description = "Handbrake power multiplier. Higher values increase handbrake strength."
|
||||
},
|
||||
|
||||
-- Steering
|
||||
fSteeringLock = {
|
||||
name = "Steering Angle",
|
||||
type = "float",
|
||||
change = 5.0,
|
||||
min = 10.0,
|
||||
max = 70.0,
|
||||
description = "Maximum steering angle. Higher values increase turn radius."
|
||||
},
|
||||
|
||||
-- Traction
|
||||
fTractionCurveMax = {
|
||||
name = "Cornering Grip",
|
||||
type = "float",
|
||||
change = 0.1,
|
||||
min = 0.1,
|
||||
max = 4.0,
|
||||
description = "Maximum cornering grip multiplier"
|
||||
},
|
||||
fTractionCurveMin = {
|
||||
name = "Acceleration Grip",
|
||||
type = "float",
|
||||
change = 0.1,
|
||||
min = 0.1,
|
||||
max = 4.0,
|
||||
description = "Minimum acceleration/braking grip multiplier"
|
||||
},
|
||||
fTractionCurveLateral = {
|
||||
name = "Lateral Grip",
|
||||
type = "float",
|
||||
change = 1.0,
|
||||
min = 0.0,
|
||||
max = 4.0,
|
||||
description = "Lateral grip curve shape"
|
||||
},
|
||||
fTractionSpringDeltaMax = {
|
||||
name = "Traction Height Loss",
|
||||
type = "float",
|
||||
change = 0.01,
|
||||
min = 0.0,
|
||||
max = 0.3,
|
||||
description = "Height at which vehicle loses traction"
|
||||
},
|
||||
fLowSpeedTractionLossMult = {
|
||||
name = "Burnout Effect",
|
||||
type = "float",
|
||||
change = 0.1,
|
||||
min = 0.0,
|
||||
max = 2.0,
|
||||
description = "Low speed traction loss. Higher values increase burnout effect."
|
||||
},
|
||||
fCamberStiffnesss = {
|
||||
name = "Drift Control",
|
||||
type = "float",
|
||||
change = 0.01,
|
||||
min = -1.0,
|
||||
max = 1.0,
|
||||
description = "Drift grip modifier. Positive values maintain drift angle, negative values cause oversteer."
|
||||
},
|
||||
fTractionBiasFront = {
|
||||
name = "Traction Balance",
|
||||
type = "float",
|
||||
change = 0.01,
|
||||
min = 0.01,
|
||||
max = 0.99,
|
||||
description = "Traction distribution: 0.01 = rear bias, 0.99 = front bias, 0.5 = balanced"
|
||||
},
|
||||
fTractionLossMult = {
|
||||
name = "Surface Grip Loss",
|
||||
type = "float",
|
||||
change = 1.0,
|
||||
min = 0.0,
|
||||
max = 2.0,
|
||||
description = "Surface traction loss multiplier. Higher values reduce grip on all surfaces."
|
||||
},
|
||||
|
||||
-- Suspension
|
||||
fSuspensionForce = {
|
||||
name = "Suspension Force",
|
||||
type = "float",
|
||||
change = 0.1,
|
||||
min = 0.0,
|
||||
max = 5.0,
|
||||
description = "Suspension spring force"
|
||||
},
|
||||
fSuspensionCompDamp = {
|
||||
name = "Compression Damping",
|
||||
type = "float",
|
||||
change = 0.1,
|
||||
min = 0.0,
|
||||
max = 5.0,
|
||||
description = "Suspension compression damping"
|
||||
},
|
||||
fSuspensionReboundDamp = {
|
||||
name = "Rebound Damping",
|
||||
type = "float",
|
||||
change = 0.1,
|
||||
min = 0.0,
|
||||
max = 5.0,
|
||||
description = "Suspension rebound damping"
|
||||
},
|
||||
fSuspensionUpperLimit = {
|
||||
name = "Upper Limit",
|
||||
type = "float",
|
||||
change = 0.01,
|
||||
min = 0.0,
|
||||
max = 0.5,
|
||||
description = "Suspension upper movement limit"
|
||||
},
|
||||
fSuspensionLowerLimit = {
|
||||
name = "Lower Limit",
|
||||
type = "float",
|
||||
change = 0.01,
|
||||
min = -0.5,
|
||||
max = 0.0,
|
||||
description = "Suspension lower movement limit"
|
||||
},
|
||||
fSuspensionRaise = {
|
||||
name = "Ride Height",
|
||||
type = "float",
|
||||
change = 0.01,
|
||||
min = -0.2,
|
||||
max = 0.2,
|
||||
description = "Vehicle ride height adjustment"
|
||||
},
|
||||
fSuspensionBiasFront = {
|
||||
name = "Suspension Balance",
|
||||
type = "float",
|
||||
change = 0.01,
|
||||
min = 0.0,
|
||||
max = 1.0,
|
||||
description = "Suspension force distribution"
|
||||
},
|
||||
fAntiRollBarForce = {
|
||||
name = "Anti-Roll Force",
|
||||
type = "float",
|
||||
change = 0.1,
|
||||
min = 0.0,
|
||||
max = 2.0,
|
||||
description = "Anti-roll bar force"
|
||||
},
|
||||
fAntiRollBarBiasFront = {
|
||||
name = "Anti-Roll Balance",
|
||||
type = "float",
|
||||
change = 0.01,
|
||||
min = 0.0,
|
||||
max = 1.0,
|
||||
description = "Anti-roll bar force distribution"
|
||||
},
|
||||
fRollCentreHeightFront = {
|
||||
name = "Front Roll Height",
|
||||
type = "float",
|
||||
change = 0.01,
|
||||
min = 0.0,
|
||||
max = 1.0,
|
||||
description = "Front roll center height"
|
||||
},
|
||||
fRollCentreHeightRear = {
|
||||
name = "Rear Roll Height",
|
||||
type = "float",
|
||||
change = 0.01,
|
||||
min = 0.0,
|
||||
max = 1.0,
|
||||
description = "Rear roll center height"
|
||||
},
|
||||
|
||||
-- Damage
|
||||
fCollisionDamageMult = {
|
||||
name = "Collision Damage",
|
||||
type = "float",
|
||||
change = 1.0,
|
||||
min = 0.0,
|
||||
max = 2.0,
|
||||
description = "Collision damage multiplier"
|
||||
},
|
||||
fWeaponDamageMult = {
|
||||
name = "Weapon Damage",
|
||||
type = "float",
|
||||
change = 1.0,
|
||||
min = 0.0,
|
||||
max = 2.0,
|
||||
description = "Weapon damage multiplier"
|
||||
},
|
||||
fDeformationDamageMult = {
|
||||
name = "Visual Damage",
|
||||
type = "float",
|
||||
change = 1.0,
|
||||
min = 0.0,
|
||||
max = 2.0,
|
||||
description = "Visual damage deformation multiplier"
|
||||
},
|
||||
fEngineDamageMult = {
|
||||
name = "Engine Damage",
|
||||
type = "float",
|
||||
change = 1.0,
|
||||
min = 0.0,
|
||||
max = 2.0,
|
||||
description = "Engine damage multiplier"
|
||||
},
|
||||
|
||||
-- Misc
|
||||
fPetrolTankVolume = {
|
||||
name = "Fuel Capacity",
|
||||
type = "float",
|
||||
change = 1.0,
|
||||
min = 0.0,
|
||||
max = 100.0,
|
||||
description = "Fuel tank capacity"
|
||||
},
|
||||
fOilVolume = {
|
||||
name = "Oil Capacity",
|
||||
type = "float",
|
||||
change = 1.0,
|
||||
min = 0.0,
|
||||
max = 10.0,
|
||||
description = "Engine oil capacity"
|
||||
},
|
||||
nMonetaryValue = {
|
||||
name = "Vehicle Value",
|
||||
type = "int",
|
||||
change = 1.0,
|
||||
min = 0,
|
||||
max = 1000000,
|
||||
description = "Vehicle monetary value"
|
||||
},
|
||||
strModelFlags = {
|
||||
name = "Model Flags",
|
||||
type = "string",
|
||||
description = "Vehicle model flags"
|
||||
},
|
||||
strHandlingFlags = {
|
||||
name = "Handling Flags",
|
||||
type = "string",
|
||||
description = "Vehicle handling flags"
|
||||
},
|
||||
strDamageFlags = {
|
||||
name = "Damage Flags",
|
||||
type = "string",
|
||||
description = "Vehicle damage flags"
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
fx_version 'cerulean'
|
||||
game 'gta5'
|
||||
|
||||
lua54 'yes'
|
||||
|
||||
name 'jraxion_handlingeditor'
|
||||
version '1.0.0'
|
||||
description 'Handling Editor'
|
||||
author 'JRaxion'
|
||||
url 'https://jraxion.tebex.io/'
|
||||
|
||||
client_scripts {
|
||||
'config.lua',
|
||||
'client/client.lua'
|
||||
}
|
||||
|
||||
server_scripts {
|
||||
'config.lua',
|
||||
'server/server.lua'
|
||||
}
|
||||
|
||||
ui_page 'html/index.html'
|
||||
|
||||
files {
|
||||
'html/index.html',
|
||||
'html/main.js',
|
||||
'html/*.js',
|
||||
|
||||
'handling.meta',
|
||||
}
|
||||
|
||||
data_file 'HANDLING_FILE' 'handling.meta'
|
||||
|
||||
escrow_ignore {
|
||||
'config.lua',
|
||||
'server/server.lua',
|
||||
}
|
||||
|
||||
dependency '/assetpacks'
|
||||
@@ -1,62 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<CHandlingDataMgr>
|
||||
<HandlingData>
|
||||
<Item type="CHandlingData">
|
||||
<handlingName>MONSTER</handlingName>
|
||||
<fMass value="4000.000000" />
|
||||
<fInitialDragCoeff value="28.000000" />
|
||||
<fPercentSubmerged value="85.000000" />
|
||||
<vecCentreOfMassOffset x="0.000000" y="0.000000" z="0.000000" />
|
||||
<vecInertiaMultiplier x="1.000000" y="1.000000" z="1.000000" />
|
||||
<fDriveBiasFront value="0.200000" />
|
||||
<nInitialDriveGears value="2" />
|
||||
<fInitialDriveForce value="2.000000" />
|
||||
<fDriveInertia value="2.000000" />
|
||||
<fClutchChangeRateScaleUpShift value="10.000000" />
|
||||
<fClutchChangeRateScaleDownShift value="9.541000" />
|
||||
<fInitialDriveMaxFlatVel value="500.000000" />
|
||||
<fBrakeForce value="0.650000" />
|
||||
<fBrakeBiasFront value="0.650000" />
|
||||
<fHandBrakeForce value="0.300000" />
|
||||
<fSteeringLock value="26.000000" />
|
||||
<fTractionCurveMax value="2.533300" />
|
||||
<fTractionCurveMin value="3.517800" />
|
||||
<fTractionCurveLateral value="3.340600" />
|
||||
<fTractionSpringDeltaMax value="0.130000" />
|
||||
<fLowSpeedTractionLossMult value="1.000000" />
|
||||
<fCamberStiffnesss value="0.000000" />
|
||||
<fTractionBiasFront value="0.510000" />
|
||||
<fTractionLossMult value="0.400000" />
|
||||
<fSuspensionForce value="2.300000" />
|
||||
<fSuspensionCompDamp value="1.200000" />
|
||||
<fSuspensionReboundDamp value="4.800000" />
|
||||
<fSuspensionUpperLimit value="0.400000" />
|
||||
<fSuspensionLowerLimit value="-0.200000" />
|
||||
<fSuspensionRaise value="-0.050000" />
|
||||
<fSuspensionBiasFront value="0.500000" />
|
||||
<fAntiRollBarForce value="0.600000" />
|
||||
<fAntiRollBarBiasFront value="0.500000" />
|
||||
<fRollCentreHeightFront value="0.400000" />
|
||||
<fRollCentreHeightRear value="0.390000" />
|
||||
<fCollisionDamageMult value="1.000000" />
|
||||
<fWeaponDamageMult value="1.000000" />
|
||||
<fDeformationDamageMult value="0.800000" />
|
||||
<fEngineDamageMult value="1.500000" />
|
||||
<fPetrolTankVolume value="80.000000" />
|
||||
<fOilVolume value="10.000000" />
|
||||
<fSeatOffsetDistX value="0.000000" />
|
||||
<fSeatOffsetDistY value="0.080000" />
|
||||
<fSeatOffsetDistZ value="-0.200000" />
|
||||
<nMonetaryValue value="500000" />
|
||||
<strModelFlags>2224008</strModelFlags>
|
||||
<strHandlingFlags>20568081</strHandlingFlags>
|
||||
<strDamageFlags>20</strDamageFlags>
|
||||
<SubHandlingData>
|
||||
<Item type="" />
|
||||
<Item type="" />
|
||||
<Item type="" />
|
||||
</SubHandlingData>
|
||||
</Item>
|
||||
</HandlingData>
|
||||
</CHandlingDataMgr>
|
||||
@@ -1,242 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>jr-handling</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
|
||||
|
||||
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
|
||||
|
||||
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
||||
|
||||
<style>
|
||||
:root {
|
||||
--dark-bg: rgba(26, 26, 26, 0.95);
|
||||
--darker-bg: rgba(20, 20, 20, 0.95);
|
||||
--accent: #3498db;
|
||||
--text: #ffffff;
|
||||
--text-muted: #a0a0a0;
|
||||
--border: #2c2c2c;
|
||||
}
|
||||
|
||||
* {
|
||||
font-family: "Montserrat", sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
background: none !important;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.handling-container {
|
||||
background: none;
|
||||
padding: 25px;
|
||||
border-radius: 15px;
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
background-color: var(--darker-bg);
|
||||
border: 1px solid var(--border);
|
||||
}
|
||||
|
||||
.modal-header {
|
||||
border-bottom: 1px solid var(--border);
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.modal-header .btn {
|
||||
margin: 0 8px;
|
||||
padding: 8px 16px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.search-bar {
|
||||
padding: 1.5rem;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.form-control {
|
||||
background-color: var(--dark-bg);
|
||||
border: 1px solid var(--border);
|
||||
color: var(--text);
|
||||
padding: 12px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.form-control:focus {
|
||||
background-color: var(--dark-bg);
|
||||
border-color: var(--accent);
|
||||
color: var(--text);
|
||||
box-shadow: 0 0 0 2px rgba(52, 152, 219, 0.25);
|
||||
}
|
||||
|
||||
.maxheight {
|
||||
max-height: 70vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.table {
|
||||
color: var(--text);
|
||||
border-color: var(--border);
|
||||
}
|
||||
|
||||
.table-dark {
|
||||
background-color: var(--darker-bg);
|
||||
}
|
||||
|
||||
.btn {
|
||||
font-weight: 500;
|
||||
padding: 8px 16px;
|
||||
border-radius: 8px;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background-color: var(--accent);
|
||||
border: none;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background-color: #2980b9;
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
background-color: var(--dark-bg);
|
||||
border: 1px solid var(--border);
|
||||
}
|
||||
|
||||
.tooltip-inner {
|
||||
max-width: 300px;
|
||||
text-align: left;
|
||||
background-color: var(--darker-bg);
|
||||
border: 1px solid var(--border);
|
||||
padding: 10px;
|
||||
font-size: 0.9rem;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background: var(--dark-bg);
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background-color: var(--border);
|
||||
border-radius: 8px;
|
||||
border: 2px solid var(--dark-bg);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background-color: var(--text-muted);
|
||||
}
|
||||
|
||||
#exportArea {
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
margin-top: 15px;
|
||||
display: none;
|
||||
background-color: var(--dark-bg);
|
||||
color: var(--text);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.input-group {
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.input-group > * {
|
||||
border-radius: 8px !important;
|
||||
}
|
||||
|
||||
.dropdown-menu {
|
||||
background-color: var(--dark-bg);
|
||||
border: 1px solid var(--border);
|
||||
padding: 8px;
|
||||
max-height: 300px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.dropdown-item {
|
||||
color: var(--text);
|
||||
padding: 8px 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.dropdown-item:hover {
|
||||
background-color: var(--darker-bg);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.dropdown-item input[type="checkbox"] {
|
||||
accent-color: var(--accent);
|
||||
}
|
||||
|
||||
.flag-dropdown {
|
||||
width: 100%;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.flag-dropdown .btn {
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
background: var(--dark-bg);
|
||||
border: 1px solid var(--border);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.flag-dropdown .btn:hover,
|
||||
.flag-dropdown .btn:focus {
|
||||
background: var(--darker-bg);
|
||||
border-color: var(--accent);
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body data-bs-theme="dark">
|
||||
<div class="modal modal-lg handling-container fade" id="open-handling-modal" tabindex="-1" aria-labelledby="handlingEditor" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="handlingLabel">XA21</h5>
|
||||
<button type="button" class="btn btn-primary" onclick="exportHandling()">Export Handling</button>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="search-bar">
|
||||
<input type="text" id="searchBar" class="form-control" placeholder="Search" onkeyup="searchVehicles()">
|
||||
</div>
|
||||
|
||||
<div class="modal-body maxheight">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered align-middle">
|
||||
<thead class="table-dark">
|
||||
<tr>
|
||||
<th style="width: 40%">Name</th>
|
||||
<th style="width: 30%">Original</th>
|
||||
<th style="width: 30%">Current</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody id="handling-data-accordion">
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<textarea id="exportArea" class="form-control" readonly></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
|
||||
<script defer src="main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,319 +0,0 @@
|
||||
const modals = {
|
||||
openhandlingModal: false,
|
||||
};
|
||||
|
||||
async function closeNUI() {
|
||||
openhandlingModal.hide();
|
||||
await fetch(`https://jraxion_handlingeditor/close`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json; charset=UTF-8",
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function handleUIMessage(data) {
|
||||
switch (data.type) {
|
||||
case "openHandlingEditor":
|
||||
openEditor(data);
|
||||
break;
|
||||
default:
|
||||
console.log("No action received.");
|
||||
}
|
||||
}
|
||||
|
||||
function main() {
|
||||
window.addEventListener("message", (event) => handleUIMessage(event.data));
|
||||
openhandlingModal = new bootstrap.Modal(document.getElementById("open-handling-modal"));
|
||||
|
||||
document.querySelectorAll(".modal").forEach((modal) => {
|
||||
modal.addEventListener("hidden.bs.modal", closeNUI);
|
||||
});
|
||||
}
|
||||
|
||||
main();
|
||||
|
||||
document.addEventListener('keydown', function(event) {
|
||||
if (event.key === "Escape") {
|
||||
closeNUI();
|
||||
}
|
||||
});
|
||||
|
||||
function updateValue(input, change, key) {
|
||||
let currentValue;
|
||||
let newValue;
|
||||
|
||||
if (input.dataset.type === "string") {
|
||||
currentValue = input.value;
|
||||
newValue = currentValue;
|
||||
} else {
|
||||
currentValue = parseFloat(input.value) || 0;
|
||||
newValue = currentValue + change;
|
||||
|
||||
const min = parseFloat(input.dataset.min);
|
||||
const max = parseFloat(input.dataset.max);
|
||||
|
||||
newValue = Math.max(min, Math.min(max, newValue));
|
||||
|
||||
if (input.dataset.type === "int") {
|
||||
newValue = Math.round(newValue);
|
||||
} else if (input.dataset.type === "float") {
|
||||
newValue = parseFloat(newValue.toFixed(6));
|
||||
}
|
||||
}
|
||||
|
||||
input.value = newValue;
|
||||
|
||||
const slider = input.parentElement.querySelector('input[type="range"]');
|
||||
if (slider) {
|
||||
slider.value = newValue;
|
||||
}
|
||||
|
||||
$.post('https://jraxion_handlingeditor/updateHandling', JSON.stringify({
|
||||
key: key,
|
||||
value: newValue
|
||||
}));
|
||||
}
|
||||
|
||||
function updateFlag(checkbox, flagType) {
|
||||
const dropdownMenu = checkbox.closest('.dropdown-menu');
|
||||
const allFlags = Array.from(dropdownMenu.querySelectorAll('input[type="checkbox"]'));
|
||||
|
||||
const flagValue = allFlags.reduce((acc, flag, index) => {
|
||||
return acc + (flag.checked ? Math.pow(2, index) : 0);
|
||||
}, 0).toString(16).toUpperCase();
|
||||
|
||||
$.post('https://jraxion_handlingeditor/updateHandling', JSON.stringify({
|
||||
key: flagType,
|
||||
value: flagValue
|
||||
}));
|
||||
|
||||
const input = dropdownMenu.parentElement.previousElementSibling.querySelector('input[type="text"]');
|
||||
input.value = flagValue;
|
||||
|
||||
const selectedCount = allFlags.filter(f => f.checked).length;
|
||||
const dropdownButton = dropdownMenu.previousElementSibling;
|
||||
dropdownButton.textContent = `Selected Flags (${selectedCount})`;
|
||||
}
|
||||
|
||||
function updateFromSlider(slider) {
|
||||
const input = slider.parentElement.querySelector('input[type="text"]');
|
||||
const key = input.dataset.handlingKey;
|
||||
const newValue = parseFloat(slider.value);
|
||||
|
||||
if (input.dataset.type === "int") {
|
||||
input.value = Math.round(newValue);
|
||||
} else {
|
||||
input.value = parseFloat(newValue.toFixed(6));
|
||||
}
|
||||
|
||||
$.post('https://jraxion_handlingeditor/updateHandling', JSON.stringify({
|
||||
key: key,
|
||||
value: input.value
|
||||
}));
|
||||
}
|
||||
|
||||
function exportHandling() {
|
||||
const vehicleName = document.querySelector("#handlingLabel").innerHTML;
|
||||
const rows = document.getElementById('handling-data-accordion').getElementsByTagName('tr');
|
||||
|
||||
const xmlHeader = '<?xml version="1.0" encoding="UTF-8"?>\n\n';
|
||||
const xmlStart = '<CHandlingDataMgr>\n <HandlingData>\n <Item type="CHandlingData">\n';
|
||||
const xmlEnd = ' </Item>\n </HandlingData>\n</CHandlingDataMgr>';
|
||||
|
||||
let xmlContent = ` <handlingName>${vehicleName}</handlingName>\n`;
|
||||
|
||||
const handlingValues = {};
|
||||
|
||||
Array.from(rows).forEach(row => {
|
||||
const input = row.querySelector('input[type="text"]');
|
||||
if (!input) return;
|
||||
|
||||
const key = input.dataset.handlingKey;
|
||||
const value = input.value;
|
||||
|
||||
switch(input.dataset.type) {
|
||||
case "float":
|
||||
handlingValues[key] = parseFloat(value).toFixed(6);
|
||||
break;
|
||||
case "int":
|
||||
handlingValues[key] = Math.round(value);
|
||||
break;
|
||||
case "string":
|
||||
handlingValues[key] = value;
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
handlingValues['vecCentreOfMassOffset'] = '0.000000 0.000000 0.000000';
|
||||
handlingValues['vecInertiaMultiplier'] = '1.000000 1.000000 1.000000';
|
||||
|
||||
const propertyOrder = [
|
||||
'fMass', 'fInitialDragCoeff', 'fPercentSubmerged',
|
||||
'vecCentreOfMassOffset', 'vecInertiaMultiplier', 'fDriveBiasFront',
|
||||
'nInitialDriveGears', 'fInitialDriveForce', 'fDriveInertia',
|
||||
'fClutchChangeRateScaleUpShift', 'fClutchChangeRateScaleDownShift',
|
||||
'fInitialDriveMaxFlatVel', 'fBrakeForce', 'fBrakeBiasFront',
|
||||
'fHandBrakeForce', 'fSteeringLock', 'fTractionCurveMax',
|
||||
'fTractionCurveMin', 'fTractionCurveLateral', 'fTractionSpringDeltaMax',
|
||||
'fLowSpeedTractionLossMult', 'fCamberStiffnesss', 'fTractionBiasFront',
|
||||
'fTractionLossMult', 'fSuspensionForce', 'fSuspensionCompDamp',
|
||||
'fSuspensionReboundDamp', 'fSuspensionUpperLimit', 'fSuspensionLowerLimit',
|
||||
'fSuspensionRaise', 'fSuspensionBiasFront', 'fAntiRollBarForce',
|
||||
'fAntiRollBarBiasFront', 'fRollCentreHeightFront', 'fRollCentreHeightRear',
|
||||
'fCollisionDamageMult', 'fWeaponDamageMult', 'fDeformationDamageMult',
|
||||
'fEngineDamageMult', 'fPetrolTankVolume', 'fOilVolume', 'fSeatOffsetDistX',
|
||||
'fSeatOffsetDistY', 'fSeatOffsetDistZ', 'nMonetaryValue', 'strModelFlags',
|
||||
'strHandlingFlags', 'strDamageFlags', 'AIHandling'
|
||||
];
|
||||
|
||||
propertyOrder.forEach(key => {
|
||||
if (handlingValues[key] !== undefined) {
|
||||
if (key.startsWith('vec')) {
|
||||
const [x, y, z] = handlingValues[key].split(' ');
|
||||
xmlContent += ` <${key} x="${x}" y="${y}" z="${z}" />\n`;
|
||||
} else if (key === 'strModelFlags' || key === 'strHandlingFlags' || key === 'strDamageFlags') {
|
||||
xmlContent += ` <${key}>${parseInt(handlingValues[key]).toString(16).toUpperCase()}</${key}>\n`;
|
||||
} else {
|
||||
xmlContent += ` <${key} value="${handlingValues[key]}" />\n`;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const subHandlingData = ` <SubHandlingData>
|
||||
<Item type="" />
|
||||
<Item type="" />
|
||||
<Item type="" />
|
||||
</SubHandlingData>\n`;
|
||||
|
||||
const finalXml = xmlHeader + xmlStart + xmlContent + subHandlingData + xmlEnd;
|
||||
const exportArea = document.getElementById('exportArea');
|
||||
exportArea.value = finalXml;
|
||||
exportArea.style.display = 'block';
|
||||
exportArea.select();
|
||||
document.execCommand('copy');
|
||||
}
|
||||
|
||||
const flagDefinitions = {
|
||||
strModelFlags: [
|
||||
"IS_VAN", "IS_BUS", "IS_LOW", "IS_BIG", "ABS_STD", "ABS_OPTION",
|
||||
"ABS_ALT_STD", "ABS_ALT_OPTION", "NO_DOORS", "TANDEM_SEATS",
|
||||
"SIT_IN_BOAT", "HAS_TRACKS", "NO_EXHAUST", "DOUBLE_EXHAUST",
|
||||
"NO1FPS_LOOK_BEHIND", "CAN_ENTER_IF_NO_DOOR", "AXLE_F_TORSION",
|
||||
"AXLE_F_SOLID", "AXLE_F_MCPHERSON", "ATTACH_PED_TO_BODYSHELL",
|
||||
"AXLE_R_TORSION", "AXLE_R_SOLID", "AXLE_R_MCPHERSON",
|
||||
"DONT_FORCE_GRND_CLEARANCE", "DONT_RENDER_STEER", "NO_WHEEL_BURST",
|
||||
"INDESTRUCTIBLE", "DOUBLE_FRONT_WHEELS", "FORCE_FRONT_WHEEL_WIDTH",
|
||||
"FORCE_REAR_WHEEL_WIDTH"
|
||||
],
|
||||
strHandlingFlags: [
|
||||
"SMOOTH_COMPRESN", "REDUCED_MOD_MASS", "DISTRIB_FRONT_MASS",
|
||||
"DISTRIB_REAR_MASS", "OFFROAD_ABILITY", "OFFROAD_ABILITY2",
|
||||
"HALOGEN_LIGHTS", "PROC_REARWHEEL_1ST", "USE_MAXSP_LIMIT",
|
||||
"LOW_RIDER", "STREET_RACER", "SWINGING_CHASSIS", "EXTREME_GRIP",
|
||||
"INCREASED_GRAVITY", "VERTICAL_FLIGHT_MODE", "DISABLE_GROUND_CLEARANCE",
|
||||
"RACING_HANDLING", "EMERGENCY_VEHICLE", "NO_HANDBRAKE",
|
||||
"CVT", "ALT_EXT_WHEEL_BOUNDS_BEH", "DONT_RAISE_BOUNDS_AT_SPEED",
|
||||
"NARROW_BOUNDS", "MEDIUM_BOUNDS", "WIDE_BOUNDS"
|
||||
],
|
||||
strDamageFlags: [
|
||||
"DRIVER_SIDE_FRONT_DOOR", "DRIVER_SIDE_REAR_DOOR", "DRIVER_PASSENGER_SIDE_FRONT_DOOR",
|
||||
"DRIVER_PASSENGER_SIDE_REAR_DOOR", "BONNET", "BOOT", "DRIVER_SIDE_FRONT_WINDOW",
|
||||
"DRIVER_SIDE_REAR_WINDOW", "PASSENGER_SIDE_FRONT_WINDOW", "PASSENGER_SIDE_REAR_WINDOW",
|
||||
"WINDSCREEN", "ENGINE", "ALL_WHEELS", "PETROL_TANK", "DOORS", "TRUNK", "WINDOWS",
|
||||
"ALL_PANELS", "WHEELS", "EXHAUST", "RADIATOR", "SUSPENSION", "BRAKES", "GEARBOX",
|
||||
"STEERING", "HEADLIGHTS", "TAILLIGHTS", "INDICATORS", "WIPERS", "MIRRORS"
|
||||
]
|
||||
};
|
||||
|
||||
function openEditor(data) {
|
||||
document.querySelector("#handlingLabel").innerHTML = data.vehicleName;
|
||||
let accordionContent = "";
|
||||
|
||||
const sortedEntries = Object.entries(data.data).sort((a, b) => a[0].localeCompare(b[0]));
|
||||
|
||||
for (let [i, dd] of sortedEntries) {
|
||||
if (i.startsWith('vec')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const isNumeric = dd.type === "float" || dd.type === "int";
|
||||
const isFlag = i === "strModelFlags" || i === "strHandlingFlags" || i === "strDamageFlags";
|
||||
|
||||
accordionContent += `
|
||||
<tr>
|
||||
<td>${dd.name}
|
||||
<button type="button" class="btn btn-secondary" data-bs-toggle="tooltip" data-bs-placement="top" data-bs-title="${dd.description}">
|
||||
i
|
||||
</button>
|
||||
${isNumeric ? `<small class="d-block text-muted">Min: ${dd.min} | Max: ${dd.max}</small>` : ''}
|
||||
</td>
|
||||
<td>${data.originalvalues[i]}</td>
|
||||
<td>
|
||||
<div class="input-group">
|
||||
${isNumeric ? `<button class="btn btn-outline-secondary" type="button" onclick="updateValue(this.parentElement.querySelector('input[type=text]'), -${dd.change}, '${i}')">-</button>` : ''}
|
||||
<input type="text"
|
||||
class="form-control"
|
||||
value="${data.values[i]}"
|
||||
data-min="${dd.min || 0}"
|
||||
data-max="${dd.max || 0}"
|
||||
data-type="${dd.type}"
|
||||
data-handling-key="${i}"
|
||||
onchange="updateValue(this, 0, '${i}')"
|
||||
>
|
||||
${isNumeric ? `<button class="btn btn-outline-secondary" type="button" onclick="updateValue(this.parentElement.querySelector('input[type=text]'), ${dd.change}, '${i}')">+</button>` : ''}
|
||||
${isNumeric && !isFlag ? `
|
||||
<input type="range"
|
||||
class="form-range"
|
||||
min="${dd.min}"
|
||||
max="${dd.max}"
|
||||
step="${dd.type === 'int' ? '1' : '0.000001'}"
|
||||
value="${data.values[i]}"
|
||||
oninput="updateFromSlider(this)"
|
||||
>
|
||||
` : ''}
|
||||
</div>
|
||||
${isFlag ? `
|
||||
<div class="flag-dropdown dropdown">
|
||||
<button class="btn dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
Selected Flags (${(parseInt(data.values[i], 16).toString(2).match(/1/g) || []).length})
|
||||
</button>
|
||||
<div class="dropdown-menu">
|
||||
${flagDefinitions[i].map((flag, index) => `
|
||||
<div class="dropdown-item">
|
||||
<input type="checkbox"
|
||||
id="${i}_${index}"
|
||||
${(parseInt(data.values[i], 16) & (1 << index)) ? 'checked' : ''}
|
||||
onchange="updateFlag(this, '${i}')"
|
||||
>
|
||||
<label for="${i}_${index}">${flag}</label>
|
||||
</div>
|
||||
`).join('')}
|
||||
</div>
|
||||
</div>
|
||||
` : ''}
|
||||
</td>
|
||||
</tr>
|
||||
`;
|
||||
}
|
||||
|
||||
document.querySelector("#handling-data-accordion").innerHTML = accordionContent;
|
||||
|
||||
openhandlingModal.show();
|
||||
const tooltipTriggerList = document.querySelectorAll('[data-bs-toggle="tooltip"]');
|
||||
const tooltipList = [...tooltipTriggerList].map(tooltipTriggerEl => new bootstrap.Tooltip(tooltipTriggerEl));
|
||||
}
|
||||
|
||||
function searchVehicles() {
|
||||
const searchInput = document.getElementById('searchBar').value.toLowerCase();
|
||||
const rows = document.getElementById('handling-data-accordion').getElementsByTagName('tr');
|
||||
|
||||
for (let row of rows) {
|
||||
const vehicleName = row.getElementsByTagName('td')[0].textContent.toLowerCase();
|
||||
if (vehicleName.includes(searchInput)) {
|
||||
row.style.display = '';
|
||||
} else {
|
||||
row.style.display = 'none';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
|
||||
while GetCurrentResourceName() ~= "jraxion_handlingeditor" do
|
||||
Wait(2000)
|
||||
print("Make sure the resource name is jraxion_handlingeditor, it will break the resource if you rename it.")
|
||||
end
|
||||
|
||||
RegisterCommand('handlingeditor', function(source, args, rawCommand)
|
||||
-- Add your permission system here.
|
||||
|
||||
if Config.isAllowed(source) then
|
||||
TriggerClientEvent('jraxion_handlingeditor:openHandlingEditor', source)
|
||||
else
|
||||
print('No permission')
|
||||
end
|
||||
end, false)
|
||||
Reference in New Issue
Block a user