Security Camera (2.10+): Difference between revisions

From The DarkMod Wiki
Jump to navigationJump to search
Dragofer (talk | contribs)
mNo edit summary
Dragofer (talk | contribs)
No edit summary
 
(6 intermediate revisions by the same user not shown)
Line 6: Line 6:


* It can either sweep back and forth between two angles or remain stationary.
* It can either sweep back and forth between two angles or remain stationary.
* If the camera sees the player, it initially plays a short alert sound that is silent to nearby guards. If the player is still in view several seconds later, another alarm sounds. This alarm will play intermittently for a while, even if the player moves out of sight. This second alarm will alert nearby guards.
* If the camera sees the player, an AI on a hostile team or a body, it plays a short alert sound that is silent to nearby guards. If the enemy or body is still in view several seconds later, an alarm sounds. This alarm will repeat every few seconds for a while, even if the enemy moves out of sight.
* The camera is able to track the player, making it much harder to escape its view.
* The camera is able to track its enemy, making it much harder to escape its view.
* An optional spotlight that points forward, lighting the area in the direction the camera faces.  
* An optional spotlight that points forward, lighting the area in the direction the camera faces.
* The ability to toggle the camera power on/off by triggering it. Alternatively, the 3 features above can be toggled individually.
* The ability to toggle the camera power on/off by triggering it. Each of the above described subsystems can be toggled individually.
* If the camera has targets, these will be activated when the camera is fully alerted. This gives the map author the ability to play a more powerful alarm than the one given off by the camera. (Or to do a variety of other things.)
* If the camera has targets, these will be activated when the camera is fully alerted. This gives the map author the ability to play a more powerful alarm than the one given off by the camera (or to do a variety of other things.)
* Sending what it sees to a separate, func_static display screen. Alternatively, it can send what another entity (typically a target_null) sees.
* Sending what it sees to a separate, func_static display screen. Alternatively, it can send what another entity (typically a target_null) sees.


Line 20: Line 20:
Place the camera entity in your map, and orient it toward its starting direction. A rotating camera will sweep clockwise, halt a moment, then sweep back counter-clockwise.
Place the camera entity in your map, and orient it toward its starting direction. A rotating camera will sweep clockwise, halt a moment, then sweep back counter-clockwise.


Some cameras may be designed to use additional parts, i.e. a ceiling pivot entity with scripted gears. See the entity descriptions inside DR for more.
Some cameras may be designed to use additional parts, i.e. a ceiling pivot entity with scripted gears. See the prefabs or the entity descriptions for more info.




Line 28: Line 28:


* "rotate" - If "1" (default) the camera will rotate. If "0", the camera is stationary.
* "rotate" - If "1" (default) the camera will rotate. If "0", the camera is stationary.
* "sweepSpeed" - How many seconds it takes a rotating camera to complete a sweep in one direction.
* "sweepSpeed" - Horizontal rotation speed in degrees per second.
* "sweepAngle" - The angle of sweep. You can cause a camera to initially sweep in the counter-clockwise direction by setting this to a negative number.
* "sweepAngle" - The number of degrees the camera covers during its sweep. You can cause a camera to initially sweep in the counter-clockwise direction by setting this to a negative number.
* "sweepWait" - How long the pause is after a sweep completes and starting the return sweep. Default is 0.5 seconds.
* "sweepWait" - How long the pause is after the end of a sweep. Default is 0.5 seconds.
* "sweepWaitSoundOffset" - Start playing snd_end before the camera reaches the end of its sweep, by this amount of seconds.




===Detection Spawnargs===
===Detection Spawnargs===


These spawnargs govern how the security camera detects and reacts to the player: up to what distance, at what light intensity, how long the alarm lasts, whether to trigger anything and so on.
These spawnargs govern how the security camera detects and reacts to enemies: max detection distance, at what light intensity, how long the alarm lasts, whether to trigger anything and so on.


* "scanDist" - The distance limit for spotting the player.
* "scanDist" - The distance limit for spotting the enemy.
* "scanFov" - The camera's field of view.
* "scanFov" - The camera's field of view.
* "seePlayer" - Whether the camera will react to the player.
* "seePlayer" - Whether the camera will react to the player.
* "seeAI" - Whether the camera will react to AIs, and what their relationship to the camera's team has to be.
* "seeBodies" - Whether the camera will react to bodies.
* "seeAnimals" - Whether the camera will react to animals.
* "sight_threshold" - From 0.0 to 1.0, how lit up the lightgem has to be for the player to be detected.
* "sight_threshold" - From 0.0 to 1.0, how lit up the lightgem has to be for the player to be detected.
* "sightTime" - After seeing the player (partial alert), the camera will wait this amount of time. If it still sees the player, it will sound the alarm. This gives the player some time to hide.
* "sightTime" - After seeing the enemy (partial alert), the camera will wait this amount of time. If it still sees the enemy, it will sound the alarm. This gives the enemy some time to hide.
* "sightResume" - If the camera can't see the player anymore after a partial alert, pause for this amount of time. When this expires, the camera will resume sweeping.
* "sightResume" - If the camera can't see the enemy anymore after a partial alert, pause for this amount of time. When this expires, the camera will resume sweeping.
* "alarm_duration" - Minimum duration of the fully alert state. Will be extended by half if the player is still in view at the end or was recently seen.
* "alarm_duration" - Minimum duration of the fully alert state. Will be extended by half if the enemy is still in view at the end or was recently seen.
* "alarm_interval" - Amount of time inbetween each activation of the alarm sound, when fully alerted.
* "alarm_interval" - Amount of time inbetween each activation of the alarm sound, when fully alerted.
* "trigger_alarm_start" - Trigger targets when an alarm begins.
* "trigger_alarm_start" - Trigger targets when an alarm begins.
Line 51: Line 55:
===Follow Spawnargs===
===Follow Spawnargs===


