BlockThingsIterator
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.
Note: This feature is for ZScript only. |
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 |
|
Initializes the iterator upon a pointer. Either this or CreateFromPos can be used.
Note: this function is static and should be called off the class name, i.e. BlockThingsIterator.Create(...). |
BlockThingsIterator | CreateFromPos |
|
Initializes the iterator upon a vector. Either this or Create can be used.
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;
}
}