
class RandomTurretsHandler : EventHandler
{

    void setupTurrets(string turretactor, int sk)
    {
	int spawnDist = 128;
	int sectorStart = random[RIDMAP](0,9-sk);
	int sectorStep = random[RIDMAP](1,9-sk);

        for (int i = sectorStart; i < level.sectors.size(); i += sectorStep)
	{
		sectorStep = random[RIDMAP](1,9-sk);

		Sector sec = level.sectors[i];

                Vector2 lowest = (double.infinity, double.infinity);
                Vector2 highest = (-double.infinity, -double.infinity);
                for (int l = 0; l < sec.lines.size(); l++)
		{
                    Vector2 verts[2];
                    verts[0] = sec.lines[l].v1.p;
                    verts[1] = sec.lines[l].v2.p;
                   
                    for (int v = 0; v < 2; v++)
		    {
                        Vector2 vert = verts[v];
                       
                        if (vert.x < lowest.x ) lowest.x  = vert.x;
                        if (vert.y < lowest.y ) lowest.y  = vert.y;
                        if (vert.x > highest.x) highest.x = vert.x;
                        if (vert.y > highest.y) highest.y = vert.y;
                    }
                }
               
		int sectorLimit = random[RIDMAP](0,sk*3);
		int sectorQ = 0;
		int clusterLimit = random[RIDMAP](1,2);
		int clusterQ = 0;
		int spawnStep = random[RIDMAP](1,6);

		if (sectorLimit>0) {
                  Vector2 start = (lowest.x+spawnDist*spawnStep, lowest.y+spawnDist*spawnStep);
                  for (double x = start.x; x < (highest.x-spawnDist); x += spawnDist * spawnStep)
		  {
                    for (double y = start.y; y < (highest.y-spawnDist); y += spawnDist * spawnStep)
		    {
                        if (Level.pointInSector((x, y)) == sec)
			{
                            if (sec.GetTexture(Sector.ceiling) != TexMan.checkForTexture("F_SKY1", TexMan.Type_Any) && sec.GetTexture(Sector.floor) != TexMan.checkForTexture("F_SKY1", TexMan.Type_Any))
			    {
                                let turret = Actor.spawn(turretactor,  (x, y, sec.ceilingPlane.zAtPoint((x, y))));
				turret.SetZ(turret.ceilingz - turret.Height);
				if ( !turret.TestMobjLocation() || (turret.ceilingz - turret.Height - turret.floorz) < 85 ) {
					turret.ClearCounters();
					turret.Destroy();
				} else {
					clusterQ++;
					sectorQ++;
					if(clusterQ==clusterLimit) {
						clusterQ = 0;
						clusterLimit = random[RIDMAP](1,2);
						spawnStep = random[RIDMAP](sectorQ*3,sectorQ*4);
					} else {
						spawnStep = 1;
					}
					if(sectorQ==sectorLimit) {
						x = highest.x;
						y = highest.y;
					}
				}
				turret.A_Explode(1,1,XF_HURTSOURCE|XF_EXPLICITDAMAGETYPE,0,1,0,0,"none","FakeExplosion");
				turret.health = turret.default.health;
                            }
                        }
                    }
                  }
		}
        }

    }
   
    override void worldLoaded(WorldEvent e)
    {
	if( (d3d_enemyrandomtype==0 || d3d_enemyrandomtype==1 || d3d_enemyrandomtype==2) && d3d_enemyrandomprob==100 ) return;

	if (d3d_enemyrandomtype==4 && Level.levelnum%2.0==0) return;

	if(d3d_turret==0) {
		string turretactor = "OrganicTurret";
		int sk = G_SkillPropertyInt(SKILLP_ACSReturn);

		setupTurrets(turretactor, sk);
	}
    }

}