Prop interactions: Difference between revisions

From Valve Developer Community
Jump to navigation Jump to search
No edit summary
Line 1: Line 1:
{{lang|Prop interactions|title=Prop Interactions}}
{{lang|Prop interactions|title=Prop Interactions}}
[[Prop interactions]], also known as '''propdata interactions''', are a group of independent [[KeyValues]] blocks that control how props handle interaction from outside forces, like being launched by the gravity gun, and how they should employ fire, like igniting after taking enough damage. They are technically part of {{ent|prop_data}}, but they are usually treated separately and embedded in a model with the {{ent|$keyvalues}} QC command. Most are defined in <code>props_shared.h</code> and <code>props_shared.cpp</code>.
[[Prop interactions]], also known as '''propdata interactions''', are a group of independent [[KeyValues]] blocks that control how props handle interaction from outside forces, like being launched by the gravity gun, and how they should employ fire, like igniting after taking enough damage. They are technically part of {{ent|prop_data}}, but they are usually treated separately and embedded in a model with the {{ent|$keyvalues}} QC command. Most are defined in {{mono|props_shared.h}} and {{mono|props_shared.cpp}}.


{{warning|Having more than one key of the same name (e.g. "'''onfirstimpact''' break" and "'''onfirstimpact''' paintsplat") in the same block may cause some or all involved keyvalues to stop working.}}
{{warning|Having more than one key of the same name (e.g. "'''onfirstimpact''' break" and "'''onfirstimpact''' paintsplat") in the same block may cause some or all involved keyvalues to stop working.}}
Line 24: Line 24:
  }
  }


