Replace usage of ThinkerIterator and BlockThingsIterator in various places where we can instead loop through sector thing lists.

While in the latter case this may result in longer loops, it also reduces GC thrashing by not needing to allocate an iterator every time.
This also simplifies the DoBlast code as there is no longer a need to manually traverse portals vertically.
This commit is contained in:
Mari the Deer 2023-07-29 13:15:34 +02:00
commit 2bd1cb0657
17 changed files with 113 additions and 220 deletions

View file

@ -111,11 +111,9 @@ Class ParryField : SWWMNonInteractiveActor
}
SetOrigin(SWWMUtility.GetFireOffset(master,20,0,0),false);
let raging = RagekitPower(master.FindInventory("RagekitPower"));
let s = Demolitionist(master).mystats;
let st = Demolitionist(master).mystats;
// check for projectiles to deflect
let ti = ThinkerIterator.Create("Actor");
Actor a;
while ( a = Actor(ti.Next()) )
foreach ( s:level.Sectors ) for ( Actor a=s.thinglist; a; a=a.snext )
{
if ( (justparried.Find(a) < justparried.Size()) || !(SWWMUtility.ValidProjectile(a) || a.bSKULLFLY) || a.bTHRUACTORS || (level.Vec3Diff(a.pos,pos).length() > 80) ) continue;
if ( a is 'Whirlwind' ) SWWMUtility.MarkAchievement("tornado",master.player);
@ -179,13 +177,13 @@ Class ParryField : SWWMNonInteractiveActor
if ( !critsnd )
{
A_StartSound("misc/soulsparry",CHAN_ITEM,CHANF_OVERLAP,1.,.5);
if ( s ) s.pparries++;
if ( st ) st.pparries++;
}
critsnd = true;
if ( (a is 'LostSoul') && (master.player.ReadyWeapon is 'SilverBullet') )
SWWMUtility.MarkAchievement("baseball",master.player);
}
if ( s ) s.parries++;
if ( st ) st.parries++;
SWWMUtility.AchievementProgressInc("parry",1,master.player);
}
if ( --special1 <= 0 ) Destroy();

View file

@ -266,14 +266,18 @@ Class HellblazerMissile : Actor
return;
}
// proximity check
let bt = BlockThingsIterator.Create(self,200);
while ( bt.Next() )
bool checked = false;
foreach ( s:level.Sectors )
{
let t = bt.Thing;
if ( !t || !t.bSHOOTABLE || (!t.bISMONSTER && !(t is 'BossBrain') && !t.player) || (t.Health <= 0) || (target && t.IsFriend(target)) || !SWWMUtility.SphereIntersect(t,level.Vec3Offset(pos,vel),bNOGRAVITY?50:90) || !CheckSight(t,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY) ) continue;
deto++;
tracer = t;
break;
for ( Actor t=s.thinglist; t; t=t.snext )
{
if ( !t.bSHOOTABLE || (!t.bISMONSTER && !(t is 'BossBrain') && !t.player) || (t.Health <= 0) || (target && t.IsFriend(target)) || !SWWMUtility.SphereIntersect(t,level.Vec3Offset(pos,vel),bNOGRAVITY?50:90) || !CheckSight(t,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY) ) continue;
deto++;
tracer = t;
checked = true;
break;
}
if ( checked ) break;
}
}

View file

