Classes:ArtiBlastRadius

From ZDoom Wiki
Jump to navigation Jump to search
Note: Wait! Stop! You do not need to copy this actor's code into your project! Here's why:
  1. This actor is already defined in GZDoom, there's no reason to define it again.
  2. In fact, trying to define an actor with the same name will cause an error (because it already exists).
  3. If you want to make your own version of this actor, use inheritance.
  4. Definitions for existing actors are put on the wiki for reference purpose only.
Disc of Repulsion
Actor type Artifact Game MiniHexenLogoIcon.png (Hexen)
DoomEd Number 10110 Class Name ArtiBlastRadius
Spawn ID 74 Identifier T_ITEMREPULSION


Classes: InventoryCustomInventoryArtiBlastRadius

The disc of repulsion, when used, calls A_Blast, pushing away nearby movable actors, including players, monsters and even projectiles. It can be used to avoid being hit by missiles, push enemies out of the way, throw them in chasms or traps, or even provoke infighting by making them collide another monsters. An actor projected by the disc of repulsion will take damage when colliding with a wall or another actor.

Monsters with the BOSS or DONTBLAST flags are normally unaffected; as well as any actor that isn't a monster, player, or projectile, unless they have the CANBLAST flag. When an actor is affected, a blue ring with a white cross temporarily appears on it to show the disc of repulsion did take effect.

ZScript definition

Note: The ZScript definition below is for reference and may be different in the current version of GZDoom.The most up-to-date version of this code can be found on GZDoom GitHub.
class ArtiBlastRadius : CustomInventory
{
	Default
	{
		+FLOATBOB
		Inventory.DefMaxAmount;
		Inventory.PickupFlash "PickupFlash";
		+INVENTORY.INVBAR +INVENTORY.FANCYPICKUPSOUND
		Inventory.Icon "ARTIBLST";
		Inventory.PickupSound "misc/p_pkup";
		Inventory.PickupMessage "$TXT_ARTIBLASTRADIUS";
		Tag "$TAG_ARTIBLASTRADIUS";
	}
	States
	{
	Spawn:
		BLST ABCDEFGH 4 Bright;
		Loop;
	Use:
		TNT1 A 0 A_Blast;
	}
	
}
//==========================================================================
//
// A_Blast is public to Actor
//
//==========================================================================

extend class Actor
{
	/* For reference, the default values:
	#define BLAST_RADIUS_DIST	255.0
	#define BLAST_SPEED			20.0
	#define BLAST_FULLSTRENGTH	255
	*/

	//==========================================================================
	//
	// AArtiBlastRadius :: BlastActor
	//
	//==========================================================================

	private void BlastActor (Actor victim, double strength, double speed, Class<Actor> blasteffect, bool dontdamage)
	{
		if (!victim.SpecialBlastHandling (self, strength))
		{
			return;
		}

		double ang = AngleTo(victim);
		Vector2 move = AngleToVector(ang, speed);
		victim.Vel.XY = move;

		// Spawn blast puff
		ang -= 180.;
		Vector3 spawnpos = victim.Vec3Offset(
			(victim.radius + 1) * cos(ang),
			(victim.radius + 1) * sin(ang),
			(victim.Height / 2) - victim.Floorclip);
		Actor mo = blasteffect? Spawn (blasteffect, spawnpos, ALLOW_REPLACE) : null;
		if (mo)
		{
			mo.Vel.XY = victim.Vel.XY;
		}
		if (victim.bMissile)
		{
			// [RH] Floor and ceiling huggers should not be blasted vertically.
			if (!victim.bFloorHugger && !victim.bCeilingHugger)
			{
				victim.Vel.Z = 8;
				if (mo != null) mo.Vel.Z = 8;
			}
		}
		else
		{
			victim.Vel.Z = 1000. / victim.Mass;
		}
		if (victim.player)
		{
			// Players handled automatically
		}
		else if (!dontdamage)
		{
			victim.bBlasted = true;
		}
		if (victim.bTouchy)
		{ // Touchy objects die when blasted
			victim.bArmed = false; // Disarm
			victim.DamageMobj(self, self, victim.health, 'Melee', DMG_FORCED|DMG_EXPLOSION);
		}
	}
	
	//==========================================================================
	//
	// AArtiBlastRadius :: Activate
	//
	// Blast all actors away
	//
	//==========================================================================

	action void A_Blast(int blastflags = 0, double strength = 255, double radius = 255, double speed = 20, class<Actor> blasteffect = "BlastEffect", sound blastsound = "BlastRadius")
	{

		if (player && (blastflags & BF_USEAMMO) && invoker == player.ReadyWeapon && stateinfo != null && stateinfo.mStateType == STATE_Psprite)
		{
			Weapon weapon = player.ReadyWeapon;
			if (weapon != null && !weapon.DepleteAmmo(weapon.bAltFire))
			{
				return;
			}
		}

		A_StartSound (blastsound, CHAN_AUTO);

		if (!(blastflags & BF_DONTWARN))
		{
			SoundAlert (self);
		}
		ThinkerIterator it = ThinkerIterator.Create("Actor");
		Actor mo;
		while ( (mo = Actor(it.Next ())) )
		{
			if (mo == self || (mo.bBoss && !(blastflags & BF_AFFECTBOSSES)) || mo.bDormant || mo.bDontBlast)
			{ // Not a valid monster: originator, boss, dormant, or otherwise protected
				continue;
			}
			if (mo.bIceCorpse || mo.bCanBlast)
			{
				// Let these special cases go
			}
			else if (mo.bIsMonster && mo.health <= 0)
			{
				continue;
			}
			else if (!mo.player && !mo.bMissile && !mo.bIsMonster && !mo.bCanBlast && !mo.bTouchy && !mo.bVulnerable)
			{	// Must be monster, player, missile, touchy or vulnerable
				continue;
			}
			if (Distance2D(mo) > radius)
			{ // Out of range
				continue;
			}
			if (mo.CurSector.PortalGroup != CurSector.PortalGroup && !CheckSight(mo))
			{
				// in another region and cannot be seen.
				continue;
			}
			if ((blastflags & BF_ONLYVISIBLETHINGS) && !isVisible(mo, true)) 
			{
				//only blast if target can bee seen by calling actor
				continue;
			}
			BlastActor (mo, strength, speed, blasteffect, !!(blastflags & BF_NOIMPACTDAMAGE));
		}
	}
}

DECORATE definition

Note: This is legacy code, kept for archival purposes only. DECORATE is deprecated in GZDoom and is completely superseded by ZScript. GZDoom internally uses the ZScript definition above.
ACTOR ArtiBlastRadius : CustomInventory
{
  +FLOATBOB
  Inventory.DefMaxAmount
  Inventory.PickupFlash "PickupFlash"
  +INVBAR
  +FANCYPICKUPSOUND
  Inventory.Icon "ARTIBLST"
  Inventory.PickupSound "misc/p_pkup"
  Inventory.PickupMessage "$TXT_ARTIBLASTRADIUS"
  Tag "$TAG_ARTIBLASTRADIUS"
  States
  {
  Spawn:
    BLST ABCDEFGH 4 Bright
    Loop
  Use:
    TNT1 A 0 A_Blast
  }
}