A Explode: Difference between revisions

From ZDoom Wiki
Jump to navigation Jump to search
(Added return value and an example)
 
(36 intermediate revisions by 7 users not shown)
Line 1: Line 1:
__NOTOC__{{codepointer|Generic Attack}}
__NOTOC__{{codepointer|Generic Attack}}
{{doomwiki|A_Explode}}
'''A_Explode''' [(int ''explosiondamage'' [, int ''explosionradius'' [, int ''flags'' [, bool ''alert'' [, int ''fulldamageradius'' [, int ''nails'' [, int ''naildamage'' [, str ''pufftype'']]]]]]])]<br>
{{note|{{function|A_Explode}} was originially designed for [[Doom]] and comes with certain implicit rules (mostly outlined below). In custom projects using '''{{function|RadiusAttack}}''' instead may be preferable for higher degree of control.}}
int '''A_Explode''' [(int ''explosiondamage'' [, int ''explosionradius'' [, int ''flags'' [, bool ''alert'' [, int ''fulldamageradius'' [, int ''nails'' [, int ''naildamage'' [, str ''pufftype'']]]]]]])] {{git|ec14dd9}}<br>
int '''A_Explode''' [(int ''explosiondamage'' [, int ''explosionradius'' [, int ''flags'' [, bool ''alert'' [, int ''fulldamageradius'' [, int ''nails'' [, int ''naildamage'' [, str ''pufftype'' [, str ''damagetype'']]]]]]]])] {{git|aa2ca77}}


'''{{class|Actor}}'''
== Usage ==


int '''A_Explode'''(int ''damage'' = -1, double ''distance'' = -1, int ''flags'' = XF_HURTSOURCE, bool ''alert'' = false, int ''fulldamagedistance'' = 0, int ''nails'' = 0, int ''naildamage'' = 10, class<Actor> ''pufftype'' = "BulletPuff", name ''damagetype'' = 'none')
Performs an explosive (radius) attack.

== Usage ==
Performs an explosive (radius) attack. In [[ZScript]] this functions as a convenient wrapper for the native function '''[[RadiusAttack]]'''.


=== Parameters ===
=== Parameters ===


