Puffs are actors spawned by hitscan attacks (such as A_FireBullets), railgun attacks (such as A_RailAttack) and melee attacks when hitting a wall (and also when hitting an actor, provided PUFFONACTORS flag is used). Whereas when using a projectile things like damagetype or flags like EXTREMEDEATH have to be attached to the projectile, in case of hitscan attacks they need to be defined in the puffs.
There's a misconception that creating new puffs requires inheriting from BulletPuff. Actually, there's no special "puff" class. A puff is just an actor; it starts acting as a puff automatically when it's used by the appropriate attack functions. There are no special flags or properties that have to be given to the Actor in order for it to be useable as puff. In fact, even classes that aren't designed to be puffs, like items or monsters, can still be used as puffs and will spawn at the points where the attack hits.
Most of the time puffs don't need any collision and can use NOBLOCKMAP or even NOINTERACTION (although the latter can sometimes cause weird collision on planes).
Puff usage and behavior
Actors used puffs have the following properties:
- they will pass their properties such as damagetype and damage-related flags to the attack
- they can utilize vspeed property to automatically float upwards when they spawn
- puffs may be replaced by particles when spawned if the ALLOWPARTICLES flag is set (and the player has the appropriate option enabled in their configuration settings)
- most importantly, puffs will automatically utilize special sounds and special states in their behavior:
|Attack result¹||Missed||Hit wall||Hit actor|
|Puff sound played²||Active||Attack||See|
|Puff state entered³||Crash||Spawn||Melee|
- 1. By default, puffs are only spawned as a result of a hitscan attack hitting a wall, or an actor with one or more of NOBLOOD, INVULNERABLE and DORMANT flags set. In order for puffs to appear in other circumstances, certain flags must be in effect on either the puff actor or the target actor. The ALWAYSPUFF flag applied to the puff actor makes it spawn even for missed attacks. The PUFFONACTORS flag applied to the puff actor will make it spawn (instead of Blood) even if the hit actor does not have any of the aforementioned flags.
- 2. If no SeeSound is defined, the AttackSound is played instead. To have a silent SeeSound, you need to use SNDINFO to give a name to the internal sound lump DSEMPTY, and assign that sound to the SeeSound property.
- 3. If no Crash or Melee state sequence is defined, the puff's Spawn state is entered by default.
- If a puff has an XDeath state defined, it will enter it upon hitting a bleeding actor, provided it also has the PUFFONACTORS flag.
Further customization with puffs can be achieved by using the PUFFONACTORS flag to make it respect the three HIT* flags (e.g. HITTRACER): this allows performing thigs with the actor that was hit using the tracer pointer and one of the states entered when the attack hits an actor (such as Melee).
Using PUFFGETSOWNER flag will set whoever used the attack as the target of the puff, which allows performing conditional checks and such based on the shooter's class and properties.
If the puff has the THRUGHOST flag, it will not affect enemies with the GHOST flag.
Puffs are spawned so as to face the originator of the attack.