-
Notifications
You must be signed in to change notification settings - Fork 19
Emergency Vehicle Properties
This page is designed to serve as a reference for the different sections in an emergency vehicle (EMV) file.
EMV.Siren = 1
This defines the default siren driver used by the vehicle. The number references how the sirens are internally indexed. For a complete list of available sirens, please see the Siren Index.
EMV.AuxiliarySiren = 1
This defines the secondary siren driver used by the vehicle. The number references how the sirens are internally indexed. For a complete list of available sirens, please see the Siren Index.
EMV.RadarDisabled = true
This disables the use of the radar for the vehicle. Useful if you want to make emergency vehicles which are not used for policing.
EMV.Color = Color( 255, 255, 255 )
This is the default color used by the vehicle when it is spawned. By default cars are spawned white (255, 255, 255). If you are applying a skin to the vehicle, leave this as "nil," as Photon will automatically use white.
To utilize a skin number, do:
EMV.Skin = 0
To use a skin without needing to create a skin index (recommended), do:
EMV.Skin = "my_skin_folder/skin_name"
To add the livery option to your vehicle.
The first table name is the name of the category. The name of the index is the name of the option. The string is the path to your skin material.
EMV.Liveries = { ["Police"] = { ["Police"] = "models/supermighty/police", ["LIVERY NAME"] = "path/to/skin", ["LIVERY NAME"] = "path/to/skin", ["LIVERY NAME"] = "path/to/skin" }, }
To add multiple props and components configuration among which you can choose in game.
The Name is the name that will be displayed in the contextual menu. The name inside the option = {} is the name that will be displayed under the main option name that you set before. the numbers inside Auto = {} are the indexes of the components you will make appear with this option and the numbers in Props = {} are the indexes of the props you will make appear with this option.
EMV.Selections = { { Name = "Name of the first option", Options = { { Name = "First Possible Option", Auto = { 1,4,5 }}, { Name = "Second Possible Option", Auto = { 2,3,4,5 }, Props = { 5 }}, { Name = "Third Possible Option" }, }, }, { Name = "Name of the second option", Options = { { Name = "First Possible Option", Props = { 1,2 }}, { Name = "Second Possible Option", Props = { 3 }}, { Name = "Third Possible Option", Auto = { 6 }, Props = { 4 }}, }, } }
To add static props (decorative), add prop information in this table.
Lightbars should be included in the EMV.Presets property table so they can be swapped or adjusted by the player.
EMV.Props = { { Model = "models/modelname.mdl", Pos = Vector( 0, 0, 0 ), Ang = Angle( 0, 0, 0 ), Scale = 1 } }
The file path the model, including the /models/ folder. Must include the .mdl extension.
A vector that defines the local position to the vehicle you're attaching to.
An angle that defines the local angle to the vehicle you're attaching to.
A float that scales the prop in all directions. Using 1 means the prop is at 100%, or default size. Scale can also be a vector.
Scale = Vector(1, 2, 1.5),
Optional The desired skin of the prop's model. The default skin is 0.
Skin = 0
Optional A table full of key, value pairs that adjust the prop's bodygroups.
BodyGroups = { { 1, 1 } }
Optional The desired color of the prop's model. The default color is Color(255, 255, 255).
Color = Color(255, 255, 255)
Optional This option allows you to overwrite the entire props material. Replace the path with the material of choice.
Material = "photon/override/blank"
Optional A table full of material overwrites. The number references the id of the material which should be overwritten. The string defines the path to the material. This property is optional and does not have to be defined in the code.
SubMaterials = { ["1"] = "photon/override/blank" }
EMV.SubMaterials = { ["26"] = "photon/override/blank", ["23"] = "photon/override/blank" }
A table full of material overwrites. The number references the id of the material which should be overwritten. The string defines the path to the material.
Tables in the "Meta" section are essentially templates that the light positions use. Supported properties are commonly added to support additional functionality.
meta_name = { AngleOffset = -90, W = 8.1, H = 7.5, Sprite = "sprites/emv/emv_whelen_src", Scale = 1.4 },
The name/key should be a unique string (meaning no duplicates per vehicle).
The angle offset refers to the default Y position. Because vehicles typically spawn with the side facing you, the front of the vehicle is generally -90 while the rear is 90. This is not a required property, however it allows many lights to use Angle( 0, 0, 0 ) which generally looks neater.
This is a number value that defines the width of your source sprite (see below).
This is a number value that defines the height of your source sprite (see below).
This is the path to template's light source sprite. Choosing or creating the correct sprite is essential for light to look realistic.
To create lights that do not have a source sprite, do: Sprite = "sprites/emv/blank",
You should not use blank sprites unless you are working on a complex shape or using the material override feature.
The Scale property is the multiplier of the apparent emitted light. A higher scale will make the light appear brighter.
This functions similar to Scale, but only affects the width of the light. By default, the lights render assuming the light source is slightly rectangular (not a perfect square). When working on lightbars where each module is rather wide compared to its height, it's recommended to increase the WMult value for a more realistic effect.
It should be noted that anything above 3-4 (unless the light is very small) should be broken into multiple lights, as the light effect will look odd when viewing the light source at an angle when it is too wide.
When working on large or complex lights, you may find it more effective to create one source sprite that emits no lighting effects. An example of this strategy would be the SGM Taurus taillights, where one primary source sprite is used while several smaller ones compose the apparent emitted light.
To make the light rotate, set the AngleOffset to R, as in: AngleOffset = "R",
.
For more information, see Rotating Lights.
This only affects rotating lights, and impacts how fast the light appears to rotate: Speed = 10
Every light position you need to use must be added to this table.
EMV.Positions = { [1] = { Vector( 10.16, 118.2, 35.17 ), Angle( 0, 0, 15.2 ), "grille_leds" }, [2] = { Vector( -10.16, 118.2, 35.17 ), Angle( 0, 0, 15.2 ), "grille_leds" }, }
For each light, it is recommended you add the light's key index with [1] = { ... }
, as it becomes much easier to reference the light when assembling frames and patterns. It is, however, optional. It should be noted, however, that the indexes must be accurate and successive.
For example, consider this snippet:
[1] = { ... }, [2] = { ... }, [4] = { ... }
Index number 3 is omitted. This will break the table and it will not render, so each number must match the actual index. You may also comment the light number at the end, however the numbers can easily become disjointed.
Best practice also suggests grouping symmetrical lights. When lights are symmetrical, only the the X values will be opposite (one positive and one negative) while the rest is generally the same (except when the lights are at an angle). This makes it easier to identify later on.
This is a vector that defines its position local to the vehicle model.
For symmetrical lights on a vehicle that is correctly zeroed, the X values will be opposite.
This is an angle that defines its direction local to the vehicle model.
Angles can pose a problem when you are mirroring lights across a vehicle.
The positions in angles are defined in the order of pitch, yaw and roll, respectively. This chart demonstrates how symmetrical lights should be adjusted.
For ease of translation, you can do simple equations that include 180. For example, these lights are symmetrical:
[19] = { Vector( 47.97, 30.5, 51.77 ), Angle( 1.18 - 180, -28.66, 180 - 6.3 ), "mirror_leds" }, [20] = { Vector( -47.97, 30.5, 51.77 ), Angle( 1.18, 28.66, 6.3 ), "mirror_leds" },This can be difficult when the light has every direction at a non-0 value.
This is a string value that should be the name of the template as described in EMV.Meta.
A section is a group of light positions. Within each defined sections, you create tables. Every table represents a "frame" that is referenced in EMV.Patterns.
The name and lights you place in each frame is completely arbitrary (meaning, it's however you want it). Within each frame you create
EMV.Sections = { ["grille_leds"] = { { { 1, B }, { 2, R } }, { { 1, B } }, { { 2, R } }, }, }
["grille_leds"] = {
This name is entirely arbitrary, but it must be unique and referenced later.
{ { 1, B }, { 2, R } },
This is Frame #1 in the grille_leds section from the example snippet above. Within this frame there are two defined lights and their respective colors. Position 1 is colored blue and position 2 is colored red.
{ { 1, B } },
This is Frame #2 in the grille_leds section. It means that within the grille_leds section, only position 1 will be appear on, and it will be colored blue.
{ { 2, R } },
Just as above, this means within the grille_leds section, only position 2 will be on, and it will be colored red.
Patterns creates a similar table to what was established in EMV.Sections, however within patterns you create a flash sequence based on the frames created within the sections.
EMV.Patterns = { ["grille_leds"] = { ["flash"] = { 1, 0, 1, 0, 0, 0, }, ["code2"] = { 2, 2, 2, 0, 0, 3, 3, 3, 0, 0 }, ["code3"] = { 2, 0, 2, 0, 3, 0, 3, 0 } }, }
Each number in the sequences are references to the aforementioned frames, while 0 means the section is "off," and no lights will appear within that section during the frame duration.
Frame durations are, at minimum, .05 seconds, meaning the lights will flash at 20 FPS. Due to visual glitches when the player's FPS drops below this number, Photon's frame durations will increase (get slower) to ensure the sequence still properly renders to the player.
["flash"] = { 1, 0, 1, 0, 0, 0, },
Consider this pattern. The "flash" title is also an arbitrary title, however it will be used later when lighting modes are defined.
In this particular instance, this sequence activates Frame #1, which, as defined in EMV.Sections is: { { 1, B }, { 2, R } },
This means the "flash" sequence will turn on both lights for one frame duration, go off for one frame duration, go on again, then off for three frame durations. Because each frame only lasts one frame duration, to make the lights stay on longer for a slower pattern, you would need to duplicate the frame. For example, to make both lights stay on for about one second, then go off for one second, you would do the following:
["flash"] = { 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 },
The Sequences property table includes all "light mode" information, or, as it's frequently referenced, "Code" states. Photon currently supports three sub-tables within the Sequences property. While they behave somewhat differently in practice, assigning patterns to components works the same for every sub group.
While the organization of each component section varies slightly, the lowest-tier table assigns a defined component to a defined pattern. Please note that the syntax of ["component"] = "pattern",
must be followed in accordance with the Lua table key-value pair syntax.
Using the example of ["grille_leds"]
above, you can see there are three defined and available patterns: flash
, code2
, and code3
. To assign a pattern to the ["grille_leds"]
component, you would write something like ["grille_leds"] = "flash"
, meaning the lights we defined for grille_leds
will flash based on the flash
pattern defined.
You may use the same pattern for multiple light modes.
{ Name = "NAME", ... }
This is the name that is displayed on player HUD whenever the light mode is active.
{ ... Disconnect = { 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 } ... }
For primary and illumination, indexes in this table will prevent the basic vehicle lights at the listed indexes. For the traffic/auxiliary sequences, these indexes only apply to emergency lighting. For example, a lightbar may be set up to flash standard warning patterns in the rear, but when the traffic advisor function is enabled, the light modules the advisor uses will turn off for the warning patterns in order to correctly enable the traffic advisor's pattern.
{ ... Components = { ["reverse"] = "flash", ["headlights"] = "code3" }, ... }
The Components
property table assigns patterns to components and affects all emergency lighting configurations. With the introduction of emergency lighting presets, the Components
property should only be used for lights that cannot be hidden, such as light points on the vehicle model that are not included in a bodygroup and are not from an added prop. In most cases, the only components that should be listed here are headlights, reverse, and taillights, as those are usually permanently attached to the car. However, even those can be included as preset assignments (see below).
In other words, any lights that instructed to go off within the Components
cannot be changed by either the Photon or Bodygroup menu, so use of it should typically be avoided.
{ ... BG_Components = { ["front interior lightbar"] = { ["0"] = { ["front_viper"] = "code3" }, ["1"] = { ["front_interior"] = "code3" } }, }, ... }
The BG_Components
property table renders lights based on the player's bodygroup configuration for the vehicle. It is best-practice to use this in combination with the presets feature, as presets will adjust the bodygroups to anything specified in the preset, however the player can still change the bodygroups through non-Photon means afterwards. This property is very comprehensive for customization, however assigning bodygroup settings within the presets table can enable color and pattern changes based on the emergency lighting preset. More information on the benefits of using the presets table is listed below.
To utilize the BG_Components
property, the first tier of children in the table (["front interior lightbar"]
) represent the actual displayed name found in the bodygroup context menu. This is strictly for readability of the table. The name, however, must be an exact match of the bodygroup category name.
Within each tier, string indexes are used to reference the actual bodygroup number. Within each index you can assign the pattern to each component.
To list bodygroup names and indexes, type photon_debug_bg
in console to get a complete listing
Primary sequences are simply referenced as Sequences = { }
. Each sub table within the Sequences table will become an selectable option when the player alternates their light pattern. It should be noted that, by default, Photon will jump to the last defined light mode as the presumed "highest priority," when the user initiates the siren while the lights are off. So it is best practice to order the light modes, starting with the lowest priority at the top and highest priority at the bottom. Adding beyond three or four light modes can make for a poor user experience, however there is no limit on the number of light modes.
Traffic = { { Name = "LEFT", Components = {}, BG_Components = { ["rear interior lightbar"] = { ["0"] = { ["traffic"] = "left", ["traffic_rb"] = "flash" }, }, }, Disconnect = { 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 } }, }The
Traffic
works in a very similar fashion to primary sequences, however the lights defined in this section are only rendered when the user has the traffic-advisor function enabled. Additionally, the user will only be presented with the Traffic-advisor section on the HUD when sequences are defined, otherwise the feature will be hidden for the vehicle. The traffic advisory function can be treated as an auxiliary lighting system, and it is fully capable of rendering emergency lighting as well (however this is a discouraged approach).
Illumination refers to the ability for the player to toggle and adjust emitted light from the vehicle. In real applications this can mean scene lighting, takedown lights, alley lights, police lamps and anything else that should project light.
WARNING: if you are creating a car for a busy multiplayer server, be aware that this feature uses projected textures. Having several projected textures may cause substantial drops in FPS for players, therefore limiting the number of lamps used (per light mode) is recommended.