The security camera can track the player if it catches sight of him. For as long as the security camera is partially or fully alerted, it will turn to wherever it can see the player. The models for the camera and mount should be able to support this without clipping into each other. A ceiling-mounted camera will generally have much more freedom to turn than a wall-mounted camera.
The security camera can track the enemy's movements. For as long as the security camera is partially or fully alerted, it will turn to the closest enemy it can see. The models for the camera and mount should be able to support this without clipping into each other. A ceiling-mounted camera will generally have much more freedom to turn than a wall-mounted camera.


* "follow" - Enable to let the camera track the player horizontally.
* "follow" - Enable to let the camera track the enemy horizontally.
* "follow_tolerance" - How far in degrees the player has to move before the camera readjusts its rotation, horizontally.
* "follow_tolerance" - How far in degrees the enemy has to move before the camera readjusts its rotation, horizontally.
* "follow_speed_mult" - Speed up horizontal movements by this multiplier when the camera is following the player.
* "follow_speed_mult" - Speed up horizontal movements by this multiplier when the camera is following the enemy.
* "follow_incline" - The camera will also track the player vertically.
* "follow_incline" - The camera will also track the enemy vertically.
* "follow_incline_tolerance" - How far in degrees the player has to move before the camera readjusts its rotation, vertically.
* "follow_incline_tolerance" - How far in degrees the enemy has to move before the camera readjusts its rotation, vertically.
* "follow_incline_speed" - Speed of vertical movements to track the player. Not affected by 'follow_speed_mult'.
* "follow_incline_speed" - Speed of vertical movements to track the enemy. Not affected by 'follow_speed_mult'.
* "follow_incline_max_up" - Limit how far the camera can turn upwards from its starting orientation.
* "follow_constrain_up" - Limit how far the camera can turn upwards from its starting orientation.
* "follow_incline_max_down" - Limit how far the camera can turn downwards from its starting orientation.
* "follow_constrain_down" - Limit how far the camera can turn downwards from its starting orientation.




===Spotlight Spawnargs===
===Spotlight Spawnargs===


If "spotLight" is set to 1, the security camera's code will spawn a spotlight and align it with its view. This dates back to the Doom3 days, so it follows different rules from the def_attach systems. If "useColors" is enabled, the spotlight's color will change depending on alert state. Otherwise it will look for a "_color" spawnarg on the camera.
If "spotLight" is set to 1, the security camera's code will spawn a spotlight and align it with its view. This dates back to the Doom 3 days, so it follows different rules from the def_attach systems. If "useColors" is enabled, the spotlight's color will change depending on alert state. Otherwise it will look for a "_color" spawnarg on the camera.


Alternatively you can specify an existing light with the spawnarg "spotlight_custom". Apart from "spotLight" and "useColors", all other spotlight-relevant spawnargs are ignored. If no valid entity of spawnclass idLight is found, it'll spawn a spotlight instead.
Alternatively you can specify an existing light with the spawnarg "spotlight_custom". Apart from "spotLight" and "useColors", all other spotlight-relevant spawnargs are ignored. If no valid entity of spawnclass idLight is found, it'll spawn a spotlight instead.
Line 73: Line 77:
* "spotlight_diameter" - Diameter of the spotlight's projection. If 0, will automatically be calculated to match spotlight_range and scanFov, for scanFov up to 90°.
* "spotlight_diameter" - Diameter of the spotlight's projection. If 0, will automatically be calculated to match spotlight_range and scanFov, for scanFov up to 90°.
* "spotlight_texture" - Texture used by the spotlight. You should use a texture that's designed for projected lights: one that uses a gradient as its falloff image. This ensures that light intensity gradually fades to black, rather than abruptly cutting to black.
* "spotlight_texture" - Texture used by the spotlight. You should use a texture that's designed for projected lights: one that uses a gradient as its falloff image. This ensures that light intensity gradually fades to black, rather than abruptly cutting to black.
* "spotlight_volumetric" - The spawned spotlight will be volumetric.




Line 79: Line 84:
* "useColors" - If "1" the camera will change the colour of its model and spotlight depending on its alert state.
* "useColors" - If "1" the camera will change the colour of its model and spotlight depending on its alert state.
* "color_sweeping" - Color when the camera is sweeping = unalerted. Default green.
* "color_sweeping" - Color when the camera is sweeping = unalerted. Default green.
* "color_sighted" - Color when the camera has noticed the player = partially alerted. Default yellow.
* "color_sighted" - Color when the camera has noticed an enemy = partially alerted. Default yellow.
* "color_alerted" - Color when the camera has sounded the alarm = fully alerted. Default red.
* "color_alerted" - Color when the camera has sounded the alarm = fully alerted. Default red.
* "_color" - If "useColors" is disabled, the model and spotlight will always have this color.
* "_color" - If "useColors" is disabled, the model and spotlight will always have this color.
Line 85: Line 90:
As an alternative or complement to color spawnargs, you may make use of shaderParm7 in materials used by the security camera. shaderParm7 represents the alert state of the camera:
As an alternative or complement to color spawnargs, you may make use of shaderParm7 in materials used by the security camera. shaderParm7 represents the alert state of the camera:
* 0 = unalerted
* 0 = unalerted
* 1 = was partially alerted for "sightTime" seconds but player has disappeared, now waiting "sightResume" seconds before resuming sweeping.
* 1 = was partially alerted for "sightTime" seconds but the enemy has disappeared, now waiting "sightResume" seconds before resuming sweeping.
* 2 = partially alerted
* 2 = partially alerted
* 3 = fully alerted
* 3 = fully alerted
Line 92: Line 97:
===Damage Spawnargs===
===Damage Spawnargs===