@ -465,13 +465,11 @@ Class YnykronImpact : SWWMNonInteractiveActor
let s = Spawn("YnykronImpactArm",pos);
s.target = target;
}
let bt = BlockThingsIterator.Create(self,rad+200);
Array<Actor> candidates;
candidates.Clear();
while ( bt.Next() )
foreach ( s:level.Sectors ) for ( Actor t=s.thinglist; t; t=t.snext )
{
let t = bt.Thing;
if ( !t || !t.bSHOOTABLE || !SWWMUtility.SphereIntersect(t,pos,rad) || (!SWWMUtility.SphereIntersect(t,pos,100) && !CheckSight(t,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY)) ) continue;
if ( !t.bSHOOTABLE || !SWWMUtility.SphereIntersect(t,pos,rad) || (!SWWMUtility.SphereIntersect(t,pos,100) && !CheckSight(t,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY)) ) continue;
if ( YnykronShot(master) && (YnykronShot(master).hitlist.Find(t) < YnykronShot(master).hitlist.Size()) )
continue;
Vector3 dirto = level.Vec3Diff(pos,t.Vec3Offset(0,0,t.Height/2));

View file

@ -211,10 +211,8 @@ Class DeepImpact : SWWMWeapon
let p = SWWMPuff.Setup(avgpos,avgdir,invoker,self,l.a);
l.a.DamageMobj(p,self,int(dmg/250.),'Push',DMG_THRUSTLESS|DMG_INFLICTOR_IS_PUFF);
}
let ti = ThinkerIterator.Create("Actor");
Actor m;
let s = Demolitionist(self).mystats;
while ( m = Actor(ti.Next()) )
let st = Demolitionist(self).mystats;
foreach ( s:level.Sectors ) for ( Actor m=s.thinglist; m; m=m.snext )
{
if ( !SWWMUtility.ValidProjectile(m) ) continue;
Vector3 rdir = level.Vec3Diff(origin,m.pos);
@ -235,7 +233,7 @@ Class DeepImpact : SWWMWeapon
pb.AttachToOwner(m);
pb.bAMBUSH = true;
}
if ( s ) s.parries++;
if ( st ) st.parries++;
SWWMUtility.AchievementProgressInc("parry",1,player);
}
int numpt = Random[Impact](7,12);

View file

