forgot to add helicam

This commit is contained in:
KingMcDonalds
2025-03-07 07:18:31 -08:00
parent a85c9cedbc
commit f696f70d63
23 changed files with 6905 additions and 1 deletions
Binary file not shown.
File diff suppressed because it is too large Load Diff
+359
View File
@@ -0,0 +1,359 @@
Config = {}
Config.TimeFormat = 0 -- 0 = ZULU (UTC), 1 = In Game Time, 2 = OS TIME (Local Time)
Config.DateFormat = 1 -- 0 = MM/DD/YY, 1 = DD/MM/YY, 2 = YY/MM/DD, 3 = DD-Mon-YYYY
Config.PlaySounds = true
Config.PlayCameraMovementSounds = true -- If true, sounds will be played when you move the helicopter camera
Config.DisablePoliceScanner = true -- If true, disables the police radio/scanner/dispatch sounds.
Config.DisableFlightMusic = true -- If true, the ambiant flight music will be disabled.
Config.CameraTransition = false -- If true, the camera will ease when you enter/exit the camera
Config.CameraTransitionTime = 1000 -- The time the transition/ease will take.
Config.DefaultCameraTimecycle = false -- "modiferName" or false. If set to a modifer name (string) then all helicopters will have this timecycle effect unless spesifed under the model inside the Config.Helicopters table ("CAMERA_BW", "CAMERA_secuirity", "secret_camera" or any valid timecycle: https://wiki.rage.mp/index.php?title=Timecycle_Modifiers)
Config.DefaultCameraTimecycleStrength = 0.5 -- number, 0.0 to 1.0.
Config.ShowLatitudeLongitude = false -- If set to true, it shows latitude/longitude, otherwise it shows the street and area
Config.TargetMaxReach = 424.0 -- The longest distance we can target an entity (424 is the regular culling dist for a player, you won't ever be able to practically reach this long anyway)
Config.ForceCameraLabel = false -- false or "Label"
Config.CanUseAnyHelicopter = false -- If true, any helicopter can be used, if false, only helicopters in the Config.Helicopters table are allowed.
Config.AllowCameraLock = true -- If true, the camera can lock onto the ground/targets
Config.InstantCameraLock = false -- If true, the camera will immediately lock on to the target instead of requiering a grace period
Config.AllowCameraLockOnGround = true -- If true, the camera can lock onto the ground/buildings etc.
Config.CameraLockBreakTicks = 3 -- The maximum amount of ticks the camera can lose visual of the point/person/vehicle before it breaks.
-- If true, when locking onto an entity it will lock to the center of it, if false the camera locks onto the part of the entity you were aiming at right before locking.
Config.LockOntoCenter = {
Peds = true, -- It has a tendency to not work perfectly when this is false.
Vehicles = false
}
Config.ShowLicensePlate = true -- (LPL)
Config.CheckLicensePlateAngle = true -- If true, it checks the angle between the helicopter camera and the plate. This reasults in player beeing unable to get a license plate read when the camera can't clearly see the plate.
Config.OnlyShowPlateIfLocked = false -- If true, the plate will only be showed if we have a lock on the vehicle.
Config.WhitelistedJobs = false -- If false, the script doesn't check for jobs. If you want to check for jobs add a table where the job is the key, and the value is the job level like so: Config.WhitelistedJobs = { ['police'] = 2, ['ambulance'] = 5 }
Config.ShowMessageIfWrongJob = true -- If true, it will display an error message of you attempt to enter the camer without the right job, if false no message, just won't allow you to enter
-- false = Anyone can use the camera (including the pilot), 1 = Any passanger (not pilot) can use the camera, 2 = Only rear passangers can use the camera
Config.PassengerOnly = false
Config.ShowPostalCodes = false -- Shows postals while in the camera (This is a little resource heavy)
Config.PostalResource = "nearest-postal" -- The resource the postal file is located in (resource must be loaded before helicam, and the files must be formated like nearest-postal)
Config.PostalFile = "new-postals.json" -- MUST be a JSON file! (Note: The file must be loaded inside the fxmanifest of Config.PostalResource for the helicam script to be able to read it)
-- Adds a audio sumbix while in a helicopter/plane (noise suppression) (NOTE: Get's applied to all helicopters/planes, not just the ones with a camera)
Config.UseSubmix = false
Config.NoSubmixInCamera = false -- Only applys if Config.UseSubmix is set to true, if true, this will stop the submix when you are using the camera
-- If true, players will be able to rappel from helicopters that support it.
Config.AllowRappelling = true
Config.RappellingTimeout = 1000 -- The time in ms that you have to press the rappel button again (so people don't accidentally rappel)
Config.MaxRappellingHight = 35.0 -- At any higher then 35.0 players might fall off the rope as the game has a hardcoded cap around 30.0 - 40.0 meters.
-- If the script should add chat suggestions for some of the chat commands.
Config.AddChatSuggestions = true
-- Spotlight
Config.AllowSpotlight = true
Config.MaxAmountOfSpotlights = false -- false or number, set's the maximum amount of spotlights that are allowed on the server at any given time (global limit)
Config.Spotlight = {
Colour = { R = 255, G = 255, B = 255 }, -- The RGB colour values of the spotlight, you can for example make it slightly more blue like so: { R = 220, G = 220, B = 255 }
MaxDistance = 600.0, -- The maximum distance the spotlight will glow
DefaultBrightness = 5.0, -- The defult brightness of the spotlight
MinBrightness = 0.5, -- The minimum brightness of the spotlight
MaxBrightness = 15.0, -- The maximum brightness of the spotlight
BrightnessIncrements = 0.75, -- How much to change the brightness of the spotlight when adjusting it
Roundness = 2.0, -- The "roundness" of the spotlight
DefaultRadius = 10.0, -- The defult radius/size of the spotlight
MinRadius = 5.0, -- The minimum radius of the spotlight
MaxRadius = 15.0, -- The maximum radius of the spotlight
RadiusIncrements = 0.75, -- How much to change the radius of the spotlight when adjusting it
Falloff = 200.0, --
}
Config.HideMinimap = false
Config.ZoomBarOffset = 20 -- The offset in % from the bottom of the screen the zoom bar will be when the minimap is enabled. (If you have something on the top of your minimap then setting it to 25 usally works well)
Config.TargetBlip = {
Display = true,
Sprite = 390,
Colour = 40
}
Config.AllowNightVision = true
Config.AllowNightVisionDuringDay = false -- If the night vision can be enabeld during the day or not.
Config.AllowThermal = true
Config.ThermalOptions = {
MaxThickness = 1.0, -- 1.0 = Default GTA, can't see trough much at all. 20.0 = Able to see trough most thin walls, however won't be able to see trough the ground or multiple/thick walls.
MinNoise = 0.0, -- The minimum amount of background noise
MaxNoise = 0.1, -- The maximum amount of background noise
FadeStart = 5000.0, -- How far away (meters) before the "background" fade starts
FadeEnd = 6000.0, -- How far away (meters) before the "background" fade becomes solid
CustomColours = true, -- If we should use custom colours for the thermal camera (so it becomes black & white for example). (Colours are set below under Config.ThermalOptions.Colours)
Colours = {
VisibleHot = { R = 0.80, G = 0.80, B = 0.80 },
VisibleWarm = { R = 0.80, G = 0.80, B = 0.80 },
VisibleBase = { R = 0.80, G = 0.80, B = 0.80 },
Far = { R = 0.20, G = 0.20, B = 0.20 },
Near = { R = 0.15, G = 0.15, B = 0.15 }
}
}
Config.AllowMarkers = true
Config.Marker = {
MaxAmount = 9, -- Above 9 the number markers should be disabled.
MaxDrawDistance = 1000.0, -- The furthest distance a marker will be drawn at.
Circle = {
Type = 23,
Scale = 8.0,
Colour = { R = 230, G = 50, B = 50, A = 200 } -- { R = 110, G = 160, B = 230, A = 200 }
},
Number = {
Display = true, -- Set this to false if you want the max amount of markers the be above 9
Scale = 6.0,
Colour = { R = 230, G = 50, B = 50, A = 200 }
},
Blip = {
Display = true, -- Whether to display marker blips
Number = true, -- Whether to display the number on the blip or not (99 is cap.)
Sprite = 57,
Scale = 0.75,
Colour = 1, -- Red
}
}
Config.UseAnimProp = true -- If true, players will have a tablet in their hands while using the camera
Config.Tablet = {
model = -1585232418, -- prop_cs_tablet
anim = {
dict = "amb@world_human_seat_wall_tablet@female@base",
name = "base"
},
bone = 57005, -- SKEL_R_Hand
offset = vector3(0.17, 0.10, -0.13),
rotation = vector3(20.0, 180.0, 180.0)
}
Config.ShowInstructions = false -- If true, instructions will be showns while you are in the camera
-- Used this website to get the controls (~INPUT_5D25DCCD~ for example): http://tools.povers.fr/hashgenerator/
-- 0 = On the right, 3+ = on the left.
Config.InstructionButtons = {
-- [0] = { control = "~INPUT_5D25DCCD~", label = "Adjust Spotlight Brightness (scroll +)" },
-- [1] = { control = "~INPUT_F8C9FB3A~", label = "Adjust Spotlight Radius (scroll +)" },
-- [2] = { control = "~INPUT_DB481F5~", label = "Lock Camera" }, -- This doesn't work for some reason...
[0] = { control = "~INPUT_662F7BF5~", label = "Add/Remove Marker" },
[1] = { control = "~INPUT_DB471A88~", label = "Cycle Vision" },
[2] = { control = "~INPUT_51D50495~", label = "Spotlight" },
[3] = { control = "~INPUT_5D25DCCD~", label = "Exit Camera" }
}
-- Speed Units:
-- KTS = Knots (nautical miles per hour)
-- MPH = Miles per hour
-- KMH = Kilometers per hour
-- MPS = Meters per second
-- FPS = Feet per second
-- Distance Units:
-- FT = Feet
-- M = Meters
-- MI = Miles
Config.Units = {
Speed = "KTS", -- The speed of the helicopter (unit type: speed)
Altitude = "FT", -- The altitude of the helicopter (unit type: distance)
TargetSpeed = "MPH", -- The speed of the target the camera is looking at (unit type: speed)
TargetElevation = "FT", -- The elevation of where the camera is aming (unit type: distance)
TargetDistance = "M" -- The distance from the helicopter to the target (unit type: distance)
}
Config.Camera = {
MovementSpeed = {
Keyboard = 3.0,
Controller = 1.0
},
Zoom = {
Max = 50.0,
Min = 5.0,
Speed = 5.0
},
RotationLimits = {
Up = 25.0,
Down = -89.5
}
}
-- Docs: https://docs.fivem.net/docs/game-references/input-mapper-parameter-ids/ -- https://docs.fivem.net/docs/game-references/input-mapper-parameter-ids/keyboard/
Config.Keybinds = {
ToggleCam = {
Type = "KEYBOARD",
Key = "E"
},
AttemptLock = {
Type = "KEYBOARD",
Key = "SPACE"
},
CycleVision = {
Type = "MOUSE_BUTTON",
Key = "MOUSE_RIGHT"
},
ToggleMarker = {
Type = "MOUSE_BUTTON",
Key = "MOUSE_MIDDLE"
},
Rappel = {
Type = "KEYBOARD",
Key = "X"
},
Spotlight = {
Type = "KEYBOARD",
Key = "G"
},
SpotlightBrightness = {
Type = "KEYBOARD",
Key = "LMENU"
},
SpotlightRadius = {
Type = "KEYBOARD",
Key = "LCONTROL"
},
Postals = {
Type = "KEYBOARD",
Key = ""
}
}
Config.Localisation = {
-- Notifications
Notification = {
JobNotWhitelisted = "You don't have the required job!",
JobGrade = "Your job grade is to low!",
NoCameraHeli = "This helicopter doesn't have a camera!",
NoCameraPlane = "This plane doesn't have a camera!",
IsPilot = "You can't use the camera while you are the pilot!",
NotInRear = "You need to be in the rear of the helicopter to use the camera!",
CameraInUse = "Someone else is already using the camera!",
SpotlightInUse = "Someone else is already using the camera spotlight!",
NoSpotlight = "This helicopter does not have a spotlight!",
SpotlightGlobalLimit = "The global spotlight limit has been reached!",
CannotRappelFromHeli = "This helicopter does not support rappelling!",
CannotRappelFromSeat = "You cannot rappel from this seat!",
ToHighToRappel = "The helicopter is to far up to rappel!",
ConfirmRappel = "Are you sure you want to rappel? (Press again to confirm)",
Rappelling = "Rappelling!"
},
-- Blip Names
Blip = {
Target = "Helicam Target",
Marker = "Helicam Marker"
},
-- Keybinding Descriptions
KeyMapping = {
ToggleCam = "Helicam - Toggle Camera",
AttemptLock = "Helicam - Attempt Lock",
CycleVision = "Helicam - Cycle Vision",
ToggleMarker = "Helicam - Add/Remove Markers",
Rappel = "Helicam - Rappel From Helicopter",
Spotlight = "Helicam - Toggle Spotlight",
SpotlightBrightness = "Helicam - (+ scroll) Adjust Spotlight Brightness",
SpotlightRadius = "Helicam - (+ scroll) Adjust Spotlight Radius",
Postals = "Helicam - Toggle Postals"
},
ChatSuggestions = {
ToggleCamera = "Enter/Exit the helicopter camera",
Rappel = "Rappel from the helicopter"
}
}
-- Nightvision/Thermal/Spotlight/PassengerOnly etc. can be manually enabled/disabled (overwriten) for each model by adding one or more of following varabels under the model.
-- nightvision = true / false
-- thermalvision = true / false
-- spotlight = true / false
-- passengerOnly = false / 1 / 2 (see Config.PassengerOnly)
-- disableRappelling = true / false
-- timecycle = "modiferName" / false
-- timecycleStrength = 0.0 to 1.0
Config.Helicopters = {
-- Default (if there is any missing data it will draw it's options from here)
default = {
offset = vector3(0.0, 0.0, -1.0),
-- nightvision = true, -- These are only needed/used if Config.AllowNightVision or Config.AllowThermal is set to false
-- thermalvision = true, -- You can add these to each and every model, adding these and setting them to false disables the vision even if Config.AllowThermal etc. is set to true
-- spotlight = true, -- Allows yo overwrite Config.AllowSpotlight on a helicopter to helicopter basis.
-- passengerOnly = false, -- Set's who can use the camera based on the seat they are in. (see Config.PassengerOnly)
-- disableRappelling = false, -- Disables rappelling for the helicopter model, will only make a diffrence when set to true. The helicopter also needs the "FLAG_ALLOWS_RAPPEL" flag too allow you to rappel out of it.
-- timecycle = "CAMERA_BW", -- The timecycle modifer name (can be set to false if you want to disable it)
-- timecycleStrength = 0.5, -- The strength of the timecycle, defaults to Config.DefaultCameraTimecycleStrength if not included.
labels = {
[0] = "FLIR SYSTEMS"
}
},
-- Police Maverick (polmav)
[353883353] = {
offset = vector3(0.0, 2.65, -1.0),
labels = { -- Liveries
[0] = "LOS SANTOS POLICE DEPARTMENT", -- 0 is default
[1] = "AIR AMBULANCE"
}
},
-- Maverick (maverick)
[-1660661558] = {
offset = vector3(0.0, 3.45, -0.65)
},
-- Buzzard Attack Chopper (buzzard)
[788747387] = {
offset = vector3(0.0, 2.15, -0.35)
},
-- Buzzard (buzzard2)
[745926877] = {
offset = vector3(0.0, 2.15, -0.35)
},
-- Frogger (frogger)
[744705981] = {
offset = vector3(0.0, 3.0, -0.35)
},
-- TPI/FIB Frogger (frogger2)
[1949211328] = {
offset = vector3(0.0, 3.0, -0.35),
labels = { -- Liveries
[0] = "FEDERAL INVESTIGATION BUREAU",
[1] = "TREVOR PHILIPS ENTERPRISES"
}
},
-- Annihilator/Patriotism and Immigration Authority (annihilator)
[837858166] = {
offset = vector3(-0.5, 4.0, -0.35),
labels = { -- Liveries
[0] = "NATIONAL OFFICE OF SECURITY ENFORCMENT"
}
},
-- Valkyrie (valkyrie)
[-1600252419] = {
offset = vector3(0.0, 4.0, -1.15),
labels = { -- Liveries
[0] = "UNITED STATES ARMY"
}
},
-- Avenger (avenger)
[-2118308144] = {
offset = vector3(0.0, 9.45, -2.45),
labels = { -- Liveries
[0] = "UNITED STATES MARINES"
}
},
-- Example of custom helicopter:
-- Emergency Maverick AS350 (eheli)
-- [`eheli`] = {
-- offset = vector3(0.0, 3.0, -1.15),
-- labels = { -- Liveries
-- [0] = "LOS SANTOS POLICE DEPARTMENT",
-- [1] = "SAN ANDREAS HIGHWAY PATROL",
-- [2] = "BLAIN COUNTY SHERIFF OFFICE",
-- [3] = "SAN ANDREAS FIRE DEPARTMENT"
-- }
-- },
-- You can also do GetHashKey("eheli") instead of `eheli`
-- Here is a guide if you need more help: https://madsl.gitbook.io/docs/resources/helicopter-camera/adding-custom-helicopters
}
+20
View File
@@ -0,0 +1,20 @@
if GetResourceState('es_extended') ~= 'started' then return end
ESX = exports.es_extended:getSharedObject()
function JobCheck()
if Config.WhitelistedJobs == false then
return true, nil
end
local PlayerData = ESX.GetPlayerData()
if Config.WhitelistedJobs[PlayerData.job.name] then
if PlayerData.job.grade >= Config.WhitelistedJobs[PlayerData.job.name] then
return true, nil
else
return false, (Config.ShowMessageIfWrongJob and 'JobGrade') or nil
end
else
return false, (Config.ShowMessageIfWrongJob and 'JobNotWhitelisted') or nil
end
end
+20
View File
@@ -0,0 +1,20 @@
if GetResourceState('qb-core') ~= 'started' then return end
QBCore = exports['qb-core']:GetCoreObject()
function JobCheck()
if Config.WhitelistedJobs == false then
return true, nil
end
local PlayerData = QBCore.Functions.GetPlayerData()
if Config.WhitelistedJobs[PlayerData.job.name] then
if PlayerData.job.grade.level >= Config.WhitelistedJobs[PlayerData.job.name] then
return true, nil
else
return false, (Config.ShowMessageIfWrongJob and 'JobGrade') or nil
end
else
return false, (Config.ShowMessageIfWrongJob and 'JobNotWhitelisted') or nil
end
end
@@ -0,0 +1,9 @@
if GetResourceState('es_extended') == 'started' or GetResourceState('qb-core') == 'started' then return end
function JobCheck()
if Config.WhitelistedJobs ~= false then
print(GetCurrentResourceName().."/frameworks/standalone.lua: Jobs check failed, none of the supported frameworks are running, please set Config.WhitelistedJobs to false or make code adjustments.")
end
return true, nil
end
+44
View File
@@ -0,0 +1,44 @@
fx_version 'cerulean'
game 'gta5'
lua54 'yes'
author 'Mads'
description 'Helicam'
version '1.0.9'
client_scripts {
'config.lua',
'numberplates.lua',
'framework/standalone.lua',
'framework/esx.lua',
'framework/qb.lua',
'client.lua'
}
server_script 'server.lua'
escrow_ignore {
'config.lua',
'numberplates.lua',
'framework/standalone.lua',
'framework/esx.lua',
'framework/qb.lua',
'client.lua',
'server.lua'
}
ui_page('html/index.html')
files {
'html/index.html',
'html/script.js',
'html/style.css',
'html/images/*.svg'
}
dependencies {
'/server:5181',
'/gameBuild:2060' -- Needed due to usage of game events.
}
dependency '/assetpacks'
+3
View File
@@ -0,0 +1,3 @@
<svg height="100" width="180" xmlns="http://www.w3.org/2000/svg">
<polygon points="0 0, 180 0, 90 100"/>
</svg>

After

Width:  |  Height:  |  Size: 115 B

@@ -0,0 +1,13 @@
<svg width="320" height="20" xmlns="http://www.w3.org/2000/svg">
<text x="0" y="9" fill="white" style="font-family: 'Consolas', Helvetica, monospace; text-shadow: 2px 0 2px hsla(0, 0%, 0%, 0.3), -2px 0 1px hsla(0, 0%, 0%, 0.3), 0 2px 1px hsla(0, 0%, 0%, 0.3), 0 -2px 1px hsla(0, 0%, 0%, 0.3), 1px 1px 1px hsla(0, 0%, 0%, 0.3), -1px -1px 1px hsla(0, 0%, 0%, 0.3), 1px -1px 1px hsla(0, 0%, 0%, 0.3), -1px 1px 1px hsla(0, 0%, 0%, 0.3), -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black; font-size: 0.85em; font-weight: bold;" text-anchor="middle">N</text>
<text x="360" y="9" fill="white" style="font-family: 'Consolas', Helvetica, monospace; text-shadow: 2px 0 2px hsla(0, 0%, 0%, 0.3), -2px 0 1px hsla(0, 0%, 0%, 0.3), 0 2px 1px hsla(0, 0%, 0%, 0.3), 0 -2px 1px hsla(0, 0%, 0%, 0.3), 1px 1px 1px hsla(0, 0%, 0%, 0.3), -1px -1px 1px hsla(0, 0%, 0%, 0.3), 1px -1px 1px hsla(0, 0%, 0%, 0.3), -1px 1px 1px hsla(0, 0%, 0%, 0.3), -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black; font-size: 0.85em; font-weight: bold;" text-anchor="middle">N</text>
<text x="315" y="9" fill="white" style="font-family: 'Consolas', Helvetica, monospace; text-shadow: 2px 0 2px hsla(0, 0%, 0%, 0.3), -2px 0 1px hsla(0, 0%, 0%, 0.3), 0 2px 1px hsla(0, 0%, 0%, 0.3), 0 -2px 1px hsla(0, 0%, 0%, 0.3), 1px 1px 1px hsla(0, 0%, 0%, 0.3), -1px -1px 1px hsla(0, 0%, 0%, 0.3), 1px -1px 1px hsla(0, 0%, 0%, 0.3), -1px 1px 1px hsla(0, 0%, 0%, 0.3), -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black; font-size: 0.85em; font-weight: bold;" text-anchor="middle">NW</text>
<text x="-45" y="9" fill="white" style="font-family: 'Consolas', Helvetica, monospace; text-shadow: 2px 0 2px hsla(0, 0%, 0%, 0.3), -2px 0 1px hsla(0, 0%, 0%, 0.3), 0 2px 1px hsla(0, 0%, 0%, 0.3), 0 -2px 1px hsla(0, 0%, 0%, 0.3), 1px 1px 1px hsla(0, 0%, 0%, 0.3), -1px -1px 1px hsla(0, 0%, 0%, 0.3), 1px -1px 1px hsla(0, 0%, 0%, 0.3), -1px 1px 1px hsla(0, 0%, 0%, 0.3), -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black; font-size: 0.85em; font-weight: bold;" text-anchor="middle">NW</text>
<text x="45" y="9" fill="white" style="font-family: 'Consolas', Helvetica, monospace; text-shadow: 2px 0 2px hsla(0, 0%, 0%, 0.3), -2px 0 1px hsla(0, 0%, 0%, 0.3), 0 2px 1px hsla(0, 0%, 0%, 0.3), 0 -2px 1px hsla(0, 0%, 0%, 0.3), 1px 1px 1px hsla(0, 0%, 0%, 0.3), -1px -1px 1px hsla(0, 0%, 0%, 0.3), 1px -1px 1px hsla(0, 0%, 0%, 0.3), -1px 1px 1px hsla(0, 0%, 0%, 0.3), -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black; font-size: 0.85em; font-weight: bold;" text-anchor="middle">NE</text>
<text x="405" y="9" fill="white" style="font-family: 'Consolas', Helvetica, monospace; text-shadow: 2px 0 2px hsla(0, 0%, 0%, 0.3), -2px 0 1px hsla(0, 0%, 0%, 0.3), 0 2px 1px hsla(0, 0%, 0%, 0.3), 0 -2px 1px hsla(0, 0%, 0%, 0.3), 1px 1px 1px hsla(0, 0%, 0%, 0.3), -1px -1px 1px hsla(0, 0%, 0%, 0.3), 1px -1px 1px hsla(0, 0%, 0%, 0.3), -1px 1px 1px hsla(0, 0%, 0%, 0.3), -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black; font-size: 0.85em; font-weight: bold;" text-anchor="middle">NE</text>
<text x="90" y="9" fill="white" style="font-family: 'Consolas', Helvetica, monospace; text-shadow: 2px 0 2px hsla(0, 0%, 0%, 0.3), -2px 0 1px hsla(0, 0%, 0%, 0.3), 0 2px 1px hsla(0, 0%, 0%, 0.3), 0 -2px 1px hsla(0, 0%, 0%, 0.3), 1px 1px 1px hsla(0, 0%, 0%, 0.3), -1px -1px 1px hsla(0, 0%, 0%, 0.3), 1px -1px 1px hsla(0, 0%, 0%, 0.3), -1px 1px 1px hsla(0, 0%, 0%, 0.3), -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black; font-size: 0.85em; font-weight: bold;" text-anchor="middle">E</text>
<text x="135" y="9" fill="white" style="font-family: 'Consolas', Helvetica, monospace; text-shadow: 2px 0 2px hsla(0, 0%, 0%, 0.3), -2px 0 1px hsla(0, 0%, 0%, 0.3), 0 2px 1px hsla(0, 0%, 0%, 0.3), 0 -2px 1px hsla(0, 0%, 0%, 0.3), 1px 1px 1px hsla(0, 0%, 0%, 0.3), -1px -1px 1px hsla(0, 0%, 0%, 0.3), 1px -1px 1px hsla(0, 0%, 0%, 0.3), -1px 1px 1px hsla(0, 0%, 0%, 0.3), -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black; font-size: 0.85em; font-weight: bold;" text-anchor="middle">SE</text>
<text x="180" y="9" fill="white" style="font-family: 'Consolas', Helvetica, monospace; text-shadow: 2px 0 2px hsla(0, 0%, 0%, 0.3), -2px 0 1px hsla(0, 0%, 0%, 0.3), 0 2px 1px hsla(0, 0%, 0%, 0.3), 0 -2px 1px hsla(0, 0%, 0%, 0.3), 1px 1px 1px hsla(0, 0%, 0%, 0.3), -1px -1px 1px hsla(0, 0%, 0%, 0.3), 1px -1px 1px hsla(0, 0%, 0%, 0.3), -1px 1px 1px hsla(0, 0%, 0%, 0.3), -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black; font-size: 0.85em; font-weight: bold;" text-anchor="middle">S</text>
<text x="225" y="9" fill="white" style="font-family: 'Consolas', Helvetica, monospace; text-shadow: 2px 0 2px hsla(0, 0%, 0%, 0.3), -2px 0 1px hsla(0, 0%, 0%, 0.3), 0 2px 1px hsla(0, 0%, 0%, 0.3), 0 -2px 1px hsla(0, 0%, 0%, 0.3), 1px 1px 1px hsla(0, 0%, 0%, 0.3), -1px -1px 1px hsla(0, 0%, 0%, 0.3), 1px -1px 1px hsla(0, 0%, 0%, 0.3), -1px 1px 1px hsla(0, 0%, 0%, 0.3), -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black; font-size: 0.85em; font-weight: bold;" text-anchor="middle">SW</text>
<text x="270" y="9" fill="white" style="font-family: 'Consolas', Helvetica, monospace; text-shadow: 2px 0 2px hsla(0, 0%, 0%, 0.3), -2px 0 1px hsla(0, 0%, 0%, 0.3), 0 2px 1px hsla(0, 0%, 0%, 0.3), 0 -2px 1px hsla(0, 0%, 0%, 0.3), 1px 1px 1px hsla(0, 0%, 0%, 0.3), -1px -1px 1px hsla(0, 0%, 0%, 0.3), 1px -1px 1px hsla(0, 0%, 0%, 0.3), -1px 1px 1px hsla(0, 0%, 0%, 0.3), -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black; font-size: 0.85em; font-weight: bold;" text-anchor="middle">W</text>
</svg>

After

Width:  |  Height:  |  Size: 5.4 KiB

+63
View File
@@ -0,0 +1,63 @@
<svg class="svg" width="320" height="20" xmlns="http://www.w3.org/2000/svg">
<rect width="2" height="6" x="-90"/>
<rect width="2" height="4" x="-81"/>
<rect width="2" height="4" x="-72"/>
<rect width="2" height="4" x="-63"/>
<rect width="2" height="4" x="-54"/>
<rect width="2" height="6" x="-45"/>
<rect width="2" height="4" x="-36"/>
<rect width="2" height="4" x="-27"/>
<rect width="2" height="4" x="-18"/>
<rect width="2" height="4" x="-9"/>
<rect width="2" height="6" x="0"/>
<rect width="2" height="4" x="9"/>
<rect width="2" height="4" x="18"/>
<rect width="2" height="4" x="27"/>
<rect width="2" height="4" x="36"/>
<rect width="2" height="6" x="45"/>
<rect width="2" height="4" x="54"/>
<rect width="2" height="4" x="63"/>
<rect width="2" height="4" x="72"/>
<rect width="2" height="4" x="81"/>
<rect width="2" height="6" x="90"/>
<rect width="2" height="4" x="99"/>
<rect width="2" height="4" x="108"/>
<rect width="2" height="4" x="117"/>
<rect width="2" height="4" x="126"/>
<rect width="2" height="6" x="135"/>
<rect width="2" height="4" x="144"/>
<rect width="2" height="4" x="153"/>
<rect width="2" height="4" x="162"/>
<rect width="2" height="4" x="171"/>
<rect width="2" height="6" x="180"/>
<rect width="2" height="4" x="189"/>
<rect width="2" height="4" x="198"/>
<rect width="2" height="4" x="207"/>
<rect width="2" height="4" x="216"/>
<rect width="2" height="6" x="225"/>
<rect width="2" height="4" x="234"/>
<rect width="2" height="4" x="243"/>
<rect width="2" height="4" x="252"/>
<rect width="2" height="4" x="261"/>
<rect width="2" height="6" x="270"/>
<rect width="2" height="4" x="279"/>
<rect width="2" height="4" x="288"/>
<rect width="2" height="4" x="297"/>
<rect width="2" height="4" x="306"/>
<rect width="2" height="6" x="315"/>
<rect width="2" height="4" x="324"/>
<rect width="2" height="4" x="333"/>
<rect width="2" height="4" x="342"/>
<rect width="2" height="4" x="351"/>
<rect width="2" height="6" x="360"/>
<rect width="2" height="4" x="369"/>
<rect width="2" height="4" x="378"/>
<rect width="2" height="4" x="387"/>
<rect width="2" height="4" x="396"/>
<rect width="2" height="6" x="405"/>
<rect width="2" height="4" x="414"/>
<rect width="2" height="4" x="423"/>
<rect width="2" height="4" x="432"/>
<rect width="2" height="4" x="441"/>
<rect width="2" height="6" x="450"/>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

@@ -0,0 +1,7 @@
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="40" fill="none" stroke="#000" stroke-width="3.5"/>
<line x1="50" y1="3" x2="50" y2="17" fill="none" stroke="#000" stroke-width="3.5"/>
<line x1="97" y1="50" x2="90" y2="50" fill="none" stroke="#000" stroke-width="3.5"/>
<line x1="10" y1="50" x2="3" y2="50" fill="none" stroke="#000" stroke-width="3.5"/>
<line x1="50" y1="90" x2="50" y2="97" fill="none" stroke="#000" stroke-width="3.5"/>
</svg>

After

Width:  |  Height:  |  Size: 508 B

@@ -0,0 +1,7 @@
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
<path d="M 50 10 A 40 40 0 1 1 10 50" fill="none" stroke="#000" stroke-width="3.5"/>
<line x1="50" y1="3" x2="50" y2="12" fill="none" stroke="#000" stroke-width="3.5"/>
<line x1="97" y1="50" x2="83" y2="50" fill="none" stroke="#000" stroke-width="3.5"/>
<line x1="50" y1="97" x2="50" y2="90" fill="none" stroke="#000" stroke-width="3.5"/>
<line x1="12" y1="50" x2="2" y2="50" fill="none" stroke="#000" stroke-width="3.5"/>
</svg>

After

Width:  |  Height:  |  Size: 515 B

+3
View File
@@ -0,0 +1,3 @@
<svg width="10" height="100" xmlns="http://www.w3.org/2000/svg">
<line x1="5" y1="100" x2="5" y2="0" fill="none" stroke="#000" stroke-width="5"/>
</svg>

After

Width:  |  Height:  |  Size: 156 B

@@ -0,0 +1,11 @@
<svg version="1.0" xmlns="http://www.w3.org/2000/svg" width="180" height="100" viewBox="0 0 180 100"
preserveAspectRatio="xMidYMid meet">
<g transform="translate(0.0, 100.0) scale(0.05, -0.05)" fill="#000000" stroke="none">
<path d="M1501 1831 c-227 -227 -229 -231 -224 -316 4 -70 -4 -94 -46 -134 l-52 -49 -105 104 c-131 129 -118 131 -280 -32 -161 -162 -159 -147 -30 -278 l104 -105 -49 -52 c-40 -42 -64 -50 -134 -46 -85 5 -89 3 -316 -224 -268 -267 -260 -240 -113 -385 146 -144 116 -153 383 115 227 227 229 231 224 316 -4 70 4 94 46 134 l52 49 105 -104 c131 -129 118 -131 280 32 161 162 159 147 30 278 l-104 105 49 52 c40 42 64 50 134 46 85 -5 89 -3 316 224 268 267 259 237 115 383 -145 147 -118 155 -385 -113z"/>
<path d="M2780 940 l0 -520 90 0 90 0 0 520 0 520 -90 0 -90 0 0 -520z"/>
<path d="M2380 810 l0 -390 90 0 90 0 0 390 0 390 -90 0 -90 0 0 -390z"/>
<path d="M1980 650 l0 -230 90 0 90 0 0 230 0 230 -90 0 -90 0 0 -230z"/>
<path d="M1580 470 c0 -46 7 -50 90 -50 83 0 90 4 90 50 0 46 -7 50 -90 50 -83 0 -90 -4 -90 -50z"/>
<path d="M3180 440 c0 -11 41 -20 90 -20 50 0 90 9 90 20 0 11 -40 20 -90 20 -49 0 -90 -9 -90 -20z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

@@ -0,0 +1,5 @@
<svg width="20" height="20" xmlns="http://www.w3.org/2000/svg">
<line x1="1" y1="1" x2="18" y2="18" fill="none" stroke="#000" stroke-width="2.5"/>
<line x1="1" y1="18" x2="18" y2="1" fill="none" stroke="#000" stroke-width="2.5"/>
</svg>

After

Width:  |  Height:  |  Size: 246 B

@@ -0,0 +1,8 @@
<svg width="200" height="100" xmlns="http://www.w3.org/2000/svg">
<line x1="2" y1="44" x2="2" y2="56" fill="none" stroke="#000" stroke-width="2.75"/>
<line x1="197" y1="44" x2="197" y2="56" fill="none" stroke="#000" stroke-width="2.75"/>
<line x1="100" y1="4" x2="100" y2="31" fill="none" stroke="#000" stroke-width="2.75"/>
<line x1="118" y1="50" x2="145" y2="50" fill="none" stroke="#000" stroke-width="2.75"/>
<line x1="100" y1="68" x2="100" y2="95" fill="none" stroke="#000" stroke-width="2.75"/>
<line x1="55" y1="50" x2="82" y2="50" fill="none" stroke="#000" stroke-width="2.75"/>
</svg>

After

Width:  |  Height:  |  Size: 617 B

@@ -0,0 +1,7 @@
<svg width="150" height="15" xmlns="http://www.w3.org/2000/svg">
<line x1="5" y1="12" x2="147" y2="12" fill="none" stroke="#000" stroke-width="2"/>
<line x1="6" y1="12" x2="6" y2="2" fill="none" stroke="#000" stroke-width="2"/>
<line x1="115" y1="12" x2="115" y2="2" fill="none" stroke="#000" stroke-width="2"/>
<line x1="130" y1="12" x2="130" y2="2" fill="none" stroke="#000" stroke-width="2"/>
<line x1="146" y1="12" x2="146" y2="2" fill="none" stroke="#000" stroke-width="2"/>
</svg>

After

Width:  |  Height:  |  Size: 492 B

+144
View File
@@ -0,0 +1,144 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Helicam by Mads</title>
<link rel="stylesheet" href="style.css"/>
<script src="nui://game/ui/jquery.js" type="text/javascript"></script>
<script src="./script.js" type="text/javascript"></script>
</head>
<body>
<div id="wrapper">
<div id="helicopter-info">
<div>
<div id="satellite-wrapper" class="inline"><img id="satellite-icon" class="svg" src="images/satellite-icon.svg"></div>
<p class="text inline" id="camera-label">FLIR SYSTEMS</p>
</div>
<div class="street"><p class="text street-text no-left-padding" id="hi-street">None</p></div>
<div id="hi-container-left">
<p class="text inline" id="hi-latitude">.</p>
<div class="relative">
<div id="hi-sub-ll" class="info-data">
<div><p class="text inline no-left-padding">SPD</p><p class="text inline float-right" id="hi-speed">0</p></div>
<p class="text inline no-left-padding">ALT</p><p class="text inline float-right" id="hi-altitude">0</p>
</div>
<div id="hi-sub-lr" class="info-data">
<p class="text" id="hi-speed-unit">KTS</p>
<p class="text" id="hi-altitude-unit">FT</p>
</div>
</div>
</div>
<div id="hi-container-right">
<p class="text inline" id="hi-longitude">.</p>
<div class="relative">
<div id="hi-sub-rl" class="info-data">
<p class="text inline">HDG</p><p class="text inline float-right" id="hi-heading">0</p>
</div>
<div id="hi-sub-rr" class="info-data">
<p class="text inline">°T</p>
</div>
</div>
</div>
</div>
<div id="target-info">
<div><p class="text inline" id="mads-label">Made By Mads</p></div>
<div class="street" id="ta-street-wrapper"><p class="text street-text" id="ta-street">None</p></div>
<span id="ta-container-wrapper">
<div id="ta-container-left">
<p class="text inline" id="ta-latitude">.</p>
<div>
<div id="ta-sub-ll" class="info-data">
<div><p class="text inline">SPD</p><p class="text inline float-right" id="ta-speed">0</p></div>
<p class="text inline">ELV</p><p class="text inline float-right" id="ta-elevation">0</p>
</div>
<div id="ta-sub-lr" class="info-data">
<p class="text" id="ta-speed-unit">MPH</p>
<p class="text" id="ta-elevation-unit">FT</p>
</div>
</div>
</div>
<div id="ta-container-right">
<p class="text inline" id="ta-longitude">.</p>
<div>
<div id="ta-sub-rl" class="info-data">
<div><p class="text inline">HDG</p><p class="text inline float-right" id="ta-heading">0</p></div>
<p class="text inline">SLT</p><p class="text inline float-right" id="ta-distance">0</p>
</div>
<div id="ta-sub-rr" class="info-data">
<p class="text inline">°T</p>
<p id="ta-distance-unit" class="text inline">M</p>
</div>
<div id="numberplate-wrapper"><p class="text inline">LPL</p><p class="text inline float-right" id="ta-numberplate">---</p></div>
</div>
</div>
</span>
</div>
<div id="bearing-container">
<div class="bearing">
<p class="text inline" id="bearing-text">0°T</p>
</div>
<div id="bearing-arrow-container" class="bearing">
<img id="bearing-arrow" class="inline svg" src="images/arrow.svg">
</div>
<div class="bearing">
<!-- Modifed version of this: https://github.com/thelindat/compass/blob/master/html/index.html -->
<img id="bearing-img" class="svg" src="images/bearing.svg">
<img id="bearing-directions" src="images/bearing-directions.svg">
</div>
</div>
<div id="timedate-container">
<div><p class="text inline" id="date">21/08/22</p></div>
<div><p class="text inline" id="time">00:00:00 Z</p></div>
</div>
<div class="centered">
<span id="cross-wrapper">
<img id="target-cross" class="svg centered" src="images/target-cross.svg" alt="X">
<!-- <img id="target-cross-inner" class="svg centered" src="images/target-cross-inner.svg" alt="X"> --> <!-- To messy for my taste -->
</span>
</div>
<div id="lock-bar-container">
<p id="lock-bar-text" class="text">Scanning...</p>
<div id="lock-bar-wrapper">
<div id="lock-bar-progress"></div>
</div>
</div>
<div id="camera-info">
<div id="camera-info-stack">
<p id="vision-state" class="text">HDEO</p>
<p id="lock-state" class="text inline">LOCK</p><p id="lock-type" class="text inline">NONE</p>
</div>
<p class="text inline">W</p>
<span>
<img id="zoom-arrow" class="svg" src="images/arrow.svg">
<img id="zoom-bar" class="svg" src="images/zoom-bar.svg">
</span>
<p class="text inline">N</p>
</div>
<div id="relative-info">
<p class="text inline" id="camera-pitch"></p>
<div class="inline">
<img class="camera-img svg" src="images/camera-pitch.svg" alt="camera pitch">
<img id="pitch-line" class="camera-line svg" src="images/line.svg">
</div>
<div class="inline">
<img class="camera-img svg" src="images/camera-heading.svg" alt="camera heading">
<img id="heading-line" class="camera-line svg" src="images/line.svg">
</div>
<p id="camera-heading" class="text inline"></p>
</div>
<!-- <div id="north-infobox">
<div id="compass-arrow"></div>
</div> -->
</div>
</body>
</html>
+203
View File
@@ -0,0 +1,203 @@
window.onload = (e) => {
window.addEventListener('message', onMessageRecieved);
};
let config = {
timeFormat: 0,
dateFormat: 0
};
let lastZoomBarLength = 243; // (243px, default for 1920:1080)
const months = {
1: 'JAN', 2: 'FEB', 3: 'MAR', 4: 'APR', 5: 'MAY', 6: 'JUN', 7: 'JUL', 8: 'AUG', 9: 'SEP', 10: 'OCT', 11: 'NOV', 12: 'DEC'
};
function FormatDate(day, month, year) {
let date;
switch(config.dateFormat) {
case 0:
date = month+"/"+day+"/"+year.slice(-2); // 0 = MM/DD/YY
break;
case 1:
date = day+"/"+month+"/"+year.slice(-2); // 1 = DD/MM/YY
break;
case 2:
date = year.slice(-2)+"/"+month+"/"+day; // 2 = YY/MM/DD
break;
case 3:
date = day+"-"+months[month]+"-"+year; // 2 = DD-Mon-YYYY
break;
default:
console.log("Error: date format was invalid!");
}
$("#date").text(date);
};
function UpdateZuluTime() {
const date = new Date();
const hours = date.getUTCHours().toLocaleString('en-US', { minimumIntegerDigits: 2, useGrouping: false });
const minutes = date.getUTCMinutes().toLocaleString('en-US', { minimumIntegerDigits: 2, useGrouping: false });
const seconds = date.getUTCSeconds().toLocaleString('en-US', { minimumIntegerDigits: 2, useGrouping: false });
const time = hours+":"+minutes+":"+seconds+" Z";
$("#time").text(time);
const day = date.getUTCDate().toLocaleString('en-US', { minimumIntegerDigits: 2, useGrouping: false });
let month = date.getUTCMonth()+1; month = month.toLocaleString('en-US', { minimumIntegerDigits: 2, useGrouping: false });
const year = date.getUTCFullYear().toLocaleString('en-US', { minimumIntegerDigits: 2, useGrouping: false });
FormatDate(day, month, year);
};
function UpdateOSTime() {
const date = new Date();
let hours = date.getHours().toLocaleString('en-US', { minimumIntegerDigits: 2, useGrouping: false });
let minutes = date.getMinutes().toLocaleString('en-US', { minimumIntegerDigits: 2, useGrouping: false });
let seconds = date.getSeconds().toLocaleString('en-US', { minimumIntegerDigits: 2, useGrouping: false });
let time = hours+":"+minutes+":"+seconds
$("#time").text(time);
};
function UpdateOSDate() {
const date = new Date();
const day = date.getDate().toLocaleString('en-US', { minimumIntegerDigits: 2, useGrouping: false });
let month = date.getMonth()+1; month = month.toLocaleString('en-US', { minimumIntegerDigits: 2, useGrouping: false });
const year = date.getFullYear().toLocaleString('en-US', { minimumIntegerDigits: 2, useGrouping: false });
FormatDate(day, month, year);
};
function onMessageRecieved(event) {
let data = event.data;
if (data != undefined) {
switch(data.action) {
case 'updateData':
$.each(data.set, function(id, value) {
$("#"+id).text(value);
});
// Show/hide/change license plate
if (data.info.numberplate == false) {
$("#numberplate-wrapper").hide();
} else if (data.info.numberplate != undefined) {
$("#ta-numberplate").text(data.info.numberplate);
if (!$("#numberplate-wrapper").is(":visible")) {
$("#numberplate-wrapper").show();
};
};
// Handle time and date
if (data.info.time) {
UpdateOSDate();
$("#time").text(data.info.time);
} else {
if (config.timeFormat == 0) {
UpdateZuluTime();
} else {
UpdateOSTime();
UpdateOSDate();
};
};
break;
case 'updateDataFrame':
// Camera Pitch
$('#pitch-line').css('transform', 'rotate(' + data.pitch + 'deg)');
// Camera Relative Heading
$('#heading-line').css('transform', 'rotate(' + data.heading + 'deg)');
// Bearing
$('#bearing-img').attr('src', 'images/bearing.svg#svgView(viewBox(' + (data.bearing - 89) + ', 0, 180, 8))');
$('#bearing-directions').attr('src', 'images/bearing-directions.svg#svgView(viewBox(' + (data.bearing - 90) + ', 0, 180, 10))');
break;
case 'setVisionState':
$("#vision-state").text(data.state); // Sets text in bottom left corner
break;
case 'setZoomBarLevel':
let barLength = $("#zoom-bar").width() || lastZoomBarLength;
let barPercent = barLength / 100;
if (barLength != lastZoomBarLength) {
lastZoomBarLength = barLength;
};
barLength = barLength - barPercent * 17.5 // Reduce the bar length by 17.5% to compensate for overflow
let pixels = barLength / 100 * data.percentage + barPercent * 5;
$("#zoom-arrow").css("margin-left", pixels + "px");
break;
case 'open':
$("#wrapper").show();
break;
case 'close':
$("#wrapper").hide();
break;
case 'startLockScanning':
$("#lock-bar-container").show();
$("#lock-bar-progress").stop().css({"width": 0}).animate({
width: 11 +'%'
}, {
duration: parseInt(200),
});
break;
case 'updateLockScanning':
const end = data.value * 10 + 1
$("#lock-bar-progress").stop().animate({
width: end+'%'
}, {
duration: parseInt(200),
easing : "linear"
});
break;
case 'lockScanningFinished':
$("#lock-bar-container").hide();
break;
case 'setCameraLockState':
if (data.state == true) {
$("#lock-state").addClass("lock-state-active");
} else {
$("#lock-state").removeClass("lock-state-active");
};
$("#lock-type").text(data.type);
break;
case 'setCameraLabel':
$("#camera-label").text(data.label);
break;
case 'setConfigData':
$.each(data.set, function(id, value) {
$("#"+id).text(value);
});
if (data.showLatitudeLongitude == true) {
$("#hi-latitude").show();
$("#hi-longitude").show();
$("#ta-latitude").show();
$("#ta-longitude").show();
} else {
$(".street").css('display', 'inline-block');
};
if (data.showLicensePlate == false) {
$("#numberplate-wrapper").hide();
};
if (data.hideMinimap == false) {
$("#camera-info").css("bottom", data.zoomBarOffset+"%");
};
if (data.showInstructions == true) {
$("#relative-info").css("bottom", "6%");
if (data.hideMinimap == true) {
$("#camera-info").css("bottom", "6%");
};
};
config.timeFormat = data.timeFormat;
config.dateFormat = data.dateFormat;
break;
default:
console.log("Error: spesifed action was not found!", data.action);
}
} else {
console.log("Error: data was not defined!");
};
};
+364
View File
@@ -0,0 +1,364 @@
/* General */
#wrapper {
display: none;
}
.text {
padding-top: 0.05vh;
padding-left: 0.5vh;
margin: 0;
color: rgb(255, 255, 255); /* rgb(50, 170, 35) <-- Green-ish */
font-family: 'Consolas', Helvetica, monospace;
text-shadow: 2px 0 2px hsla(0, 0%, 0%, 0.3), -2px 0 1px hsla(0, 0%, 0%, 0.3), 0 2px 1px hsla(0, 0%, 0%, 0.3), 0 -2px 1px hsla(0, 0%, 0%, 0.3), 1px 1px 1px hsla(0, 0%, 0%, 0.3), -1px -1px 1px hsla(0, 0%, 0%, 0.3), 1px -1px 1px hsla(0, 0%, 0%, 0.3), -1px 1px 1px hsla(0, 0%, 0%, 0.3), -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black;
font-size: 2.35vh; /* font-size: 1.55rem; */
font-weight: bold;
}
.no-left-padding {
padding-left: 0;
}
.float-right {
float: right;
}
.relative {
position: relative;
}
.inline {
display: inline-block;
}
.street {
display: none;
width: 100%;
}
.street-text {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
/*
This is were you set the colour for the svg images (bearing, crosshair etc.)
Use this to "translate" the colour; https://codepen.io/sosuke/pen/Pjoqqp
The "Green-ish" mentioned with the text would for example be like this: invert(51%) sepia(9%) saturate(4544%) hue-rotate(68deg) brightness(102%) contrast(85%) drop-shadow(-1px -1px 0px #00000096) drop-shadow(1px -1px 0px #00000096) drop-shadow(1px 1px 0px #00000096) drop-shadow(-1px 1px 0px #00000096);
Note: if you are going to change the colour, remember to also change it inside the bearing-directions.svg aswell (fill="white" -> fill="#32AA23" for "green-ish")
*/
.svg {
filter: invert(100%) sepia(100%) saturate(0%) hue-rotate(51deg) brightness(106%) contrast(101%) drop-shadow(-1px -1px 0px #00000096) drop-shadow(1px -1px 0px #00000096) drop-shadow(1px 1px 0px #00000096) drop-shadow(-1px 1px 0px #00000096);
}
/* Helicopter Info (top left) */
#helicopter-info {
display: inline-block;
margin-top: 2vh;
margin-left: 1vw;
margin-right: 0;
width: 35vw;
padding: 0;
}
#satellite-wrapper {
width: 4vh;
}
#satellite-icon {
margin-bottom: -0.35vh;
width: 100%;
}
#camera-label {
margin-left: 0;
}
.info-data {
display: inline-block;
vertical-align: top;
}
#hi-container-left {
display: inline-block;
}
#hi-latitude {
display: none;
}
#hi-sub-ll {
min-width: 8vw;
width: calc(100% - 3.15vw);
}
#hi-sub-lr {
float: right;
margin: 0;
margin-left: 0.15vw;
width: 3vw;
}
#hi-container-right {
display: inline-block;
}
#hi-longitude {
display: none;
}
#hi-sub-rl {
min-width: 8vw;
width: calc(100% - 2.25vw);
}
#hi-sub-rr {
float: right;
margin: 0;
margin-left: 0.15vw;
width: 2vw;
}
/* Target Info (top right) */
#target-info {
float: right;
margin-top: 2vh;
margin-left: 0;
margin-right: 1vw;
max-width: 35vw;
height: 25vh;
padding: 0;
}
#mads-label {
color: rgba(255, 255, 255, 0);
opacity: 0.0;
}
#ta-street-wrapper {
float: right;
text-align: right;
}
#ta-container-wrapper {
float: right;
}
#ta-container-left {
float: left;
margin-right: 1vw;
}
#ta-latitude {
display: none;
}
#ta-sub-ll {
min-width: 8vw;
width: calc(100% - 3.15vw);
}
#ta-sub-lr {
float: right;
margin: 0;
margin-left: 0.15vw;
width: 3vw;
}
#ta-container-right {
float: right;
}
#ta-longitude {
display: none;
}
#ta-sub-rl {
min-width: 8vw;
width: calc(100% - 2.5vw);
}
#ta-sub-rr {
float: right;
margin: 0;
margin-left: 0.25vw;
width: 2.25vw;
}
/* bearing */
#bearing-container {
width: 24.5vw;
position: absolute;
top: 2%;
left: 50%;
transform: translateX(-50%);
}
#bearing-img {
width: 30vh;
}
#bearing-directions {
margin-top: 0.25vh;
width: 30vh;
}
.bearing {
display: inline-block;
text-align: center;
width: 100%;
}
#bearing-arrow-container {
width: 2vh;
display: block;
margin-left: auto;
margin-right: auto;
}
#bearing-arrow {
width: 100%;
height: auto;
}
#bearing-letters {
margin: 0;
}
#timedate-container {
margin-top: 4vh;
margin-left: 1vw;
width: 12vw;
height: 6vh;
}
.centered {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
#cross-wrapper {
position: relative;
}
#target-cross {
height: 13vh;
}
#target-cross-inner {
height: 3vh;
}
#lock-bar-container {
display: none;
position: absolute;
left: 50%;
top: 60%;
transform: translate(-50%, -50%);
overflow: hidden;
text-align: center;
}
#lock-bar-text {
margin-bottom: 0.5vh;
}
#lock-bar-wrapper {
background-color: rgba(0, 0, 0, 0.15);
width: 15vw;
height: 0.85vh;
border-radius: 0.25vh;
border: 2px solid hsla(0, 0%, 0%, 0.4);
}
#lock-bar-progress {
background-color: rgba(255, 255, 255, 0.95);
z-index: 2;
height: 100%;
width: 0%;
}
#relative-info {
position: absolute;
left: 50%;
bottom: 2%;
transform: translate(-50%, 0%);
}
#camera-pitch, #camera-heading {
width: 2vw;
}
.camera-img {
position: relative;
z-index: 44;
width: 12.4vh;
}
.camera-line {
position: absolute;
margin-left: -6.65vh;;
margin-top: 1.4vh;
height: 4.8vh;
width: 0.8vh;
transform: rotate(90deg);
transform-origin: bottom;
}
#camera-info {
position: absolute;
bottom: 2%;
left: 0;
margin-left: 1vw;
}
#camera-info-stack {
margin-bottom: 2vh;
}
#lock-state {
margin-right: 0.8vh;
}
.lock-state-active {
color: rgb(200, 0, 0);
}
#zoom-arrow {
position: absolute;
width: 2vh;
z-index: 2;
margin-top: 0.3vh;
margin-left: 1vh;
}
#zoom-bar {
height: 2.25vh;
}
/* #north-infobox {
margin-top: 6vh;
margin-left: 2vh;
width: 10vw;
height: 12vh;
background-color: rgba(78, 36, 36, 0.288);
}
#compass-arrow{
transform-origin : center left;
background:#000;
width: 5vw;
height: 2vh;
position: absolute;
} */
File diff suppressed because it is too large Load Diff
+53
View File
@@ -0,0 +1,53 @@
local helicopters = {}
GlobalState.heliSpotlightsActive = 0
RegisterServerEvent('helicam:enterCamera')
AddEventHandler('helicam:enterCamera', function(heliNetId)
local helicopter = Entity(NetworkGetEntityFromNetworkId(heliNetId))
if helicopter and not helicopter.state.heliCamInUse then
helicopter.state.heliCamInUse = true
helicopter.state.heliCamTargetBlip = false
helicopter.state.heliCamSpotlightData = nil
if not helicopter.state.heliCamMarkers then
helicopter.state.heliCamMarkers = {}
end
helicopters[source] = heliNetId
TriggerClientEvent('helicam:enterCamera', source, true)
else
TriggerClientEvent('helicam:enterCamera', source, false)
end
end)
RegisterServerEvent('helicam:leaveCamera')
AddEventHandler('helicam:leaveCamera', function(heliNetId)
local helicopter = Entity(NetworkGetEntityFromNetworkId(heliNetId))
helicopter.state.heliCamInUse = false
helicopter.state.heliCamTargetBlip = nil
if source ~= nil and source ~= "" then
helicopters[source] = nil
end
end)
RegisterServerEvent('helicam:setStateBag')
AddEventHandler('helicam:setStateBag', function(heliNetId, bagName, value)
local helicopter = Entity(NetworkGetEntityFromNetworkId(heliNetId))
helicopter.state[bagName] = value
end)
RegisterServerEvent('helicam:toggleSpotlight')
AddEventHandler('helicam:toggleSpotlight', function(state)
if state then
GlobalState.heliSpotlightsActive += 1
else
GlobalState.heliSpotlightsActive -= 1
end
end)
-- If a player crashes/leaves while in the camera
AddEventHandler('playerDropped', function(reason)
if helicopters[source] then
TriggerEvent('helicam:leaveCamera', helicopters[source])
Player(source).state.heliCamSpotlightData = { position = false, helicopter = helicopters[source] }
helicopters[source] = nil
end
end)
+1 -1
View File
@@ -244,7 +244,7 @@ add_ace resource.sonoran_updatehelper command allow
ensure ulc
ensure reverse-hud
ensure taser_effect-main
ensure
ensure helicam
ensure
******christmasmaps******