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 , but they are usually treated separately and embedded in a model with the QC command. Most are defined in props_shared.h and props_shared.cpp.
==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. 
;carry_distance_offset <float>
:Adds or subtracts to the prop's distance from whoever is carrying it. 
; 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. 
;onfirstimpact <choices>
: When we first hit something after being thrown by the gravity gun.
:; break
:: Breaks on colliding with anything after being launched. 
:; 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. 
:; 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. 
:; spin_zaxis
:: Prop should spin around the Z axis when launched by the physcannon. (e.g. Ravenholm propellers.) 
; 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) 
; 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. 
; 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. 
:; 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.
===Options===
;flammable yes
:Allows the prop to be ignited by fire and explosions.
;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 ==
* 
* Adnan's Rotational Grav Gun - a 4MB demo mod that simply allows the player to control the "carryangles" of objects held by the Gravgun.
Category:QC Keyvalues