Putting them under <code>prop_data</code> is also possible:
Putting them under {{mono|prop_data}} is also possible:
  [[$keyvalues]]
  [[$keyvalues]]
  {
  {
Line 61: Line 61:


== Physgun Interactions ==
== Physgun Interactions ==
The <code>physgun_interactions</code> block affects how a prop or ragdoll is handled by and responds to the [[weapon_physcannon|Gravity Gun]]. Despite the name, some interactions, like <code>explode_fire</code>, can be triggered by forces not related to the gravity gun.
The {{mono|physgun_interactions}} block affects how a prop or ragdoll is handled by and responds to the [[weapon_physcannon|Gravity Gun]]. Despite the name, some interactions, like {{mono|explode_fire}}, can be triggered by forces not related to the gravity gun.


===Options===
===Options===
;<code>preferred_carryangles <[[angles]]></code>
;{{mono|preferred_carryangles <[[angles]]>}}
:Sets the angles, relative to the player's orientation, at which the prop will be held when carried.  
:Sets the angles, relative to the player's orientation, at which the prop will be held when carried.  
:This is used with the sawblades and propellers in [[Ravenholm]]. {{note|{{ent|npc_turret_floor}} is held upright automatically and the model does not need to use this keyvalue.}}
:This is used with the sawblades and propellers in [[Ravenholm]]. {{note|{{ent|npc_turret_floor}} is held upright automatically and the model does not need to use this keyvalue.}}
;<code>carry_distance_offset <[[float]]></code>
;{{mono|carry_distance_offset <[[float]]>}}
:Adds or subtracts to the prop's distance from whoever is carrying it. {{todo|Confirm and clarify}}
:Adds or subtracts to the prop's distance from whoever is carrying it. {{todo|Confirm and clarify}}
; <code>onworldimpact <choices></code>
; {{mono|onworldimpact <choices>}}
: ''When we hit the [[world]] after being thrown by the gravity gun.''
: ''When we hit the [[world]] after being thrown by the gravity gun.''
:; <code>stick</code>
:; {{mono|stick}}
:: Sticks to what we hit if we're traveling fast enough. {{note|Using the gravity gun to pick up a sticking prop automatically turns the prop into debris.}}
:: Sticks to what we hit if we're traveling fast enough. {{note|Using the gravity gun to pick up a sticking prop automatically turns the prop into debris.}}
;<code>onfirstimpact <choices></code>
;{{mono|onfirstimpact <choices>}}
: ''When we first hit something after being thrown by the gravity gun.''
: ''When we first hit something after being thrown by the gravity gun.''
:; <code>break</code>
:; {{mono|break}}
:: Breaks on colliding with anything after being launched. {{tip|Use this with explosive props that should break after the player launches them.}}
:: Breaks on colliding with anything after being launched. {{tip|Use this with explosive props that should break after the player launches them.}}
:; <code>paintsplat</code>
:; {{mono|paintsplat}}
:: Applies paint decals to the first thing we hit after being launched.
:: Applies paint decals to the first thing we hit after being launched.
:: They come in 3 colors (Red, Green, Blue) by default, but each instance of this prop should stick to one color.
:: They come in 3 colors (Red, Green, Blue) by default, but each instance of this prop should stick to one color.
:; <code>impale</code>
:; {{mono|impale}}
:: Sometimes impales the first NPC we hit and sticks it to the wall. {{note|This interaction has several bugs. Use with caution.}} {{warning|This interaction is actually executed against all high-speed collisions regardless of whether it's the first impact or not, so the interaction occasionally runs several times per impact. This can cause various bugs, including spawning extra ragdolls and/or crashing the game. This also has the <code>stick</code> interaction built-in, causing the prop to sometimes disappear due to the aforementioned collision rules.}} {{bug|NPCs killed by impalement will not play their death sound(s).}}
:: Sometimes impales the first NPC we hit and sticks it to the wall. {{note|This interaction has several bugs. Use with caution.}} {{warning|This interaction is actually executed against all high-speed collisions regardless of whether it's the first impact or not, so the interaction occasionally runs several times per impact. This can cause various bugs, including spawning extra ragdolls and/or crashing the game. This also has the {{mono|stick}} interaction built-in, causing the prop to sometimes disappear due to the aforementioned collision rules.}} {{bug|NPCs killed by impalement will not play their death sound(s).}}
:; <code>bloodsplat</code>
:; {{mono|bloodsplat}}
:: ''Ragdolls only.'' Creates a blood [[decal]] on the first thing we hit.
:: ''Ragdolls only.'' Creates a blood [[decal]] on the first thing we hit.
:; <code>alienbloodsplat</code>
:; {{mono|alienbloodsplat}}
:: ''Ragdolls only.'' Identical to <code>bloodsplat</code>, but creates alien blood instead.
:: ''Ragdolls only.'' Identical to {{mono|bloodsplat}}, but creates alien blood instead.
;<code>onlaunch <choices></code>
;{{mono|onlaunch <choices>}}
: ''When we are flung by the gravity gun.''
: ''When we are flung by the gravity gun.''
:; Default
:; Default
:: Physgun applies random angular velocity to the prop as it launches.
:: Physgun applies random angular velocity to the prop as it launches.
:; <code>spin_none</code>
:; {{mono|spin_none}}
:: Prop does not spin when launched. {{bug|This interaction doesn't work as expected since {{src07}}.}}
:: Prop does not spin when launched. {{bug|This interaction doesn't work as expected since {{src07}}.}}
:; <code>spin_zaxis</code>
:; {{mono|spin_zaxis}}
:: Prop should spin around the Z axis when launched by the physcannon. (e.g. Ravenholm propellers.) {{tip|This automatically adds slash damage to the prop, allowing it to slice zombies.}}
:: Prop should spin around the Z axis when launched by the physcannon. (e.g. Ravenholm propellers.) {{tip|This automatically adds slash damage to the prop, allowing it to slice zombies.}}
; <code>onbreak <choices></code>
; {{mono|onbreak <choices>}}
: ''When we are broken by any means.'' (or after being flung by the gravity gun)
: ''When we are broken by any means.'' (or after being flung by the gravity gun)
:;explode_fire
:;explode_fire
:: Explodes in a fireball and ignites nearby enemies (that are flammable) {{note|Explosive properties ''must'' be defined in <code>prop_data</code> in order to use this interaction.}} {{tip|Use this in conjunction with [[#Fire interactions|fire_interactions]] to allow the prop to ignite before exploding and use <code>prop_data</code> to control damage and radius.}}
:: Explodes in a fireball and ignites nearby enemies (that are flammable) {{note|Explosive properties ''must'' be defined in {{mono|prop_data}} in order to use this interaction.}} {{tip|Use this in conjunction with [[#Fire interactions|fire_interactions]] to allow the prop to ignite before exploding and use {{mono|prop_data}} to control damage and radius.}}
; <code>damage none</code>
; {{mono|damage none}}
: Prop does not deal impact damage, meaning it cannot deal any damage directly from hitting anything else. The prop can still deal damage with other interactions.
: Prop does not deal impact damage, meaning it cannot deal any damage directly from hitting anything else. The prop can still deal damage with other interactions.
; <code>allow_overhead yes</code>
; {{mono|allow_overhead yes}}
: Allows the gravity gun to carry the prop directly above the wielder. {{note|Some entities don't need this interaction to allow the prop to be carried overhead. See <code>CGrabController::IsObjectAllowedOverhead()</code>.}}
: Allows the gravity gun to carry the prop directly above the wielder. {{note|Some entities don't need this interaction to allow the prop to be carried overhead. See {{mono|CGrabController::IsObjectAllowedOverhead()}}.}}
; <code>onpickup <choices></code>
; {{mono|onpickup <choices>}}
: ''When we are picked up by the gravity gun.'' (some interactions like <code>create_flare</code> can be triggered by +USE)
: ''When we are picked up by the gravity gun.'' (some interactions like {{mono|create_flare}} can be triggered by +USE)
:; onpickup create_flare
:; onpickup create_flare
:: Emits a flare from the "fuse" attachment when picked up. {{note|<code>HL2_EPISODIC</code> DLLs only; see <code>CBreakableProp::OnPhysGunPickup()</code>.}} {{bug|Doesn't work in {{bms|4}}, use {{ent|prop_flare}} instead.}}
:: Emits a flare from the "fuse" attachment when picked up. {{note|{{mono|HL2_EPISODIC}} DLLs only; see {{mono|CBreakableProp::OnPhysGunPickup()}}.}} {{bug|Doesn't work in {{bms|4}}, use {{ent|prop_flare}} instead.}}
:; onpickup boogie
:; onpickup boogie
:: ''Ragdolls only.'' Begins ragdoll boogie when released, electrocuting the ragdoll and causing it to flail rapidly.
:: ''Ragdolls only.'' Begins ragdoll boogie when released, electrocuting the ragdoll and causing it to flail rapidly.
Line 111: Line 111:


== Fire Interactions ==
== Fire Interactions ==
The <code>fire_interactions</code> block defines flammability. It is not required to make NPCs flammable.
The {{mono|fire_interactions}} block defines flammability. It is not required to make NPCs flammable.


{{note|Unbreakable models (health 0) can still be made flammable, but they cannot be ignited by other fires or explosions and will not take any damage from the fire. They can only be ignited with the "Ignite" input.}}
{{note|Unbreakable models (health 0) can still be made flammable, but they cannot be ignited by other fires or explosions and will not take any damage from the fire. They can only be ignited with the "Ignite" input.}}


===Options===
===Options===
;<code>flammable yes</code>
;{{mono|flammable yes}}
:Allows the prop to be ignited by fire and explosions. {{note|<code>flammable yes</code> does nothing in {{gmod}}. All props are flammable. You can use <code>flammable no</code> to disable ignition from explosive damage.}}
:Allows the prop to be ignited by fire and explosions. {{note|{{mono|flammable yes}} does nothing in {{gmod}}. All props are flammable. You can use {{mono|flammable no}} to disable ignition from explosive damage.}}
;<code>ignite halfhealth</code>
;{{mono|ignite halfhealth}}
:Causes the prop to ignite spontaneously upon reaching 50% health.
:Causes the prop to ignite spontaneously upon reaching 50% health.
;<code>explosive_resist yes</code>
;{{mono|explosive_resist yes}}
:Causes the prop to ignite instead of breaking when it is damaged by an explosion.
:Causes the prop to ignite instead of breaking when it is damaged by an explosion.


Line 126: Line 126:
This section is for leftover interactions that are now nonfunctional or no longer exist at all.
This section is for leftover interactions that are now nonfunctional or no longer exist at all.
===Physgun Interactions===
===Physgun Interactions===
;<code>onfirstimpact <choices></code>
;{{mono|onfirstimpact <choices>}}
:  
:  
:; <code>lose_energy</code>
:; {{mono|lose_energy}}
:  
:  
:: Can be found in <code>models/props_junk/sawblade001a</code>. No code exists in the SDK.
:: Can be found in {{mono|models/props_junk/sawblade001a}}. No code exists in the SDK.
===World Interactions===
===World Interactions===
Unused code exists of a KV block known as <code>world_interactions</code> belonging to a single interaction.
Unused code exists of a KV block known as {{mono|world_interactions}} belonging to a single interaction.
; <code>onworldimpact <choices></code>
; {{mono|onworldimpact <choices>}}
:  
:  
:; <code>bloodsplat</code>
:; {{mono|bloodsplat}}
:: This is declared and defined in the SDK, but it is not functional or used anywhere else. Not to be confused with the <code>onfirstimpact</code> variant for ragdolls.
:: This is declared and defined in the SDK, but it is not functional or used anywhere else. Not to be confused with the {{mono|onfirstimpact}} variant for ragdolls.


== Creating New Interactions ==
== Creating New Interactions ==
Line 142: Line 142:


===Props===
===Props===
Prop interactions are declared in <code>props_shared.h</code> starting at Line 49.
Prop interactions are declared in {{mono|props_shared.h}} starting at Line 49.


<pre>// Propdata defined interactions
<pre>// Propdata defined interactions
Line 173: Line 173:
};</pre>
};</pre>


To create a new interaction, simply add another entry to this list. Do not put any interactions below <code>PROPINTER_NUM_INTERACTIONS</code> and try to avoid putting any below <code>PROPINTER_PHYSGUN_NOTIFY_CHILDREN</code> unless you know what you are doing. The order of this list is crucial later. The comment at the bottom of the list implies there can only be a maximum of 32 interactions. Commenting the keyvalue of your interaction is optional and has no negative consequences, nor does it do anything implement your interaction. In this example, we will create <code>PROPINTER_WORLD_KILL</code>, which would remove a prop the moment it hits the world. We will put it in between <code>PROPINTER_WORLD_BLOODSPLAT</code> and <code>PROPINTER_PHYSGUN_NOTIFY_CHILDREN</code>.
To create a new interaction, simply add another entry to this list. Do not put any interactions below {{mono|PROPINTER_NUM_INTERACTIONS}} and try to avoid putting any below {{mono|PROPINTER_PHYSGUN_NOTIFY_CHILDREN}} unless you know what you are doing. The order of this list is crucial later. The comment at the bottom of the list implies there can only be a maximum of 32 interactions. Commenting the keyvalue of your interaction is optional and has no negative consequences, nor does it do anything implement your interaction. In this example, we will create {{mono|PROPINTER_WORLD_KILL}}, which would remove a prop the moment it hits the world. We will put it in between {{mono|PROPINTER_WORLD_BLOODSPLAT}} and {{mono|PROPINTER_PHYSGUN_NOTIFY_CHILDREN}}.


<pre> PROPINTER_WORLD_KILL, // "onworldimpact", "kill"</pre>
<pre> PROPINTER_WORLD_KILL, // "onworldimpact", "kill"</pre>


In order for <code>$keyvalues</code> to use it, its KeyValue must be defined in a separate list at Line 155 in <code>props_shared.cpp</code>:
In order for {{mono|$keyvalues}} to use it, its KeyValue must be defined in a separate list at Line 155 in {{mono|props_shared.cpp}}:


<pre>propdata_interaction_s sPropdataInteractionSections[PROPINTER_NUM_INTERACTIONS] =
<pre>propdata_interaction_s sPropdataInteractionSections[PROPINTER_NUM_INTERACTIONS] =
Line 203: Line 203:
Format: { Section Name, Key Name, Value }
Format: { Section Name, Key Name, Value }


You can use a different section name (e.g., <code>world_interactions</code>) without consequence, except that you'd need a whole new block separate from <code>physgun_interactions</code> or <code>fire_interactions</code>.
You can use a different section name (e.g., {{mono|world_interactions}}) without consequence, except that you'd need a whole new block separate from {{mono|physgun_interactions}} or {{mono|fire_interactions}}.


'''This list must be in the same order as the original enumerator.'''
'''This list must be in the same order as the original enumerator.'''


<code>PROPINTER_PHYSGUN_NOTIFY_CHILDREN</code> is a unique exception to this list. It is defined as a physgun interaction, but apparently it has no keyvalues declared here and thus cannot be used in a model's QC keyvalues. It was suggested earlier that you should avoid placing interactions below it because it may confuse the new keyvalue with <code>PROPINTER_PHYSGUN_NOTIFY_CHILDREN</code>. In order to associate your new interaction with the correct keyvalues, you must either declare <code>PROPINTER_PHYSGUN_NOTIFY_CHILDREN</code> beforehand or just avoid placing any interactions below <code>PROPINTER_PHYSGUN_NOTIFY_CHILDREN</code> in the first place. <code>PROPINTER_PHYSGUN_NOTIFY_CHILDREN</code> is believed to be used by props with [[npc_hunter|Hunter]] flechettes on them and was most likely never meant to be set via KeyValues.
{{mono|PROPINTER_PHYSGUN_NOTIFY_CHILDREN}} is a unique exception to this list. It is defined as a physgun interaction, but apparently it has no keyvalues declared here and thus cannot be used in a model's QC keyvalues. It was suggested earlier that you should avoid placing interactions below it because it may confuse the new keyvalue with {{mono|PROPINTER_PHYSGUN_NOTIFY_CHILDREN}}. In order to associate your new interaction with the correct keyvalues, you must either declare {{mono|PROPINTER_PHYSGUN_NOTIFY_CHILDREN}} beforehand or just avoid placing any interactions below {{mono|PROPINTER_PHYSGUN_NOTIFY_CHILDREN}} in the first place. {{mono|PROPINTER_PHYSGUN_NOTIFY_CHILDREN}} is believed to be used by props with [[npc_hunter|Hunter]] flechettes on them and was most likely never meant to be set via KeyValues.


For our example of <code>PROPINTER_WORLD_KILL</code>, we will place this at the bottom according to its position in the enum:
For our example of {{mono|PROPINTER_WORLD_KILL}}, we will place this at the bottom according to its position in the enum:
<pre>{ "physgun_interactions", "onworldimpact", "kill" }, // PROPINTER_WORLD_KILL,</pre>
<pre>{ "physgun_interactions", "onworldimpact", "kill" }, // PROPINTER_WORLD_KILL,</pre>
Again, commenting its name is optional.
Again, commenting its name is optional.
Line 218: Line 218:
void RemoveInteraction( propdata_interactions_t Interaction ) // Removes a specific interaction from this prop</pre>
void RemoveInteraction( propdata_interactions_t Interaction ) // Removes a specific interaction from this prop</pre>


For our example, we will implement <code>PROPINTER_WORLD_KILL</code> in <code>props.cpp</code> under <code>CPhysicsProp::HandleAnyCollisionInteractions</code>.
For our example, we will implement {{mono|PROPINTER_WORLD_KILL}} in {{mono|props.cpp}} under {{mono|CPhysicsProp::HandleAnyCollisionInteractions}}.
<pre> if ( HasInteraction(PROPINTER_WORLD_KILL) )
<pre> if ( HasInteraction(PROPINTER_WORLD_KILL) )
{
{
Line 237: Line 237:


===Ragdolls===
===Ragdolls===
Creating new interactions in <code>physics_prop_ragdoll.cpp</code> is much simpler but it is also much more limited. It involves their keyvalues alone, meaning you cannot make anything like <code>PROPINTER_PHYSGUN_NOTIFY_CHILDREN</code> from the previous section, and they can only be used when under <code>physgun_interactions</code>.
Creating new interactions in {{mono|physics_prop_ragdoll.cpp}} is much simpler but it is also much more limited. It involves their keyvalues alone, meaning you cannot make anything like {{mono|PROPINTER_PHYSGUN_NOTIFY_CHILDREN}} from the previous section, and they can only be used when under {{mono|physgun_interactions}}.


They are only called by this function:
They are only called by this function:

Revision as of 10:32, 6 March 2025

English (en)Translate (Translate)

Prop interactions, also known as propdata interactions, are a group of independent KeyValues blocks that control how props handle interaction from outside forces, like being launched by the gravity gun, and how they should employ fire, like igniting after taking enough damage. They are technically part of prop_data, but they are usually treated separately and embedded in a model with the $keyvalues QC command. Most are defined in props_shared.h and props_shared.cpp.

Warning.pngWarning:Having more than one key of the same name (e.g. "onfirstimpact break" and "onfirstimpact paintsplat") in the same block may cause some or all involved keyvalues to stop working.

Examples

They are usually embedded in a model like this:

$keyvalues
{
	physgun_interactions
	{
	 	preferred_carryangles 	"-90 0 0"
	 	onworldimpact 		stick
	 	onlaunch 		spin_zaxis
	 	onbreak 		explode_fire
	}
	fire_interactions
	{
	 	ignite			halfhealth
 	 	explosive_resist	yes
 	 	flammable		yes
	}
}

Putting them under prop_data is also possible:

$keyvalues
{
	prop_data
	{
		physgun_interactions
		{
		 	preferred_carryangles 	"-90 0 0"
		 	onfirstimpact 		break
		 	allow_overhead		yes
		}
		fire_interactions
		{
	 	 	explosive_resist	yes
	 	 	flammable		yes
		}
	}
}

You can even use them in propdata base types:

PropData.txt
{
	"Wooden.Base"
	{
		"dmg.bullets"		"0.75"
		"dmg.club"		"2.0"
		"dmg.explosive" 	"1.5"
		
		physgun_interactions
		{
			"onfirstimpact"	"paintsplat"
		}
	}
}


Physgun Interactions

The physgun_interactions block affects how a prop or ragdoll is handled by and responds to the Gravity Gun. Despite the name, some interactions, like explode_fire, can be triggered by forces not related to the gravity gun.

Options

preferred_carryangles <angles>
Sets the angles, relative to the player's orientation, at which the prop will be held when carried.
This is used with the sawblades and propellers in Ravenholm.
Note.pngNote:npc_turret_floor is held upright automatically and the model does not need to use this keyvalue.
carry_distance_offset <float>
Adds or subtracts to the prop's distance from whoever is carrying it.
Todo: Confirm and clarify
onworldimpact <choices>
When we hit the world after being thrown by the gravity gun.
stick
Sticks to what we hit if we're traveling fast enough.
Note.pngNote:Using the gravity gun to pick up a sticking prop automatically turns the prop into debris.
onfirstimpact <choices>
When we first hit something after being thrown by the gravity gun.
break
Breaks on colliding with anything after being launched.
Tip.pngTip:Use this with explosive props that should break after the player launches them.
paintsplat
Applies paint decals to the first thing we hit after being launched.
They come in 3 colors (Red, Green, Blue) by default, but each instance of this prop should stick to one color.
impale
Sometimes impales the first NPC we hit and sticks it to the wall.
Note.pngNote:This interaction has several bugs. Use with caution.
Warning.pngWarning:This interaction is actually executed against all high-speed collisions regardless of whether it's the first impact or not, so the interaction occasionally runs several times per impact. This can cause various bugs, including spawning extra ragdolls and/or crashing the game. This also has the stick interaction built-in, causing the prop to sometimes disappear due to the aforementioned collision rules.
Icon-Bug.pngBug:NPCs killed by impalement will not play their death sound(s).  [todo tested in ?]
bloodsplat
Ragdolls only. Creates a blood decal on the first thing we hit.
alienbloodsplat
Ragdolls only. Identical to bloodsplat, but creates alien blood instead.
onlaunch <choices>
When we are flung by the gravity gun.
Default
Physgun applies random angular velocity to the prop as it launches.
spin_none
Prop does not spin when launched.
Icon-Bug.pngBug:This interaction doesn't work as expected since Source 2007.  [todo tested in ?]
spin_zaxis
Prop should spin around the Z axis when launched by the physcannon. (e.g. Ravenholm propellers.)
Tip.pngTip:This automatically adds slash damage to the prop, allowing it to slice zombies.
onbreak <choices>
When we are broken by any means. (or after being flung by the gravity gun)
explode_fire
Explodes in a fireball and ignites nearby enemies (that are flammable)
Note.pngNote:Explosive properties must be defined in prop_data in order to use this interaction.
Tip.pngTip:Use this in conjunction with fire_interactions to allow the prop to ignite before exploding and use prop_data to control damage and radius.
damage none
Prop does not deal impact damage, meaning it cannot deal any damage directly from hitting anything else. The prop can still deal damage with other interactions.
allow_overhead yes
Allows the gravity gun to carry the prop directly above the wielder.
Note.pngNote:Some entities don't need this interaction to allow the prop to be carried overhead. See CGrabController::IsObjectAllowedOverhead().
onpickup <choices>
When we are picked up by the gravity gun. (some interactions like create_flare can be triggered by +USE)
onpickup create_flare
Emits a flare from the "fuse" attachment when picked up.
Note.pngNote:HL2_EPISODIC DLLs only; see CBreakableProp::OnPhysGunPickup().
Icon-Bug.pngBug:Doesn't work in Black Mesa Black Mesa, use prop_flare instead.  [todo tested in ?]
onpickup boogie
Ragdolls only. Begins ragdoll boogie when released, electrocuting the ragdoll and causing it to flail rapidly.
If the ragdoll was punted, the boogie lasts for 3 seconds. If it was released by other means, like being dropped, it lasts for 2 seconds.

Fire Interactions

The fire_interactions block defines flammability. It is not required to make NPCs flammable.

Note.pngNote:Unbreakable models (health 0) can still be made flammable, but they cannot be ignited by other fires or explosions and will not take any damage from the fire. They can only be ignited with the "Ignite" input.

Options

flammable yes
Allows the prop to be ignited by fire and explosions.
Note.pngNote:flammable yes does nothing in Garry's Mod. All props are flammable. You can use flammable no to disable ignition from explosive damage.
ignite halfhealth
Causes the prop to ignite spontaneously upon reaching 50% health.
explosive_resist yes
Causes the prop to ignite instead of breaking when it is damaged by an explosion.

Non-Functional Interactions

This section is for leftover interactions that are now nonfunctional or no longer exist at all.

Physgun Interactions

onfirstimpact <choices>
lose_energy
Can be found in models/props_junk/sawblade001a. No code exists in the SDK.

World Interactions

Unused code exists of a KV block known as world_interactions belonging to a single interaction.

onworldimpact <choices>
bloodsplat
This is declared and defined in the SDK, but it is not functional or used anywhere else. Not to be confused with the onfirstimpact variant for ragdolls.

Creating New Interactions

Creating new interactions in your own mod is relatively simple, depending on if you want to make them for props or ragdolls.

Props

Prop interactions are declared in props_shared.h starting at Line 49.

// Propdata defined interactions
enum propdata_interactions_t
{
	PROPINTER_PHYSGUN_WORLD_STICK,		// "onworldimpact"	"stick"
	PROPINTER_PHYSGUN_FIRST_BREAK,		// "onfirstimpact"	"break"
	PROPINTER_PHYSGUN_FIRST_PAINT,		// "onfirstimpact"	"paintsplat"
	PROPINTER_PHYSGUN_FIRST_IMPALE,		// "onfirstimpact"	"impale"
	PROPINTER_PHYSGUN_LAUNCH_SPIN_NONE,	// "onlaunch"		"spin_none"
	PROPINTER_PHYSGUN_LAUNCH_SPIN_Z,	// "onlaunch"		"spin_zaxis"
	PROPINTER_PHYSGUN_BREAK_EXPLODE,	// "onbreak"		"explode_fire"
	PROPINTER_PHYSGUN_DAMAGE_NONE,		// "damage"			"none"

	PROPINTER_FIRE_FLAMMABLE,			// "flammable"			"yes"
	PROPINTER_FIRE_EXPLOSIVE_RESIST,	// "explosive_resist"	"yes"
	PROPINTER_FIRE_IGNITE_HALFHEALTH,	// "ignite"				"halfhealth"

	PROPINTER_PHYSGUN_CREATE_FLARE,		// "onpickup"		"create_flare"

	PROPINTER_PHYSGUN_ALLOW_OVERHEAD,	// "allow_overhead"	"yes"

	PROPINTER_WORLD_BLOODSPLAT,			// "onworldimpact", "bloodsplat"
	
	PROPINTER_PHYSGUN_NOTIFY_CHILDREN,	// "onfirstimpact" cause attached flechettes to explode

	// If we get more than 32 of these, we'll need a different system

	PROPINTER_NUM_INTERACTIONS,
};

To create a new interaction, simply add another entry to this list. Do not put any interactions below PROPINTER_NUM_INTERACTIONS and try to avoid putting any below PROPINTER_PHYSGUN_NOTIFY_CHILDREN unless you know what you are doing. The order of this list is crucial later. The comment at the bottom of the list implies there can only be a maximum of 32 interactions. Commenting the keyvalue of your interaction is optional and has no negative consequences, nor does it do anything implement your interaction. In this example, we will create PROPINTER_WORLD_KILL, which would remove a prop the moment it hits the world. We will put it in between PROPINTER_WORLD_BLOODSPLAT and PROPINTER_PHYSGUN_NOTIFY_CHILDREN.

	PROPINTER_WORLD_KILL,			// "onworldimpact", "kill"

In order for $keyvalues to use it, its KeyValue must be defined in a separate list at Line 155 in props_shared.cpp:

propdata_interaction_s sPropdataInteractionSections[PROPINTER_NUM_INTERACTIONS] =
{
	{ "physgun_interactions", "onworldimpact", "stick" },		// PROPINTER_PHYSGUN_WORLD_STICK,
	{ "physgun_interactions", "onfirstimpact", "break" },		// PROPINTER_PHYSGUN_FIRST_BREAK,
	{ "physgun_interactions", "onfirstimpact", "paintsplat" },	// PROPINTER_PHYSGUN_FIRST_PAINT,
	{ "physgun_interactions", "onfirstimpact", "impale" },		// PROPINTER_PHYSGUN_FIRST_IMPALE,
	{ "physgun_interactions", "onlaunch", "spin_none" },		// PROPINTER_PHYSGUN_LAUNCH_SPIN_NONE,
	{ "physgun_interactions", "onlaunch", "spin_zaxis" },		// PROPINTER_PHYSGUN_LAUNCH_SPIN_Z,
	{ "physgun_interactions", "onbreak", "explode_fire" },		// PROPINTER_PHYSGUN_BREAK_EXPLODE,
	{ "physgun_interactions", "damage", "none" },				// PROPINTER_PHYSGUN_DAMAGE_NONE,
	
	{ "fire_interactions", "flammable", "yes" },				// PROPINTER_FIRE_FLAMMABLE,
	{ "fire_interactions", "explosive_resist", "yes" },			// PROPINTER_FIRE_EXPLOSIVE_RESIST,
	{ "fire_interactions", "ignite", "halfhealth" },			// PROPINTER_FIRE_IGNITE_HALFHEALTH,

	{ "physgun_interactions", "onpickup", "create_flare" },		// PROPINTER_PHYSGUN_CREATE_FLARE,

	{ "physgun_interactions", "allow_overhead", "yes" },	// 	PROPINTER_PHYSGUN_ALLOW_OVERHEAD,

	{ "world_interactions", "onworldimpact", "bloodsplat" },	// PROPINTER_WORLD_BLOODSPLAT,
};

Format: { Section Name, Key Name, Value }

You can use a different section name (e.g., world_interactions) without consequence, except that you'd need a whole new block separate from physgun_interactions or fire_interactions.

This list must be in the same order as the original enumerator.

PROPINTER_PHYSGUN_NOTIFY_CHILDREN is a unique exception to this list. It is defined as a physgun interaction, but apparently it has no keyvalues declared here and thus cannot be used in a model's QC keyvalues. It was suggested earlier that you should avoid placing interactions below it because it may confuse the new keyvalue with PROPINTER_PHYSGUN_NOTIFY_CHILDREN. In order to associate your new interaction with the correct keyvalues, you must either declare PROPINTER_PHYSGUN_NOTIFY_CHILDREN beforehand or just avoid placing any interactions below PROPINTER_PHYSGUN_NOTIFY_CHILDREN in the first place. PROPINTER_PHYSGUN_NOTIFY_CHILDREN is believed to be used by props with Hunter flechettes on them and was most likely never meant to be set via KeyValues.

For our example of PROPINTER_WORLD_KILL, we will place this at the bottom according to its position in the enum:

{ "physgun_interactions", "onworldimpact", "kill" },	// PROPINTER_WORLD_KILL,

Again, commenting its name is optional.

Now that our interaction has been created, we can put it into action. Three functions can be used to handle prop interactions:

bool		HasInteraction( propdata_interactions_t Interaction ) // Checks to see if this prop has a specific interaction
void		SetInteraction( propdata_interactions_t Interaction ) // Adds a specific interaction to this prop
void		RemoveInteraction( propdata_interactions_t Interaction ) // Removes a specific interaction from this prop

For our example, we will implement PROPINTER_WORLD_KILL in props.cpp under CPhysicsProp::HandleAnyCollisionInteractions.

	if ( HasInteraction(PROPINTER_WORLD_KILL) )
	{
		if (pEvent->pEntities[!index]->IsWorld())
		{
			UTIL_Remove(this);
		}
	}

Once this is complete, you should now be able to implement it in a model's QC keyvalues. For example:

$keyvalues
{
	physgun_interactions
	{
	 	onworldimpact 		kill
	}
}

Ragdolls

Creating new interactions in physics_prop_ragdoll.cpp is much simpler but it is also much more limited. It involves their keyvalues alone, meaning you cannot make anything like PROPINTER_PHYSGUN_NOTIFY_CHILDREN from the previous section, and they can only be used when under physgun_interactions.

They are only called by this function:

HasPhysgunInteraction( const char *pszKeyName, const char *pszValue )
// Example: HasPhysgunInteraction("onfirstimpact", "bloodsplat")

Other than adding the keyvalues to your ragdoll's QC file, all you need to do is call the function with your keyvalue in whatever code you want to use.


See also