void CProjectileHandler::DrawProjectiles(const ProjectileContainer& pc, bool drawReflection, bool drawRefraction) {
	for (ProjectileContainer::render_iterator pci = pc.render_begin(); pci != pc.render_end(); ++pci) {
		CProjectile* pro = *pci;

		pro->UpdateDrawPos();

		if (camera->InView(pro->pos, pro->drawRadius) && (gu->spectatingFullView || loshandler->InLos(pro, gu->myAllyTeam) ||
			(pro->owner() && teamHandler->Ally(pro->owner()->allyteam, gu->myAllyTeam)))) {

			CUnit* owner = pro->owner();
			bool stunned = owner? owner->stunned: false;

			if (owner && stunned && dynamic_cast<CShieldPartProjectile*>(pro)) {
				// if the unit that fired this projectile is stunned and the projectile
				// forms part of a shield (ie., the unit has a CPlasmaRepulser weapon but
				// cannot fire it), prevent the projectile (shield segment) from being drawn
				//
				// also prevents shields being drawn at unit's pre-pickup position
				// (since CPlasmaRepulser::Update() is responsible for updating
				// CShieldPartProjectile::centerPos) if the unit is in a non-fireplatform
				// transport
				continue;
			}

			if (drawReflection) {
				if (pro->pos.y < -pro->drawRadius)
					continue;

				float dif = pro->pos.y - camera->pos.y;
				float3 zeroPos = camera->pos * (pro->pos.y / dif) + pro->pos * (-camera->pos.y / dif);

				if (ground->GetApproximateHeight(zeroPos.x, zeroPos.z) > 3 + 0.5f * pro->drawRadius)
					continue;
			}

			if (drawRefraction && pro->pos.y > pro->drawRadius)
				continue;

			if (pro->s3domodel) {
				if (pro->s3domodel->type == MODELTYPE_S3O) {
					unitDrawer->QueS3ODraw(pro, pro->s3domodel->textureType);
				} else {
					pro->DrawUnitPart();
				}
			}

			pro->tempdist = pro->pos.dot(camera->forward);
			distset.insert(pro);
		}
	}
}
void CProjectileHandler::DrawProjectilesShadow(const ProjectileContainer& pc) {
	for (ProjectileContainer::render_iterator pci = pc.render_begin(); pci != pc.render_end(); ++pci) {
		CProjectile* p = *pci;

		if ((gu->spectatingFullView || loshandler->InLos(p, gu->myAllyTeam) ||
			(p->owner() && teamHandler->Ally(p->owner()->allyteam, gu->myAllyTeam)))) {

			if (p->s3domodel) {
				p->DrawUnitPart();
			} else if (p->castShadow) {
				p->Draw();
			}
		}
	}
}
void CProjectileHandler::DrawProjectilesMiniMap(const ProjectileContainer& pc) {
	if (pc.render_size() > 0) {
		CVertexArray* lines = GetVertexArray();
		CVertexArray* points = GetVertexArray();

		lines->Initialize();
		lines->EnlargeArrays(pc.render_size() * 2, 0, VA_SIZE_C);

		points->Initialize();
		points->EnlargeArrays(pc.render_size(), 0, VA_SIZE_C);

		for (ProjectileContainer::render_iterator pci = pc.render_begin(); pci != pc.render_end(); ++pci) {
			CProjectile* p = *pci;

			if ((p->owner() && (p->owner()->allyteam == gu->myAllyTeam)) ||
				gu->spectatingFullView || loshandler->InLos(p, gu->myAllyTeam)) {
				p->DrawOnMinimap(*lines, *points);
			}
		}

		lines->DrawArrayC(GL_LINES);
		points->DrawArrayC(GL_POINTS);
	}
}