* "health" - Cameras can be 'killed', including by swords, broadhead arrows and fire arrows, but not blackjacks. You may protect (parts of) the camera from damage with nodrawsolid brushes, but note that fire arrows only do 30 splash damage, equivalent to 1 broadhead hit. Setting to 0 will make the camera invincible.
* "health" - amount of damage the camera can take before being destroyed. Setting to 0 will make the camera invincible. Setting to 0 will make the camera invincible. Default base damage per hit: sword - 42; broadhead - 35; fire arrow direct hit - 400.
* "damage_blackjack" - how much damage the security camera takes from blackjack hits, default: 0.
* "damage_mult_" - a series of spawnargs to multiply how much damage the security camera takes from various damage sources. You can name specific weapon classnames or damageDefs in the spawnarg, i.e. "damage_mult_atdm:weapon_shortsword" "0.5".
* "damage_splash_falloff" - how quickly splash damage from fire arrows exponentially decreases with distance, default: 3.
* "damage_flinderize" - if a security camera is destroyed and the destroying hit (or post-destruction hit) is greater than this value, the security camera explodes into pieces. Default: 90.
* "def_flinder1" - the classname of the flinder pieces generated when a camera is flinderized by a heavy hit. Use "def_flinder2" etc. to generate more flinders.
* "flinder_offset1" - specifies the spawn point of the respective flinder piece relative to the camera's origin. Takes the camera's current rotation into account.
* "broken" - the security camera switches to this model when destroyed
* "broken_flinderized" - Optional. Specify the model of the security camera when destroyed + flinderized.
* "skin_broken" - the security camera switches to this skin when destroyed
* "skin_flinderized" - Optional. Specify the skin of the security camera when destroyed + flinderized.
* "hideModelOnBreak" - the security camera will be hidden when destroyed, default: 0.
* "notice_destroyed" - Whether AIs will become alerted if they find this security camera destroyed.
* "fx_damage" - Fx to play whenever the camera is damaged while power is on.
* "fx_damage" - Fx to play whenever the camera is damaged while power is on.
* "fx_damage_nopower" - Fx to play whenever the camera is damaged while power is off.
* "fx_damage_nopower" - Fx to play whenever the camera is damaged while power is off.
Line 103: Line 120:
===Sound Spawnargs===
===Sound Spawnargs===


* "snd_sight" - Sound emitted when the camera notices the player.
* "snd_sight" - Sound emitted when the camera notices an enemy.
* "snd_moving" - Sound emitted when the camera is rotating.
* "snd_moving" - Sound emitted when the camera is rotating.
* "snd_stationary" - Sound emitted by a stationary type of camera.
* "snd_stationary" - Sound emitted by a stationary type of camera.
Line 111: Line 128:
* "snd_death_nopower" - Sound emitted when the camera is destroyed while power is off.
* "snd_death_nopower" - Sound emitted when the camera is destroyed while power is off.
* "snd_sparks" - Sound emitted when the camera emits sparks after it was destroyed.
* "snd_sparks" - Sound emitted when the camera emits sparks after it was destroyed.
* "sprS_alert" - How far snd_alert propagates to AIs, at default this is a few rooms. Higher settings than mild can cause large framedrops.
* "sprS_alert" - How far snd_alert propagates to AIs, at default this is a few rooms. Higher settings than mild can cause large framedrops due to mass AI alerts.




Line 121: Line 138:
* "sparks_particle" - Particle that is spawned.
* "sparks_particle" - Particle that is spawned.
* "sparks_delay" - Time taken for the particle emitter to spawn initially.
* "sparks_delay" - Time taken for the particle emitter to spawn initially.
* "sparks_power_dependent" - Only show the particle if power to the (dead) camera is on.
* "sparks_power_dependent" - Only show the particle if power to the destroyed camera is on.
* "sparks_periodic" - Set to '0' if you use a looping particle and sound. For single-cycle particles and sounds, set to '1' so that they are regularly triggered.
* "sparks_interval" - For non-looping particles, minimum time between triggers.
* "sparks_interval" - For non-looping particles, minimum time between triggers.
* "sparks_interval_rand" - For non-looping particles, additional random factor added to the time between triggers.
* "sparks_interval_rand" - For non-looping particles, additional random factor added to the time between triggers.
Line 132: Line 148:


* "broken" - Use this model when the camera is destroyed.
* "broken" - Use this model when the camera is destroyed.
* "clipmodel" - Assign a simplified collision mesh to this camera. Should be under 32 tris, have only convex angles and use textures/common/collision.
* "viewOffset" - A vector that defines the offset of the camera's 'eye' from the camera's origin.
* "viewOffset" - A vector that defines the offset of the camera's 'eye' from the camera's origin.
* "lightOffset" - A vector that defines the spotlight offset from the camera's origin.
* "lightOffset" - A vector that defines the spotlight offset from the camera's origin.
Line 145: Line 160:
===Misc Spawnargs===
===Misc Spawnargs===