@ -192,12 +192,10 @@ Class BigBiospark : Actor
if ( !(special2%5) )
{
double closest = double.infinity;
let bt = BlockThingsIterator.Create(self,8000);
while ( bt.Next() )
foreach ( s:level.Sectors ) for ( Actor t=s.thinglist; t; t=t.snext )
{
let t = bt.Thing;
double dist;
if ( !t || !t.bSHOOTABLE || (!t.bISMONSTER && !(t is 'BossBrain') && !t.player) || (t.Health <= 0) || (target && t.IsFriend(target)) || ((dist=Distance3DSquared(t)) > 64000000) || !CheckSight(t,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY) ) continue;
if ( !t.bSHOOTABLE || (!t.bISMONSTER && !(t is 'BossBrain') && !t.player) || (t.Health <= 0) || (target && t.IsFriend(target)) || ((dist=Distance3DSquared(t)) > 64000000) || !CheckSight(t,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY) ) continue;
Vector3 dirto = level.Vec3Diff(pos,t.Vec3Offset(0,0,t.height/2)).unit();
if ( dist > closest ) continue;
closest = dist;
@ -222,11 +220,9 @@ Class BigBiospark : Actor
angle = atan2(dir.y,dir.x);
pitch = asin(-dir.z);
// deal (proper) radius damage
let bt2 = BlockThingsIterator.Create(self,500);
while ( bt2.Next() )
foreach ( s:level.Sectors ) for ( Actor t=s.thinglist; t; t=t.snext )
{
let t = bt2.Thing;
if ( !t || !t.bSHOOTABLE ) continue;
if ( !t.bSHOOTABLE ) continue;
if ( SWWMUtility.SphereIntersect(t,pos,40) )
{
t.DamageMobj(self,target,4+special1,'Biospark');
@ -465,12 +461,10 @@ Class BiosparkBall : Actor
if ( !(special2%5) )
{
double closest = double.infinity;
let bt = BlockThingsIterator.Create(self,500);
while ( bt.Next() )
foreach ( s:level.Sectors ) for ( Actor t=s.thinglist; t; t=t.snext )
{
let t = bt.Thing;
double dist;
if ( !t || !t.bSHOOTABLE || (!t.bISMONSTER && !(t is 'BossBrain') && !t.player) || (t.Health <= 0) || (target && t.IsFriend(target)) || ((dist=Distance3DSquared(t)) > 250000) || !CheckSight(t,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY) ) continue;
if ( !t.bSHOOTABLE || (!t.bISMONSTER && !(t is 'BossBrain') && !t.player) || (t.Health <= 0) || (target && t.IsFriend(target)) || ((dist=Distance3DSquared(t)) > 250000) || !CheckSight(t,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY) ) continue;
Vector3 dirto = level.Vec3Diff(pos,t.Vec3Offset(0,0,t.height/2)).unit();
if ( dir dot dirto < .5 ) continue; // don't seek stuff that's behind us
if ( dist > closest ) continue;
@ -497,13 +491,17 @@ Class BiosparkBall : Actor
return;
}
// proximity check
let bt = BlockThingsIterator.Create(self,100);
while ( bt.Next() )
bool checked = false;
foreach ( s:level.Sectors )
{
let t = bt.Thing;
if ( !t || !t.bSHOOTABLE || (!t.bISMONSTER && !(t is 'BossBrain')) || (t.Health <= 0) || (target && t.IsFriend(target)) || !SWWMUtility.SphereIntersect(t,level.Vec3Offset(pos,vel),16) || !CheckSight(t,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY) ) continue;
deto++;
break;
for ( Actor t=s.thinglist; t; t=t.snext )
{
if ( !t.bSHOOTABLE || (!t.bISMONSTER && !(t is 'BossBrain')) || (t.Health <= 0) || (target && t.IsFriend(target)) || !SWWMUtility.SphereIntersect(t,level.Vec3Offset(pos,vel),16) || !CheckSight(t,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY) ) continue;
deto++;
checked = true;
break;
}
if ( checked ) break;
}
}
override void OnDestroy()
@ -1055,12 +1053,10 @@ Class BiosparkBeam : SWWMNonInteractiveActor
}
nextpos = t.Results.HitPos;
double closest = double.infinity;
let bt = BlockThingsIterator.Create(self,500);
while ( bt.Next() )
foreach ( s:level.Sectors ) for ( Actor t=s.thinglist; t; t=t.snext )
{
let t = bt.Thing;
double dist;
if ( !t || (!(t is 'BiosparkHitbox') && (!t.bSHOOTABLE || (!t.bISMONSTER && !(t is 'BossBrain') && !t.player) || (t.Health <= 0) || (target && t.IsFriend(target)))) || ((dist=Distance3DSquared(t)) > 250000) || !CheckSight(t,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY) ) continue;
if ( (!(t is 'BiosparkHitbox') && (!t.bSHOOTABLE || (!t.bISMONSTER && !(t is 'BossBrain') && !t.player) || (t.Health <= 0) || (target && t.IsFriend(target)))) || ((dist=Distance3DSquared(t)) > 250000) || !CheckSight(t,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY) ) continue;
Vector3 dirto = level.Vec3Diff(nextpos,t.Vec3Offset(0,0,t.height/2));
if ( dir dot dirto < .2 ) continue;
if ( dist > closest ) continue;
@ -1362,12 +1358,10 @@ Class BiosparkArc : SWWMNonInteractiveActor
else
{
double closest = double.infinity;
let bt = BlockThingsIterator.Create(self,1500);
while ( bt.Next() )
foreach ( s:level.Sectors ) for ( Actor t=s.thinglist; t; t=t.snext )
{
let t = bt.Thing;
double dist;
if ( !t || !t.bSHOOTABLE || (!t.bISMONSTER && !(t is 'BossBrain') && !t.player) || (t.Health <= 0) || (target && t.IsFriend(target)) || ((dist=Distance3DSquared(t)) > 2250000) || !CheckSight(t,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY) ) continue;
if ( !t.bSHOOTABLE || (!t.bISMONSTER && !(t is 'BossBrain') && !t.player) || (t.Health <= 0) || (target && t.IsFriend(target)) || ((dist=Distance3DSquared(t)) > 2250000) || !CheckSight(t,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY) ) continue;
Vector3 dirto = level.Vec3Diff(nextpos,t.Vec3Offset(0,0,t.height/2));
if ( dir dot dirto < .2 ) continue;
if ( dist > closest ) continue;

View file

@ -245,15 +245,20 @@ Class ExplodiumMagHitbox : Actor
return;
}
SetOrigin(target.Vec3Offset(0,0,-height*.5),false);
let bt = BlockThingsIterator.Create(self,128);
while ( bt.Next() )
bool breakout = false;
foreach ( s:level.Sectors )
{
if ( !bt.Thing || (bt.Thing == self) || !bt.Thing.bSHOOTABLE || (bt.Thing == target.target) || bt.Thing.IsFriend(target.target) || !SWWMUtility.BoxIntersect(self,bt.Thing) )
continue;
target.bKILLED = true;
target.SetStateLabel("Detonate");
Destroy();
break;
for ( Actor t=s.thinglist; t; t=t.snext )
{
if ( (t == self) || !t.bSHOOTABLE || (t == target.target) || t.IsFriend(target.target) || !SWWMUtility.BoxIntersect(self,t) )
continue;
target.bKILLED = true;
target.SetStateLabel("Detonate");
Destroy();
breakout = true;
break;
}
if ( breakout ) break;
}
}
override int DamageMobj( Actor inflictor, Actor source, int damage, Name mod, int flags, double angle )