*{{c|int '''damage'''}}
* ''explosiondamage'': How much damage is inflicted at the center of the explosion. Default is 128.
:How much damage is inflicted at the center of the explosion. If this is set to a value that is less than 0, the {{c|{{Property|ExplosionDamage}}}} property is used for the damage. Default is -1.
* ''explosionradius'': The area covered by the damage (damage inflicted drop linearly with distance). Note that a radius larger than 32767 extends beyond ZDoom's map space limitations, and will overflow with undesired results (such as becoming too small and damaging nothing). Default is 128.
:Note: The default value of the {{c|{{Property|ExplosionDamage}}}} property is 128.
* ''flags'': The following flags can be combined by using the {{!}} character between the constant names:
{{warning|Using a negative value for {{c|damage}} not only sets the damage value to be equal to the actor's {{property|ExplosionDamage}} property, it also forces values for some other parameters:<br>- {{c|radius}} becomes equal to {{property|ExplosionRadius}} and will ignore other values;<br>- {{c|flags}} will only recognize either {{c|XF_HURTSOURCE}} or {{c|0}}, ignoring other flags;<br>- {{c|alert}} will be automatically set to {{c|false}}.<br>As such, if custom behavior is desired, always specify an explicit positive damage value.}}
** '''XF_HURTSOURCE'''&nbsp;&mdash; Hurts the source: if set, the source can be damaged by the explosion. Note that the source is not necessarily the calling actor. This flag is set by default.
*{{c|double '''distance'''}}
** '''XF_NOTMISSILE'''&nbsp;&mdash; Not a missile: if set, the calling actor is considered to be the source. By default, the calling actor is assumed to be a projectile, and the source is therefore considered to be the calling actor's [[actor pointer|target]].
:The area covered by the damage (damage inflicted drop linearly with distance). Note that a radius larger than 32767 extends beyond ZDoom's map space limitations, and will overflow with undesired results (such as becoming too small and damaging nothing). If {{c|distance}} is less than 0, the {{c|{{Property|ExplosionRadius}}}} property is used for the radius. In this case, if the {{c|{{Property|ExplosionRadius}}}} property is set to a value less than 0, it'll use the same value as the {{c|{{Property|ExplosionDamage}}}} property.
** '''XF_EXPLICITDAMAGETYPE''' {{git|aa2ca77}} &nbsp;&mdash; the damagetype parameter will never change to the actor's damagetype.
:Note: The default value of the {{c|{{Property|ExplosionRadius}}}} property is -1, which means it uses the same value as {{c|{{Property|ExplosionDamage}}}}.
* ''alert'': Whether the explosion rings the alarm? Default is ''false''.
*{{c|int '''flags'''}}
* ''fulldamageradius'': The area within which full damage is inflicted. Default is 0.
:Allows the alteration of the function's behavior. This parameter is ignored in favor of using the {{c|{{Property|DontHurtShooter}}}} property if {{c|damage}} is less than 0. The following flags can be combined by using the <code>|</code> character between the constant names:
* ''nails'': The number of horizontal hitscan attacks performed in a ring. Default is 0. A value of 30 emulates the A_NailBomb codepointer from [[SMMU]], while still allowing to modify all other parameters from '''A_Explode'''.
:* {{c|XF_HURTSOURCE}} — '''This flag is set by default.''' Hurts the source: if set, the source can be damaged by the explosion. Note that the source is not necessarily the calling actor. To unset the flag, either use <code>0</code> for the {{c|flags}} argument, or pass other flags to it without passing this one.
* ''naildamage'': The amount of damage inflicted by nails, if any. Default is 10.
:Flags listed below will ONLY work if {{c|damage}} is 0 or higher, and will be ignored if it's negative:
* ''pufftype'': The name of the puff to use upon calling the explosion, originating from the actor's center. If nothing is supplied, {{Class|BulletPuff}} is used.
:* {{c|XF_NOTMISSILE}} — Not a missile: if set, the calling actor is considered to be the source. By default, the calling actor is assumed to be a projectile, and the source is therefore considered to be the calling actor's [[actor pointer|target]].
* ''damagetype'': The damagetype to use for the damage of this function rather than the actor's damagetype. Defaults to none. If left as is without XF_EXPLICITDAMAGETYPE, will use the actor's damagetype instead. {{git|aa2ca77}}
:* {{c|XF_EXPLICITDAMAGETYPE}} — If set, the {{c|damagetype}} parameter will never change to the actor's {{Property|DamageType|damage type}}.

:* {{c|XF_NOSPLASH}} — Disables splash: if set, the explosion does not create any [[TERRAIN]] splashes.
'''Do not use the old actor property method of passing the parameters. Only use the parameters of '''A_Explode''' directly.'''
:* {{c|XF_THRUSTZ}} — Applies vertical thrust: if set, the attack pushes the victim vertically, in addition to horizontally. Normally, vertical thrust is applied without the need of this flag, but it could be disabled by setting the {{c|{{CVAR|C|compat_explode1}}}} compatibility flag. This flag overrides the compatibility flag.
:* {{c|XF_THRUSTLESS}} — The explosion produces no thrust whatsoever, only dealing pure damage. This can be used to supplement the native thrusting with a custom implementation.
:* {{c|XF_NOALLIES}} — The explosion does not affect any actors friendly to the source of the explosion. Only works with {{flag|FRIENDLY}} monsters and players. Keep in mind that ''XF_HURTSOURCE'' still needs to be off to not affect the source.
:* {{c|XF_CIRCULAR}} — Changes the shape of the explosion from the vanilla cuboid shape into a spherical shape.
:* {{c|XF_CIRCULARTHRUST}} — Blast actors away with more physically accurate momentum. When enabled, XF_THRUSTZ is ignored.
*{{c|bool '''alert'''}}
:Whether or not the explosion rings the alarm. This parameter is always set to <code>false</code> if {{c|damage}} is less than 0, regardless of what is passed to it. Default is <code>false</code>.
*{{c|int '''fulldamagedistance'''}}
:The area within which full damage is inflicted. Default is <code>0</code>.
*{{c|int '''nails'''}}
:The number of horizontal [[hitscan]] attacks performed in a ring, originating from the actor's center. A value of <code>30</code> emulates the [[A_NailBomb]] function from [[SMMU]], while still allowing to modify all other parameters from {{c|A_Explode}}. Default is <code>0</code>.
*{{c|int '''naildamage'''}}
:The amount of damage inflicted by the nail attack, if any. Default is <code>10</code>. If {{c|nails}} is <code>0</code>, this, obviously, has no effect.
*{{c|class<Actor> '''pufftype'''}}
:The name of the [[Puff|puff]] class to use for the nail attack. If nothing is supplied, {{c|{{Class|BulletPuff}}}} is used. Default is <code>"BulletPuff"</code>.
*{{c|name '''damagetype'''}}
:The [[damage type]] to use for the damage of this function rather than the actor's own {{Property|DamageType|damage type}}. If left as is without {{c|XF_EXPLICITDAMAGETYPE}}, will use the actor's damage type instead. Default is <code>"none"</code>.


=== Return value ===
=== Return value ===


Returns the number of actors damaged. Actors that absorb the damage completely are not counted.
The return value of the function is the number of damaged actors.

== [[ZScript]] definition ==
{{ZScriptDefinitionNote|actors/attacks.zs#L572}}
<syntaxhighlight lang="csharp">
int A_Explode(int damage = -1, double distance = -1.0, int flags = XF_HURTSOURCE, bool alert = false, double fulldamagedistance = 0.0, int nails = 0, int naildamage = 10, class<Actor> pufftype = "BulletPuff", name damagetype = "none")
{

if (damage < 0) // get parameters from metadata
{
damage = ExplosionDamage;
distance = ExplosionRadius;
flags = !DontHurtShooter;
alert = false;
}
if (distance <= 0) distance = damage;

// NailBomb effect, from SMMU but not from its source code: instead it was implemented and
// generalized from the documentation at http://www.doomworld.com/eternity/engine/codeptrs.html

if (nails)
{
double ang;
for (int i = 0; i < nails; i++)
{
ang = i*360./nails;
// Comparing the results of a test wad with Eternity, it seems A_NailBomb does not aim
LineAttack(ang, MISSILERANGE, 0.,
//P_AimLineAttack (self, ang, MISSILERANGE),
naildamage, 'Hitscan', pufftype, bMissile ? LAF_TARGETISSOURCE : 0);
}
}

if (!(flags & XF_EXPLICITDAMAGETYPE) && damagetype == 'None')
{
damagetype = self.DamageType;
}

int pflags = 0;
if (flags & XF_HURTSOURCE) pflags |= RADF_HURTSOURCE;
if (flags & XF_NOTMISSILE) pflags |= RADF_SOURCEISSPOT;
if (flags & XF_THRUSTZ) pflags |= RADF_THRUSTZ;
if (flags & XF_THRUSTLESS) pflags |= RADF_THRUSTLESS;
if (flags & XF_NOALLIES) pflags |= RADF_NOALLIES;
if (flags & XF_CIRCULAR) pflags |= RADF_CIRCULAR;

int count = RadiusAttack (target, damage, distance, damagetype, pflags, fulldamagedistance);
if (!(flags & XF_NOSPLASH)) CheckSplash(distance);
if (alert && target != NULL && target.player != NULL)
{
SoundAlert(target);
}
return count;
}</syntaxhighlight>


== Examples ==
== Examples ==


This grenades deals less damage than Doom's {{class|Rocket}} but over the same distance:
Actor MyGrenade : {{Class|Grenade}}
class MyGrenade : {{Class|Grenade}}
{
{
Default
{{Property|Speed}} 17
{
{{Property|BounceFactor}} 0.4
{{Property|BounceCount}} 6
{{Property|Speed}} 17;
{{Property|BounceFactor}} 0.4;
States
{{Property|BounceCount}} 6;
{
}
Death:
QEX1 A 0 [[A_PlaySound]]("Weapon/GenericExplode", {{const|CHAN_WEAPON}})
States
QEX1 A 5 [[A_Explode]](100, 128)
{
QEX1 BCDE 5
Death:
Stop
QEX1 A 5 bright
}
{
[[A_Explode]](100, 128);
[[A_StartSound]]("Weapon/GenericExplode", {{const|CHAN_WEAPON}});
}
QEX1 BCDE 5 bright;
Stop;
}
}
}




Whenever this rocket explodes, it logs the number of actors which got damaged by its splash effect.
Whenever this rocket explodes, it logs the number of actors which got damaged by its splash effect.
ACTOR SmartRocket : {{Class|Rocket}}
class SmartRocket : {{Class|Rocket}}
{
{
States
States
{
{
Death:
Death:
MISL B 8 Bright [[A_LogInt]]([[A_Explode]])
MISL B 8 Bright [[A_LogInt]]([[A_Explode]]);
Goto Super::Death+1
Goto Super::Death+1;
}
}
}
}

== See also ==
*[[RadiusAttack]]
*[[A_RadiusThrust]]

Latest revision as of 16:26, 28 August 2025

DoomWiki.org
For more information on this article, visit the A_Explode page on the Doom Wiki.
Note: A_Explode was originially designed for Doom and comes with certain implicit rules (mostly outlined below). In custom projects using RadiusAttack instead may be preferable for higher degree of control.


Actor

int A_Explode(int damage = -1, double distance = -1, int flags = XF_HURTSOURCE, bool alert = false, int fulldamagedistance = 0, int nails = 0, int naildamage = 10, class<Actor> pufftype = "BulletPuff", name damagetype = 'none')

Usage

Performs an explosive (radius) attack. In ZScript this functions as a convenient wrapper for the native function RadiusAttack.

Parameters

  • int damage
How much damage is inflicted at the center of the explosion. If this is set to a value that is less than 0, the ExplosionDamage property is used for the damage. Default is -1.
Note: The default value of the ExplosionDamage property is 128.
Error.gif
Warning: Using a negative value for damage not only sets the damage value to be equal to the actor's ExplosionDamage property, it also forces values for some other parameters:
- radius becomes equal to ExplosionRadius and will ignore other values;
- flags will only recognize either XF_HURTSOURCE or 0, ignoring other flags;
- alert will be automatically set to false.
As such, if custom behavior is desired, always specify an explicit positive damage value.
  • double distance
The area covered by the damage (damage inflicted drop linearly with distance). Note that a radius larger than 32767 extends beyond ZDoom's map space limitations, and will overflow with undesired results (such as becoming too small and damaging nothing). If distance is less than 0, the ExplosionRadius property is used for the radius. In this case, if the ExplosionRadius property is set to a value less than 0, it'll use the same value as the ExplosionDamage property.
Note: The default value of the ExplosionRadius property is -1, which means it uses the same value as ExplosionDamage.
  • int flags
Allows the alteration of the function's behavior. This parameter is ignored in favor of using the DontHurtShooter property if damage is less than 0. The following flags can be combined by using the | character between the constant names:
  • XF_HURTSOURCEThis flag is set by default. Hurts the source: if set, the source can be damaged by the explosion. Note that the source is not necessarily the calling actor. To unset the flag, either use 0 for the flags argument, or pass other flags to it without passing this one.
Flags listed below will ONLY work if damage is 0 or higher, and will be ignored if it's negative:
  • XF_NOTMISSILE — Not a missile: if set, the calling actor is considered to be the source. By default, the calling actor is assumed to be a projectile, and the source is therefore considered to be the calling actor's target.
  • XF_EXPLICITDAMAGETYPE — If set, the damagetype parameter will never change to the actor's damage type.
  • XF_NOSPLASH — Disables splash: if set, the explosion does not create any TERRAIN splashes.
  • XF_THRUSTZ — Applies vertical thrust: if set, the attack pushes the victim vertically, in addition to horizontally. Normally, vertical thrust is applied without the need of this flag, but it could be disabled by setting the compat_explode1 compatibility flag. This flag overrides the compatibility flag.
  • XF_THRUSTLESS — The explosion produces no thrust whatsoever, only dealing pure damage. This can be used to supplement the native thrusting with a custom implementation.
  • XF_NOALLIES — The explosion does not affect any actors friendly to the source of the explosion. Only works with FRIENDLY monsters and players. Keep in mind that XF_HURTSOURCE still needs to be off to not affect the source.
  • XF_CIRCULAR — Changes the shape of the explosion from the vanilla cuboid shape into a spherical shape.
  • XF_CIRCULARTHRUST — Blast actors away with more physically accurate momentum. When enabled, XF_THRUSTZ is ignored.
  • bool alert
Whether or not the explosion rings the alarm. This parameter is always set to false if damage is less than 0, regardless of what is passed to it. Default is false.
  • int fulldamagedistance
The area within which full damage is inflicted. Default is 0.
  • int nails
The number of horizontal hitscan attacks performed in a ring, originating from the actor's center. A value of 30 emulates the A_NailBomb function from SMMU, while still allowing to modify all other parameters from A_Explode. Default is 0.
  • int naildamage
The amount of damage inflicted by the nail attack, if any. Default is 10. If nails is 0, this, obviously, has no effect.
  • class<Actor> pufftype
The name of the puff class to use for the nail attack. If nothing is supplied, BulletPuff is used. Default is "BulletPuff".
  • name damagetype
The damage type to use for the damage of this function rather than the actor's own damage type. If left as is without XF_EXPLICITDAMAGETYPE, will use the actor's damage type instead. Default is "none".

Return value

Returns the number of actors damaged. Actors that absorb the damage completely are not counted.

ZScript definition

Note: The ZScript definition below is for reference and may be different in the current version of UZDoom. The most up-to-date version of this code can be found on UZDoom GitHub.
	int A_Explode(int damage = -1, double distance = -1.0, int flags = XF_HURTSOURCE, bool alert = false, double fulldamagedistance = 0.0, int nails = 0, int naildamage = 10, class<Actor> pufftype = "BulletPuff", name damagetype = "none")
	{

		if (damage < 0)	// get parameters from metadata
		{
			damage = ExplosionDamage;
			distance = ExplosionRadius;
			flags = !DontHurtShooter;
			alert = false;
		}
		if (distance <= 0) distance = damage;

		// NailBomb effect, from SMMU but not from its source code: instead it was implemented and
		// generalized from the documentation at http://www.doomworld.com/eternity/engine/codeptrs.html

		if (nails)
		{
			double ang;
			for (int i = 0; i < nails; i++)
			{
				ang = i*360./nails;
				// Comparing the results of a test wad with Eternity, it seems A_NailBomb does not aim
				LineAttack(ang, MISSILERANGE, 0.,
					//P_AimLineAttack (self, ang, MISSILERANGE), 
					naildamage, 'Hitscan', pufftype, bMissile ? LAF_TARGETISSOURCE : 0);
			}
		}

		if (!(flags & XF_EXPLICITDAMAGETYPE) && damagetype == 'None')
		{
			damagetype = self.DamageType;
		}

		int pflags = 0;
		if (flags & XF_HURTSOURCE)	pflags |= RADF_HURTSOURCE;
		if (flags & XF_NOTMISSILE)	pflags |= RADF_SOURCEISSPOT;
		if (flags & XF_THRUSTZ)	pflags |= RADF_THRUSTZ;
		if (flags & XF_THRUSTLESS) pflags |= RADF_THRUSTLESS;
		if (flags & XF_NOALLIES) pflags |= RADF_NOALLIES;
		if (flags & XF_CIRCULAR) pflags |= RADF_CIRCULAR;

		int count = RadiusAttack (target, damage, distance, damagetype, pflags, fulldamagedistance);
		if (!(flags & XF_NOSPLASH)) CheckSplash(distance);
		if (alert && target != NULL && target.player != NULL)
		{
			SoundAlert(target);
		}
		return count;
	}

Examples

This grenades deals less damage than Doom's Rocket but over the same distance:

class MyGrenade : Grenade
{
    Default
    {
        Speed 17;
        BounceFactor 0.4;
        BounceCount 6;
    }

    States
    {
    Death:
        QEX1 A 5 bright
        {
            A_Explode(100, 128);
            A_StartSound("Weapon/GenericExplode", CHAN_WEAPON);
        }
        QEX1 BCDE 5 bright;
        Stop;
    }
}


Whenever this rocket explodes, it logs the number of actors which got damaged by its splash effect.

class SmartRocket : Rocket
{
    States
    {
    Death:
        MISL B 8 Bright A_LogInt(A_Explode);
        Goto Super::Death+1;
    }
}

See also