* "start_on" - Whether the camera starts powered on or off.
* "start_off" - Whether the camera starts powered on or off.
* "cameraTarget" - Use the view from this entity instead of from self if sending a view to the display screen. See section ''The Display Screen'' for more.
* "cameraTarget" - Use the view from this entity instead of from self if sending a view to the display screen. See section ''The Display Screen'' for more.
* "gearSpeed" - This spawnarg is set on the ceiling pivot of the 2nd security camera. It controls how fast the gears turn when the security camera turns.
* "gearSpeed" - This spawnarg is set on the ceiling pivot of the 2nd type of security camera. It controls how fast the gears turn when the security camera turns.
* "legacy" - This marks an old version of the security camera, for backwards compatibility with older missions.


The security camera uses spawnargs to place its 'eye' and spotlight in front of the model to ensure the view and spotlight aren't blocked by the model. If you use a different model, you might need to change these.
The security camera uses spawnargs to place its 'eye' and spotlight in front of the model to ensure the view and spotlight aren't blocked by the model. If you use a different model, you might need to change these.
Line 156: Line 172:
==Damaging the Camera==
==Damaging the Camera==


By default the security camera is vulnerable to sword attacks, broadhead arrows and fire arrows. The player will receive feedback that a hit was successful in the form of spark effects, specified in spawnargs beginning with fx_. An .fx definiton is basically an instruction to emit a sequence of particles and sounds.
===Damage sources===


Setting "health" to 0 will make the camera totally invicible. Alternatively, you can make the camera immune to everything but fire arrow splash damage by binding a tight-fitting nodrawsolid_metal brush. Be sure to consider that cameras use a separate clipmodel with a different shape. Also note that fire arrows only do 30 splash damage throughout a large radius, so you may want to lower the camera's health.
By default the security camera is vulnerable only to fire arrows (direct & splash damage). The "damage_" and "damage_mult_" spawnargs allow you to to specify how much damage security cameras take from each weapon, but be sure to communicate the camera's vulnerabilities to the player. You can create your own "damage_mult_" spawnargs by adding the name of a specific weapon classname or damageDef, i.e. "damage_mult_atdm:weapon_shortsword" "0.5". Unfortunately it does not appear to be possible to make water damage the camera, since TDM will crash upon load when a water response is applied to the camera.  


A similar approach is to bind a brush that leaves parts of the camera exposed, i.e. the lens or face. Note that it will weaken fire arrows considerably if they hit from the wrong angle. A direct hit does up to 400 damage, while the splash only does 30 damage.
Setting "health" to 0 will make the camera totally invicible. Alternatively, you can make the camera immune to everything but fire arrow splash damage by binding a tight-fitting nodrawsolid_metal brush. A similar approach is to bind a brush that leaves parts of the camera exposed, i.e. the lens or face. Note that it will weaken fire arrows considerably if they hit from the wrong angle. A direct hit does up to 400 damage, while the splash does a distance-dependent amount of damage below 100. Note that collision detection is done using the camera's clipmodel, which has a different shape than the visual model.


Unfortunately it does not appear to be possible to make water damage the camera, since TDM will crash upon load when a water response is applied to the camera.
The player will receive feedback that the camera took damage in the form of spark effects, specified in spawnargs beginning with fx_. An .fx definiton is basically an instruction to emit a sequence of particles and sounds.


In any case, be sure to communicate the camera's vulnerabilities to the player.
===Destroying the Camera===
 
Security cameras can not only be destroyed, but also be flinderized (burst apart into pieces) which occurs when the security camera takes a hit whose damage is higher than the value of the "damage_flinderize" spawnarg. The "broken" and "skin_broken" spawnargs let you set the model and skin when the camera is destroyed, while the optional "broken_flinderized" and "skin_flinderized" let you set the model and skin when the camera has been flinderized. The "def_flinder" and "flinder_offset" spawnargs allow you to specify the flinder pieces and their spawn point relative to the camera's origin.




Line 174: Line 192:
* getSecurityCameraState() - Returns the security camera's state. 1 = unalerted, 2 = partially alerted, 3 = fully alerted, 4 = inactive (power off), 5 = destroyed, 0 = not a security camera.
* getSecurityCameraState() - Returns the security camera's state. 1 = unalerted, 2 = partially alerted, 3 = fully alerted, 4 = inactive (power off), 5 = destroyed, 0 = not a security camera.
* getShaderParm(7) - Returns the current value of shaderParm7 on the camera model. 0 = unalerted, 1 = about to resume sweep after a partial alert, 2 = partially alerted, 3 = fully alerted.
* getShaderParm(7) - Returns the current value of shaderParm7 on the camera model. 0 = unalerted, 1 = about to resume sweep after a partial alert, 2 = partially alerted, 3 = fully alerted.
* activate() and trigger() - These activate or deactivate the camera fully, representing switching power on or off.
* On() and Off() - Switch the camera's power on or off (note the capitalisation).
* getHealth() and setHealth(float newHealth) - As per the name. Setting health to 0 or lower will destroy the security camera, which is irreversible.
* activate() and trigger() - Toggle the camera's power.
* getHealth() and setHealth(float newHealth) - As per the name. Setting health to 0 or lower will destroy the security camera, which is irreversible. setHealth() will make an invincible camera vulnerable.
* getEnemy() - Returns the entity that most recently caused or refreshed the security camera's suspicious or alert state.
* canSee() - Tests whether the security camera is able to see a specific entity. Currently only player1 is supported.
* setSightThreshold() - This changes how lit up the player's lightgem has to be for the security camera to see him, from 0.0 to 1.0.
* setSightThreshold() - This changes how lit up the player's lightgem has to be for the security camera to see him, from 0.0 to 1.0.
* state_light(boolean set) - Switch the camera's spotlight on/off, if the camera has one.
* state_sweep(boolean set) - Switch the camera's sweep on/off. This will also affect enemy tracking.
* state_see_player(boolean set) - Toggle whether the camera is able to detect the player. An alternative is just to set "seePlayer" to "1" or "0", since the code monitors this spawnarg.
* toggle_light() - Toggle the spotlight on/off, if the camera has one.
* toggle_light() - Toggle the spotlight on/off, if the camera has one.
* toggle_sweep() - Toggle the camera's sweep on/off. This will also affect following.
* toggle_sweep() - Toggle the camera's sweep on/off. This will also affect enemy tracking.
* toggle_see_player() - Toggle whether the camera is able to detect the player. An alternative is just to set "seePlayer" to "1" or "0", since the code monitors this spawnarg.
* toggle_see_player() - Toggle whether the camera is able to detect the player. An alternative is just to set "seePlayer" to "1" or "0", since the code monitors this spawnarg.


