Classes:BlockThingsIterator

From ZDoom Wiki
(Redirected from BlockThingsIterator)
Jump to navigation Jump to search
Note: This feature is for ZScript only.


BlockThingsIterator is a type of iterator used to search for entities that are within the Blockmap. This excludes all actors with the NOBLOCKMAP flag. Any Actor in a blockmap square within the provided radius is taken, so this does not guarantee they are at radius distance or lower (manual checking will have to be done if a strict distance is necessary). Generally they are best used for getting surrounding Actors within a small area as opposed to every Actor.

Members

Type Variables Use
Actor thing The Actor the iterator is currently checking.
Vector3 position The xy map position for the origin of the check relative to the Actor. The z value is the radius that was given
int portalflags Used to signify what Portal-related flags were used when getting the Actor.

Functions

Return Type Function Arguments (first to last) Use/Arguments
BlockThingsIterator Create
  1. Actor origin,
  2. double checkradius = -1,
  3. bool ignorerestricted = false

Initializes the iterator upon a pointer. Either this or CreateFromPos can be used.

  • origin - A pointer to an Actor to perform the search upon. To perform it on the calling actor, self can be used.
  • checkradius - The radius to search. Default is -1, interpreted as "use the pointer's radius".
  • ignorerestricted - Does nothing.

Note: this function is static and should be called off the class name, i.e. BlockThingsIterator.Create(...).

BlockThingsIterator CreateFromPos
  1. double checkx,
  2. double checky,
  3. double checkz,
  4. double checkh,
  5. double checkradius,
  6. bool ignorerestricted

Initializes the iterator upon a vector. Either this or Create can be used.

  • check-x/y/z - The map coordinates to set the origin of the search to.
  • checkh - The height to use for the origin point. Important for getting correct portal information.
  • checkradius - The radius to search from the origin.
  • ignorerestricted - Does nothing.

Note: this function is static and should be called off the class name, i.e. BlockThingsIterator.CreateFromPos(...).

bool Next None Iterates through the list of found Actors. Returns false when at the end of the list.

Examples

This function returns how many solid Actors there are within rad distance.

int CountPotentialBlockers(double rad)
{
   // Create the iterator
   BlockThingsIterator it = BlockThingsIterator.Create(self, rad);
   Actor mo;
   int blockers;

   while (it.Next())
   {
       mo = it.thing; // Get the Actor it's currently on
       if (!mo || !mo.bSolid || Distance2D(mo) > rad)
           continue;

       ++blockers;
   }

   return blockers;
}

This is a more detailed example: this projectile (reusing Cell sprites) explodes like a Rocket when hitting a bleeding actor (by entering its XDeath state sequence), but if it falls on the floor, it'll function as a proximity mine that can be activated by either players or monsters (aside from the projectile's target, i.e. whoever fired it):

class ProximityMineProjectile : Actor
{
	// This will the mine's activation radius:
	const DETECTRADIUS = 160;
	

	Default
	{
		// This turns the green lights on the cell pack red:
		Translation "117:117=176:176";
		Projectile;
		-NOGRAVITY;
		gravity 0.6;
		speed 15;
	}
	
	States 
	{
	Spawn:
		CELL A -1;
		stop;
	Death:
		CELL A 1
		{
		
			// Create an iterator to cover the effective radius:
			BlockThingsIterator it = BlockThingsIterator.Create(self, DETECTRADIUS);
			while (it.Next())
			{
				// Get a shorter pointer to the found actor (for convenience):
				let obj = it.thing;
				
				// Check the object is either a monster or a player, isn't the same
				// as the projectile's target (so that the shooter can't trigger it),
				// then checks that it's alive and within distance:
				if ((obj.bISMONSTER || obj.player) && (!target || obj != target) && obj.health > 0 && Distance3D(obj) <= DETECTRADIUS)
				{
					// Go to the Boom state sequence if the check passes:
					return ResolveState("Detected");
				}
			}
			
			// Once a second it'll play a DSTINK sound to emulate beeping:
			if (GetAge() % 35 == 0)
			{
				A_StartSound("misc/chat2", volume: 0.4, attenuation: 5);
			}
			
			// If the jump didn't happen, proceed to loop:
			return ResolveState(null);
		}
		loop;
	Detected:
		// Make the mine jump up as a visual cue,
		// then proceed to the explosion sequence:
		CELL A 8 { vel.z += 8; }
	XDeath:
		TNT1 A 0 
		{
			// Enable NOGRAVITY so that the explosion animation
			// isn't subjected to gravity:
			bNOGRAVITY = true;
			// Play the Rocket explosion sound:
			A_StartSound("weapons/rocklx");
			// Explode; explosion distance is slightly larger
			// than the detection radius:
			A_Explode(192, DETECTRADIUS * 1.2);
		}
		// Reused rocket explosion sprites:
		MISL BCD 4 bright;
		stop;
	}
}

See Also