Line 226: Line 250:
==Examining a Test Map==
==Examining a Test Map==


You can obtain a test map with sample cameras in it here: [http://ftp.thedarkmod.com/tutorials/RemoteCamera/camerawiki2.pk4 camerawiki2.pk4]. Similar setups can be found as prefabs in AI/Machines.
You can obtain a test map with sample cameras in it here: [https://ftp.thedarkmod.com/tutorials/RemoteCamera/camerawiki2.pk4 camerawiki2.pk4]. Similar setups can be found as prefabs in AI/Machines.


Open the map ''camerawiki.map'' in Dark Radiant. In this map, we have examples of the different cameras.
Open the map ''camerawiki.map'' in Dark Radiant. In this map, we have examples of the different cameras.

Latest revision as of 14:05, 16 July 2022

Security Camera

This article documents the security camera as it will be from 2.10 onwards. See Security Camera if you're currently working with TDM 2.09 or older versions.

The security camera provides the following features:

  • It can either sweep back and forth between two angles or remain stationary.
  • If the camera sees the player, an AI on a hostile team or a body, it plays a short alert sound that is silent to nearby guards. If the enemy or body is still in view several seconds later, an alarm sounds. This alarm will repeat every few seconds for a while, even if the enemy moves out of sight.
  • The camera is able to track its enemy, making it much harder to escape its view.
  • An optional spotlight that points forward, lighting the area in the direction the camera faces.
  • The ability to toggle the camera power on/off by triggering it. Each of the above described subsystems can be toggled individually.
  • If the camera has targets, these will be activated when the camera is fully alerted. This gives the map author the ability to play a more powerful alarm than the one given off by the camera (or to do a variety of other things.)
  • Sending what it sees to a separate, func_static display screen. Alternatively, it can send what another entity (typically a target_null) sees.


The Security Camera: Entities and Prefabs

Security camera entities can be found in AI/Machines/Security Camera and inherit from func_securitycamera. Prefabs can be found in AI/Machines.

Place the camera entity in your map, and orient it toward its starting direction. A rotating camera will sweep clockwise, halt a moment, then sweep back counter-clockwise.

Some cameras may be designed to use additional parts, i.e. a ceiling pivot entity with scripted gears. See the prefabs or the entity descriptions for more info.


Spawnargs

Movement Spawnargs

  • "rotate" - If "1" (default) the camera will rotate. If "0", the camera is stationary.
  • "sweepSpeed" - Horizontal rotation speed in degrees per second.
  • "sweepAngle" - The number of degrees the camera covers during its sweep. You can cause a camera to initially sweep in the counter-clockwise direction by setting this to a negative number.
  • "sweepWait" - How long the pause is after the end of a sweep. Default is 0.5 seconds.
  • "sweepWaitSoundOffset" - Start playing snd_end before the camera reaches the end of its sweep, by this amount of seconds.


Detection Spawnargs

These spawnargs govern how the security camera detects and reacts to enemies: max detection distance, at what light intensity, how long the alarm lasts, whether to trigger anything and so on.

  • "scanDist" - The distance limit for spotting the enemy.
  • "scanFov" - The camera's field of view.
  • "seePlayer" - Whether the camera will react to the player.
  • "seeAI" - Whether the camera will react to AIs, and what their relationship to the camera's team has to be.
  • "seeBodies" - Whether the camera will react to bodies.
  • "seeAnimals" - Whether the camera will react to animals.
  • "sight_threshold" - From 0.0 to 1.0, how lit up the lightgem has to be for the player to be detected.
  • "sightTime" - After seeing the enemy (partial alert), the camera will wait this amount of time. If it still sees the enemy, it will sound the alarm. This gives the enemy some time to hide.
  • "sightResume" - If the camera can't see the enemy anymore after a partial alert, pause for this amount of time. When this expires, the camera will resume sweeping.
  • "alarm_duration" - Minimum duration of the fully alert state. Will be extended by half if the enemy is still in view at the end or was recently seen.
  • "alarm_interval" - Amount of time inbetween each activation of the alarm sound, when fully alerted.
  • "trigger_alarm_start" - Trigger targets when an alarm begins.
  • "trigger_alarm_end" - Trigger targets when an alarm ends.


Follow Spawnargs

The security camera can track the enemy's movements. For as long as the security camera is partially or fully alerted, it will turn to the closest enemy it can see. The models for the camera and mount should be able to support this without clipping into each other. A ceiling-mounted camera will generally have much more freedom to turn than a wall-mounted camera.

  • "follow" - Enable to let the camera track the enemy horizontally.
  • "follow_tolerance" - How far in degrees the enemy has to move before the camera readjusts its rotation, horizontally.
  • "follow_speed_mult" - Speed up horizontal movements by this multiplier when the camera is following the enemy.
  • "follow_incline" - The camera will also track the enemy vertically.
  • "follow_incline_tolerance" - How far in degrees the enemy has to move before the camera readjusts its rotation, vertically.
  • "follow_incline_speed" - Speed of vertical movements to track the enemy. Not affected by 'follow_speed_mult'.
  • "follow_constrain_up" - Limit how far the camera can turn upwards from its starting orientation.
  • "follow_constrain_down" - Limit how far the camera can turn downwards from its starting orientation.


Spotlight Spawnargs

If "spotLight" is set to 1, the security camera's code will spawn a spotlight and align it with its view. This dates back to the Doom 3 days, so it follows different rules from the def_attach systems. If "useColors" is enabled, the spotlight's color will change depending on alert state. Otherwise it will look for a "_color" spawnarg on the camera.

Alternatively you can specify an existing light with the spawnarg "spotlight_custom". Apart from "spotLight" and "useColors", all other spotlight-relevant spawnargs are ignored. If no valid entity of spawnclass idLight is found, it'll spawn a spotlight instead.

  • "spotLight" - If "1" the camera will use a spotlight.
  • "spotlight_range" - Reach of the spotlight.
  • "spotlight_diameter" - Diameter of the spotlight's projection. If 0, will automatically be calculated to match spotlight_range and scanFov, for scanFov up to 90°.
  • "spotlight_texture" - Texture used by the spotlight. You should use a texture that's designed for projected lights: one that uses a gradient as its falloff image. This ensures that light intensity gradually fades to black, rather than abruptly cutting to black.
  • "spotlight_volumetric" - The spawned spotlight will be volumetric.


Color Spawnargs

  • "useColors" - If "1" the camera will change the colour of its model and spotlight depending on its alert state.
  • "color_sweeping" - Color when the camera is sweeping = unalerted. Default green.
  • "color_sighted" - Color when the camera has noticed an enemy = partially alerted. Default yellow.
  • "color_alerted" - Color when the camera has sounded the alarm = fully alerted. Default red.
  • "_color" - If "useColors" is disabled, the model and spotlight will always have this color.

As an alternative or complement to color spawnargs, you may make use of shaderParm7 in materials used by the security camera. shaderParm7 represents the alert state of the camera:

  • 0 = unalerted
  • 1 = was partially alerted for "sightTime" seconds but the enemy has disappeared, now waiting "sightResume" seconds before resuming sweeping.
  • 2 = partially alerted
  • 3 = fully alerted


Damage Spawnargs

  • "health" - amount of damage the camera can take before being destroyed. Setting to 0 will make the camera invincible. Setting to 0 will make the camera invincible. Default base damage per hit: sword - 42; broadhead - 35; fire arrow direct hit - 400.
  • "damage_blackjack" - how much damage the security camera takes from blackjack hits, default: 0.
  • "damage_mult_" - a series of spawnargs to multiply how much damage the security camera takes from various damage sources. You can name specific weapon classnames or damageDefs in the spawnarg, i.e. "damage_mult_atdm:weapon_shortsword" "0.5".
  • "damage_splash_falloff" - how quickly splash damage from fire arrows exponentially decreases with distance, default: 3.
  • "damage_flinderize" - if a security camera is destroyed and the destroying hit (or post-destruction hit) is greater than this value, the security camera explodes into pieces. Default: 90.
  • "def_flinder1" - the classname of the flinder pieces generated when a camera is flinderized by a heavy hit. Use "def_flinder2" etc. to generate more flinders.
  • "flinder_offset1" - specifies the spawn point of the respective flinder piece relative to the camera's origin. Takes the camera's current rotation into account.
  • "broken" - the security camera switches to this model when destroyed
  • "broken_flinderized" - Optional. Specify the model of the security camera when destroyed + flinderized.
  • "skin_broken" - the security camera switches to this skin when destroyed
  • "skin_flinderized" - Optional. Specify the skin of the security camera when destroyed + flinderized.
  • "hideModelOnBreak" - the security camera will be hidden when destroyed, default: 0.
  • "notice_destroyed" - Whether AIs will become alerted if they find this security camera destroyed.
  • "fx_damage" - Fx to play whenever the camera is damaged while power is on.
  • "fx_damage_nopower" - Fx to play whenever the camera is damaged while power is off.
  • "fx_destroyed" - Fx to play whenever the camera is destroyed while power is on.
  • "fx_destroyed_nopower" - Fx to play whenever the camera is destroyed while power is off.
  • "break_up_script" - This script is called when the camera is destroyed.
  • "break_up_target" - This entity is triggered if the camera is destroyed.


Sound Spawnargs

  • "snd_sight" - Sound emitted when the camera notices an enemy.
  • "snd_moving" - Sound emitted when the camera is rotating.
  • "snd_stationary" - Sound emitted by a stationary type of camera.
  • "snd_alert" - Alarm sound emitted when fully alerted.
  • "snd_end" - Sound emitted when the camera is about to reach the end point of a sweep.
  • "snd_death" - Sound emitted when the camera is destroyed.
  • "snd_death_nopower" - Sound emitted when the camera is destroyed while power is off.
  • "snd_sparks" - Sound emitted when the camera emits sparks after it was destroyed.
  • "sprS_alert" - How far snd_alert propagates to AIs, at default this is a few rooms. Higher settings than mild can cause large framedrops due to mass AI alerts.


Sparks Spawnargs

The security camera spawns a particle emitter when it's destroyed. By default it uses a single-cycle spark particle which is periodically triggered at random intervals. When power to the camera is switched off, the sparks stop appearing.

  • "sparks" - Whether to spawn a particle emitter at all.
  • "sparks_particle" - Particle that is spawned.
  • "sparks_delay" - Time taken for the particle emitter to spawn initially.
  • "sparks_power_dependent" - Only show the particle if power to the destroyed camera is on.
  • "sparks_interval" - For non-looping particles, minimum time between triggers.
  • "sparks_interval_rand" - For non-looping particles, additional random factor added to the time between triggers.


Model Spawnargs

These spawnargs are important if you change the camera model:

  • "broken" - Use this model when the camera is destroyed.
  • "viewOffset" - A vector that defines the offset of the camera's 'eye' from the camera's origin.
  • "lightOffset" - A vector that defines the spotlight offset from the camera's origin.
  • "flipAxis" - This and the next spawnarg can be used to turn a model such that it faces forwards. Not needed if the model was created forward-facing.
  • "modelAxis"
  • "skin" - This is the "on" skin. It may contain materials that make use of the colored keyword or shaderParm7, to change depending on alert state.
  • "skin_on_spotlight_off" - This is the "on" skin, but with the spotlight toggled off. This is useful if your model contains inbuilt lightrays that should represent the spotlight.
  • "skin_off" - This is the "off" skin. It should not contain materials with the colored keyword or shaderParm7.
  • "skin_broken" - When the camera is destroyed it will switch to this skin.


Misc Spawnargs

  • "start_off" - Whether the camera starts powered on or off.
  • "cameraTarget" - Use the view from this entity instead of from self if sending a view to the display screen. See section The Display Screen for more.
  • "gearSpeed" - This spawnarg is set on the ceiling pivot of the 2nd type of security camera. It controls how fast the gears turn when the security camera turns.
  • "legacy" - This marks an old version of the security camera, for backwards compatibility with older missions.

The security camera uses spawnargs to place its 'eye' and spotlight in front of the model to ensure the view and spotlight aren't blocked by the model. If you use a different model, you might need to change these.

  • "lightOffset"
  • "viewOffset"


Damaging the Camera

Damage sources

By default the security camera is vulnerable only to fire arrows (direct & splash damage). The "damage_" and "damage_mult_" spawnargs allow you to to specify how much damage security cameras take from each weapon, but be sure to communicate the camera's vulnerabilities to the player. You can create your own "damage_mult_" spawnargs by adding the name of a specific weapon classname or damageDef, i.e. "damage_mult_atdm:weapon_shortsword" "0.5". Unfortunately it does not appear to be possible to make water damage the camera, since TDM will crash upon load when a water response is applied to the camera.

Setting "health" to 0 will make the camera totally invicible. Alternatively, you can make the camera immune to everything but fire arrow splash damage by binding a tight-fitting nodrawsolid_metal brush. A similar approach is to bind a brush that leaves parts of the camera exposed, i.e. the lens or face. Note that it will weaken fire arrows considerably if they hit from the wrong angle. A direct hit does up to 400 damage, while the splash does a distance-dependent amount of damage below 100. Note that collision detection is done using the camera's clipmodel, which has a different shape than the visual model.

The player will receive feedback that the camera took damage in the form of spark effects, specified in spawnargs beginning with fx_. An .fx definiton is basically an instruction to emit a sequence of particles and sounds.

Destroying the Camera

Security cameras can not only be destroyed, but also be flinderized (burst apart into pieces) which occurs when the security camera takes a hit whose damage is higher than the value of the "damage_flinderize" spawnarg. The "broken" and "skin_broken" spawnargs let you set the model and skin when the camera is destroyed, while the optional "broken_flinderized" and "skin_flinderized" let you set the model and skin when the camera has been flinderized. The "def_flinder" and "flinder_offset" spawnargs allow you to specify the flinder pieces and their spawn point relative to the camera's origin.


Scripting

Script Events

The security camera supports the following script events:

  • getSecurityCameraState() - Returns the security camera's state. 1 = unalerted, 2 = partially alerted, 3 = fully alerted, 4 = inactive (power off), 5 = destroyed, 0 = not a security camera.
  • getShaderParm(7) - Returns the current value of shaderParm7 on the camera model. 0 = unalerted, 1 = about to resume sweep after a partial alert, 2 = partially alerted, 3 = fully alerted.
  • On() and Off() - Switch the camera's power on or off (note the capitalisation).
  • activate() and trigger() - Toggle the camera's power.
  • getHealth() and setHealth(float newHealth) - As per the name. Setting health to 0 or lower will destroy the security camera, which is irreversible. setHealth() will make an invincible camera vulnerable.
  • getEnemy() - Returns the entity that most recently caused or refreshed the security camera's suspicious or alert state.
  • canSee() - Tests whether the security camera is able to see a specific entity. Currently only player1 is supported.
  • setSightThreshold() - This changes how lit up the player's lightgem has to be for the security camera to see him, from 0.0 to 1.0.
  • state_light(boolean set) - Switch the camera's spotlight on/off, if the camera has one.
  • state_sweep(boolean set) - Switch the camera's sweep on/off. This will also affect enemy tracking.
  • state_see_player(boolean set) - Toggle whether the camera is able to detect the player. An alternative is just to set "seePlayer" to "1" or "0", since the code monitors this spawnarg.
  • toggle_light() - Toggle the spotlight on/off, if the camera has one.
  • toggle_sweep() - Toggle the camera's sweep on/off. This will also affect enemy tracking.
  • toggle_see_player() - Toggle whether the camera is able to detect the player. An alternative is just to set "seePlayer" to "1" or "0", since the code monitors this spawnarg.


Object Functions

The security camera's scriptobject contains the following object functions:

  • toggleSCSpotlight() - calls toggle_light() on the camera if it has a spotlight (spawnarg "spotLight" = "1")
  • toggleSCSweep() - calls toggle_sweep() on the camera
  • toggleSCPlayer() - calls toggle_see_player() on the camera


As you can see, these object functions simply call the toggle script events on the camera they belong to. This allows you to call the script events from i.e. buttons without scripting. To set this up:

  1. create an atdm:target_callobjectfunction entity
  2. give it the spawnarg "call" with the name of the desired object function, i.e. "toggleSCSpotlight"
  3. let it target the security camera
  4. when desired, trigger this entity (from a script, from a button etc.).


Scriptobjects

The security camera's scriptobject only consists of the 3 object functions mentioned above. Beyond some added utility, this scriptobject has no importance for the security camera and you can easily give it your own scriptobject instead.


Upon Destruction

You may call a script when the camera is destroyed, as per the spawnarg "break_up_script". This script should be able to receive the name of the destroyed security camera as input, i.e.:

void camera_destroyed ( entity camera )

An alternative is to use the spawnarg "break_up_target" to name an entity that calls the script when triggered, but this will not pass the name of the destroyed security camera unless you use an atdm:target_callscriptfunction entity with the spawnarg "forEach" "1".


Sending the camera's view to a Display Screen

You can create a display screen that shows that the camera sees: all that's needed is a func_static patch that uses a texture like textures/common/camera/camera1. It's recommended to put another patch behind it, since this func_static will get hidden if it's switched off. The screen then needs to be given a spawnarg "cameraTarget" that names either a security camera or a different entity, typically a target_null. The screen will display what that entity sees.

To change the screen's field of view, apply the spawnargs "cameraFovX" and "cameraFovY" to the entity sending the view. Otherwise it will default to "scanFov" for security cameras or 120 for other entities.

The screen is hidden or shown automatically if the screen is displaying a security camera's view. The screen can also be switched on/off manually by triggering it, but this requires the screen to start with the spawnarg "hide" "0" or "hide" "1".


Multiple Display Screens / Reflective Water / Skybox

If you plan to have multiple security cameras sending to multiple display screens in your mission, or if the camera display will appear in the same player POV as the sky or reflective water surfaces, you'll need to use unique camera materials for each screen. You can find 9 additional camera materials in the textures/common/camera/ folder. If you should need even more, you can simply clone one of the materials and change the name after the map keyword.


Examining a Test Map

You can obtain a test map with sample cameras in it here: camerawiki2.pk4. Similar setups can be found as prefabs in AI/Machines.

Open the map camerawiki.map in Dark Radiant. In this map, we have examples of the different cameras.

cam1

A rotating camera that sweeps back and forth

This camera (cam1) starts its rotation at 135 degrees (assuming +X is 0 degrees), and sweeps clockwise until it reaches 45 degrees. It pauses for a moment, then return-sweeps back to 135 degrees. It has a spotlight.

The display for cam1 is on the wall behind it. (Don't worry about the material being displayed backward in the screenshot.)

The display patch uses the material camera1 (provided in the camerawiki/materials/tdm_camera.mtr file).

The four buttons below the display do the following (from left to right):

  • Toggle Power - targets cam1 directly. When power is off, the display screen is hidden. You can simulate an "off" screen by making sure there's a black material behind the display. You could also place a glass material behind the display.
  • Toggle Spotlight - calls the toggleSCSpotlight() object function in the camera's scriptobject, turning the spotlight on/off
  • Toggle Player Sighting - calls the toggleSCPlayer() object function in the camera's scriptobject, turning Player detection on/off
  • Toggle Sweep - calls the toggleSCSweep() object function in the camera's scriptobject, turning camera sweep on/off
cam1's display

A stationary camera that doesn't move

cam2 and its display

This camera (cam2) is stationary, w/o a spotlight.

Its display, to its left, uses the material camera2.

The two buttons below the display do the following (from left to right):

  • Toggle Power - targets cam2 directly. When power is off, the display screen is hidden.
  • Toggle Player Sighting - calls the toggleSCPlayer() object function in the camera's scriptobject, turning player detection on/off


A screen showing the view from another entity (a target_null)

a small screen showing what a target_null is seeing

This is simply a screen referencing a target_null as its cameraTarget. The target_null is in a separate room pointed at a guard.

If you look in the room where the guard is standing, you'll see that the target_null has the spawnargs cameraFovX and cameraFovY. These were set because the default field of view for a view from a non-camera entity is 120 by 120, which looks quite zoomed out. For a small screen like this one, 60 by 60 is much better.

Also notice that the screen itself has the spawnarg hide 0. This makes it respond to triggers by hiding or showing itself, allowing you to switch it on or off at the push of a button (see below).

The button below the display does the following:

  • Toggle Power - targets the screen directly to show or hide it. This only works because the screen has a hide spawnarg.