#include "Gameplay.h"

//screen aprx. size x: -0.8 0.8
//screen aprx. size y: 0.43 -0.43

extern void SaveBestScore();

extern unsigned int counter;
extern Snd *pShot, *pBang, *pBoom, *pDie, *pPixel, *pVoxel;

int lives = 0, score = 0, health = 2, voxel_counter;
unsigned int shotp, tmp_counter, weapon;

float px, py;

enum EGO_TYPE {GO_WAVE, GO_CLOUD, GO_BULLET, GO_EXPLO, GO_SMOKE, GO_ISKRY, GO_LIFE, GO_WEAPON, GO_FALLING_VOX, GO_SHOOTER_VOX, GO_STUPID_FLY, GO_FLY_MOVE, GO_FLY_SIN, GO_FLY_KAMIKAZE, GO_INFLAME_FLY, GO_ROCKET, GO_ROCKET_AI, GO_VOXEL};

struct TGameObject
{
	EGO_TYPE type;
	float x, y, angle, size;
	unsigned int counter;
	int lives; float scale;
	int some_tmp, some_tmp2;

	TGameObject():counter(0){};
	TGameObject(EGO_TYPE _type, float _x, float _y, float _angle):
	lives(3), counter(0), type(_type), x(_x), y(_y), angle(_angle)
	{
		scale = 1.f + 10.f/(100.f+float(rand()%100));
		switch(type)
		{
			case GO_VOXEL:
				size = 0.1;
				lives = 50;
				break;
			case GO_WAVE:
			case GO_CLOUD:
				size = float(rand()%100)/100.f;
			break;
			case GO_BULLET: size = 0.005; break;
			case GO_INFLAME_FLY: lives = 0;
			case GO_FLY_MOVE:
			case GO_FLY_SIN:
			case GO_FLY_KAMIKAZE:
			case GO_STUPID_FLY: size = 0.03; break;
			case GO_ISKRY: size = 0.01; break;
			case GO_EXPLO: size = 0.1; break;
			case GO_SHOOTER_VOX:
				some_tmp2 = rand()%3;
				lives = 2;
			case GO_FALLING_VOX: 
				size = 0.02; break;
			case GO_LIFE: size = 0.05; break;
			case GO_WEAPON: size = 0.05; break;
			case GO_ROCKET:
			case GO_ROCKET_AI:
				lives = 2;
				size = 0.05;
				break;
			case GO_SMOKE: 
				angle += 35.f - rand()%70;
				size = 0.02; 
				break;
		}
	}
};

std::vector<TGameObject> objects;


void ProcessObjects()
{
	int i = 0, j;
	bool kill_this;
	static std::vector<TGameObject> tmp;

	while(i >= 0 && i < objects.size())
	{
		kill_this = false;
		TGameObject &obj = objects[i];

		switch(obj.type)
		{
			case GO_VOXEL:
				if(obj.lives >= 0)
				{
					if(obj.x > 0.42)
						obj.x -= 0.001;

					if(counter%500 > 200)
						obj.y += sin(counter/2.f)*0.01;

					if(counter%500 < 100)
						obj.y += 0.005;
					else
						if(counter%500 < 200)
							obj.y -= 0.005;

				for(j = 0; j < objects.size(); j++)
				{
					if(obj.x < 0.42 && objects[j].type == GO_BULLET && objects[j].x > 0.3 && objects[j].y < -0.025 && objects[j].y > -0.3)
					{
						tmp.push_back(TGameObject(GO_ISKRY, objects[j].x, objects[j].y, rand()%360));
						objects.erase(objects.begin() + j);
						if(j < i) i--;
						break;
					}

					if(counter%500 < 200 && objects[j].type == GO_BULLET && CheckCollide(objects[j].x, objects[j].y, objects[j].size*0.5, obj.x, obj.y, obj.size*0.5) && (objects[j].angle == 0.f || objects[j].angle == 15.f || objects[j].angle == -15.f))
					{
						obj.lives--;
						if(obj.lives < 0)
						{
							score += 10000;
							if(pBoom) pBoom->Play();
							tmp.push_back(TGameObject(GO_EXPLO, obj.x, obj.y + 0.05, rand()%360));
							tmp.push_back(TGameObject(GO_EXPLO, obj.x, obj.y - 0.05, rand()%360));
							tmp.push_back(TGameObject(GO_EXPLO, obj.x, obj.y, rand()%360));
							tmp.push_back(TGameObject(GO_EXPLO, obj.x - 0.05, obj.y, rand()%360));
							tmp.push_back(TGameObject(GO_EXPLO, obj.x + 0.05, obj.y, rand()%360));

							tmp.push_back(TGameObject(GO_FALLING_VOX, obj.x, obj.y + 0.1, 290.f));
							tmp.push_back(TGameObject(GO_FALLING_VOX, obj.x, obj.y - 0.1, 250.f));
							tmp.push_back(TGameObject(GO_FALLING_VOX, obj.x, obj.y, 270.f));
							tmp.push_back(TGameObject(GO_FALLING_VOX, obj.x - 0.1, obj.y, 280.f));
							tmp.push_back(TGameObject(GO_FALLING_VOX, obj.x + 0.1, obj.y, 260.f));
							voxel_counter = 1;
						}
						else
							tmp.push_back(TGameObject(GO_ISKRY, objects[j].x, objects[j].y, rand()%360));
						objects.erase(objects.begin() + j);
						if(j < i) i--;
					}
				}
				}
			break;
			case GO_WAVE:
				obj.x -= 0.001 - obj.y/100.f;
			break;
			case GO_CLOUD:
				obj.x -= 0.0025*obj.size;
			break;
			case GO_ROCKET_AI:
				if(obj.x > -0.325)
					obj.angle= atan2(py - obj.y, px - obj.x)*todeg;
			case GO_ROCKET:
				tmp.push_back(TGameObject(GO_SMOKE, obj.x - cos(obj.angle * torad)*0.04, obj.y - sin(obj.angle * torad)*0.04, -obj.angle));

				obj.x += cos(obj.angle * torad)*0.01;
				obj.y += sin(obj.angle * torad)*0.01;

				for(j = 0; j < objects.size(); j++)
					if(obj.counter > 25 && objects[j].type == GO_BULLET && CheckCollide(objects[j].x, objects[j].y, objects[j].size*0.5, obj.x, obj.y, obj.size) && (objects[j].angle == 0.f || objects[j].angle == 15.f || objects[j].angle == -15.f))
					{
						obj.lives--;
						if(obj.lives <= 0)
						{
							if(pBoom) pBoom->Play();
							tmp.push_back(TGameObject(GO_EXPLO, obj.x, obj.y, rand()%360));
							kill_this = true;
						}
						else
							tmp.push_back(TGameObject(GO_ISKRY, objects[j].x,  objects[j].y, rand()%360));
						objects.erase(objects.begin() + j);
						if(j < i) i--;
					}
				break;
			case GO_BULLET:
				obj.x += cos(obj.angle * torad)*0.01;
				obj.y += sin(obj.angle * torad)*0.01;
				break;
			case GO_SMOKE:
				if(obj.angle != 0.f)
				{
					obj.x += cos(obj.angle * torad)*0.001;
					obj.y += sin(obj.angle * torad)*0.001;
				}
			case GO_EXPLO:
			case GO_ISKRY:
				if(obj.counter > 62) kill_this = true;
				break;
			case GO_FALLING_VOX:
				if(obj.counter > 50)
				{
					obj.x -= 0.001;
					obj.y -= 0.0005;
					obj.angle =270.f + sin((obj.counter-50.f)/50.f)*15.f;
				}
				else
					obj.y -= 0.002;

				if(obj.lives == 0)
					obj.y -= 0.005;
				
			case GO_SHOOTER_VOX:

				if(obj.type == GO_SHOOTER_VOX)
				{
					obj.x -= 0.0007;

					obj.some_tmp = atan2(py - obj.y, px - obj.x)*todeg;
					if(obj.counter !=0 && (obj.counter % 600 == 0 || obj.counter == 200) && obj.lives != 0 && obj.x > -0.05)
					{
						if(pShot) pShot->Play();
						tmp.push_back(TGameObject(GO_BULLET, obj.x - 0.02, obj.y, obj.some_tmp));
					}
				}

				for(j = 0; j < objects.size(); j++)
					if(obj.counter > 25 && obj.lives != 0 && objects[j].type == GO_BULLET && CheckCollide(objects[j].x, objects[j].y, objects[j].size*0.5, obj.x, obj.y, obj.size) && (objects[j].angle == 0.f || objects[j].angle == 15.f || objects[j].angle == -15.f))
					{
						obj.lives--;
						if(obj.lives <= 0 || obj.type == GO_FALLING_VOX)
						{
							if(obj.type == GO_FALLING_VOX) score += 1000; else score += 100;
							obj.lives = 0;
							if(pDie) pDie->Play();
							if(obj.type == GO_FALLING_VOX && (rand()%6 == 3 || (obj.some_tmp == GO_FLY_KAMIKAZE && rand()%2 == 0))) tmp.push_back(TGameObject(GO_LIFE, obj.x, obj.y, 0.f));
							for(int k = 0; k < 6; k++)
								tmp.push_back(TGameObject(GO_ISKRY, objects[j].x + (0.01 - rand()%100/5000.f),  objects[j].y + (0.01 - rand()%100/5000.f), rand()%360));
						}
						else
							tmp.push_back(TGameObject(GO_ISKRY, objects[j].x,  objects[j].y, rand()%360));
						objects.erase(objects.begin() + j);
						if(j < i) i--;
					}

				break;
			case GO_WEAPON:
			case GO_LIFE:
				obj.x -= 0.003;
				break;
			case GO_INFLAME_FLY:
				if(obj.angle < 180.f+60.f) obj.angle += 1.f;

				obj.x += cos(obj.angle * torad)*0.001;
				obj.y += sin(obj.angle * torad)*0.002;

			case GO_FLY_SIN:
				if(obj.type == GO_FLY_SIN)
				{
					obj.angle = 180.f + sin(obj.counter/50.f)*60.f;
					obj.x += cos(obj.angle * torad)*0.003;
					obj.y += sin(obj.angle * torad)*0.003;
				}
			case GO_FLY_KAMIKAZE:
				if(obj.type == GO_FLY_KAMIKAZE && obj.x > -0.25)
				{
					obj.angle= atan2(py - obj.y, px - obj.x)*todeg;
					obj.x += cos(obj.angle * torad)*0.0015;
					obj.y += sin(obj.angle * torad)*0.0015;
				}
			case GO_FLY_MOVE:
				if(obj.type == GO_FLY_MOVE)
				{
					if(obj.counter%200 == 0 || (fabs(py-obj.y) < 0.05 && obj.counter%50 == 0))
					{
						if(rand()%2 == 1)
							obj.some_tmp = 1;
						else
							obj.some_tmp = 2;
					}

					if(obj.counter%200 < 50)
					{
						if(obj.some_tmp == 1)
							obj.y += 0.0025;
						else
							obj.y -= 0.0025;
					}

					obj.x -= 0.001;
				}
			case GO_STUPID_FLY:
				obj.x += cos(obj.angle * torad)*0.001;
				obj.y += sin(obj.angle * torad)*0.001;

				if(obj.type != GO_FLY_SIN && obj.type != GO_INFLAME_FLY && obj.counter != 0 && (obj.counter%200 == 0 || (obj.type >= GO_FLY_MOVE && fabs(py-obj.y) < 0.05 && obj.counter%50 == 0)))
				{
					if(pShot) pShot->Play();
					tmp.push_back(TGameObject(GO_BULLET, obj.x - 0.05, obj.y + 0.02, obj.angle));
					tmp.push_back(TGameObject(GO_BULLET, obj.x - 0.05, obj.y - 0.02, obj.angle));
				}
				
				if(obj.lives <= 1)
				{
					if(counter % 3 == 0)
						tmp.push_back(TGameObject(GO_SMOKE, obj.x, obj.y, -260.f));

					if(rand()%10 == 5)
						tmp.push_back(TGameObject(GO_ISKRY, obj.x, obj.y, rand()%360));
				}

				for(j = 0; j < objects.size(); j++)
					if(obj.counter > 25 && obj.x < 0.8 && j != i && objects[j].type == GO_BULLET && CheckCollide(objects[j].x, objects[j].y, objects[j].size*0.5, obj.x, obj.y, obj.size*0.6) && (objects[j].angle == 0.f || objects[j].angle == 15.f || objects[j].angle == -15.f))
					{
						obj.lives--;
						tmp.push_back(TGameObject(GO_ISKRY, objects[j].x, objects[j].y, rand()%360));
						objects.erase(objects.begin() + j);
						if(j < i) i--;

						if(obj.lives < 0)
						{
							if(pBoom) pBoom->Play();

							if((counter < GAMEPLAY_PART_1 && weapon < 2) || (counter > GAMEPLAY_PART_1 && counter < GAMEPLAY_PART_2 && weapon <= 3) || counter > GAMEPLAY_PART_2)
							if(obj.type != GO_FLY_SIN && ((obj.type <= GO_STUPID_FLY &&  rand()%10 == 5) || (obj.type >= GO_FLY_MOVE &&  rand()%6 == 3))) tmp.push_back(TGameObject(GO_WEAPON, obj.x, obj.y, 0.f));

							tmp.push_back(TGameObject(GO_EXPLO, obj.x, obj.y, rand()%360));
							
							score += 50 + 50 * (GO_STUPID_FLY - obj.type);
							
							if((obj.type != GO_INFLAME_FLY && rand()%6 == 3) || obj.type == GO_FLY_KAMIKAZE)
							{
								tmp.push_back(TGameObject(GO_INFLAME_FLY, obj.x, obj.y, obj.angle));
								tmp.push_back(TGameObject(GO_FALLING_VOX, obj.x, obj.y, 270.f));
								tmp[tmp.size()-1].some_tmp = obj.type - GO_STUPID_FLY;
							}
							
							kill_this = true;
						}
						else
							if(pBang) pBang->Play();
						break;
					}

				break;
		}

		obj.counter++;

		if((obj.type <= GO_CLOUD && (obj.x > 2.f || obj.x < -2.f)) || (obj.type > GO_CLOUD && (obj.x > 0.9 || obj.x < -0.9 || obj.y > 0.53 || obj.y < -0.53 || kill_this)))
		{
			objects.erase(objects.begin() + i);
			continue;
		}

		i++;
	}

	for(i = 0; i < tmp.size(); i++)
		objects.push_back(tmp[i]);

	tmp.clear();
}

void DrawObjects()
{
	for(int i = 0; i < objects.size(); i++)
	{
		const TGameObject &obj = objects[i];
		glPushMatrix();
		glTranslatef(obj.x, obj.y, obj.type <= GO_CLOUD ? -1.f : 0.f);
		glRotatef(obj.angle, 0.f, 0.f, 1.f);
		if(obj.type != GO_WAVE) scale(obj.size);
		
		switch(obj.type)
		{
			case GO_VOXEL:
				if(obj.lives >= 0)
				{
					glPushMatrix();
					glRotatef(-45.f, 0.f, 1.f, 0.f);
					DrawVoxel();
					glPopMatrix();
				}
				glPopMatrix();


				if(obj.lives >= 0)
				{
					glPushMatrix();
					glTranslatef(obj.x, obj.y + 0.085, 0.f);
					scale(obj.size);
					glColor3ub(255, 0, 0);
					glScalef(1.75 - (1.75/50.f)*(50-obj.lives), 0.05, 1.f);
					DrawQuad();
					glPopMatrix();
				}

				glPushMatrix();

				glTranslatef(obj.x, 0.f, -0.07);
				scale(obj.size);
				
				glPushMatrix();
				glTranslatef(-4.f, -8.f, 0.f);
				glColor3ub(0, 255, 0);
				glScalef(7.f, 6.f, 1.f);
				DrawHill();
				glColor3ub(0, 0, 0);
				glTranslatef(0.f, 0.f, 0.05);
				glLineWidth(3.f);
				DrawHill(true);
				glLineWidth(1.f);
				glPopMatrix();

				glPushMatrix();
				glTranslatef(0.3, -2.5f, 0.1f);
				glScalef(2.5, 1.f, 1.f);
				DrawCube();
				glPopMatrix();
				glPushMatrix();
				glTranslatef(-1.1, -1.75, 0.1f);
				glScalef(0.5, 3.f, 1.f);
				DrawCube();
				glPopMatrix();
				glPushMatrix();
				glTranslatef(1.7, -1.75, 0.1f);
				glScalef(0.5, 3.f, 1.f);
				DrawCube();
				glPopMatrix();

				glPushMatrix();
				glTranslatef(1.f, -1.9 + cos(counter/50.f)*0.05, 0.f);
				scale(0.25);
				DrawTexel();
				glPopMatrix();
				break;
			case GO_WAVE:
				glColor3ub(255, 255, 255);
				glTranslatef(0.f, 0.f, 0.5);
				glScalef(0.15*(1.f + obj.y), 0.01*(1.f + obj.y), 1.f);
				DrawQuad();
				break;
			case GO_CLOUD:
				scale(3.f);
				DrawCloud();
				break;
			case GO_BULLET:
				DrawDisc();
				glScalef(2.f, 1.f, 1.f);
				glColor3f(1.f, 1.f, 0.f);
				DrawQuad();
				break;
			case GO_ROCKET_AI:
			case GO_ROCKET:
				scale(5.f);
				DrawRoket();
				break;
			case GO_SHOOTER_VOX:
				if(obj.lives != 0)
					VoxelShooter(obj.some_tmp);

				if(counter <= GAMEPLAY_PART_1)
					DrawKater();
				else
				{
					glTranslatef(0.f, 0.f, -0.25);
					glPushMatrix();
					glTranslatef(-8.f, -10.f, -0.3);
					glColor3ub(0, 255, 0);
					glScalef(12.5f, 10.5, 1.f);
					DrawHill();
					glColor3ub(0, 0, 0);
					glTranslatef(0.f, 0.f, 0.05);
					glLineWidth(3.f);
					DrawHill(true);
					glLineWidth(1.f);
					glPopMatrix();

					if(obj.some_tmp2 == 0)
					{
						glPushMatrix();
						glTranslatef(1.6f, 0.f, 0.f);
						scale(2.f);
						DrawTree();
						glPopMatrix();
					}
					else
						if(obj.some_tmp2 == 1)
						{
							glPushMatrix();
							glTranslatef(-0.6f, -2.f, 0.f);
							DrawRomashka(sin(counter/200.f)*45.f);
							glTranslatef(2.6f, -1.f, 0.f);
							DrawRomashka(sin(counter/200.f)*45.f);
							glTranslatef(-2.f, -2.f, 0.f);
							DrawRomashka(sin(counter/200.f)*45.f);
							glPopMatrix();
						}
				}
				break;

			case GO_FALLING_VOX:
				glRotatef(90.f, 0.f, 0.f, 1.f);
				if(obj.lives > 0)
					DrawMiniVoxel(obj.some_tmp);
				if(obj.lives == 0)
					glTranslatef(-0.55, 3.f, 0.f);				
				else
				{
					if(obj.counter < 50)
						glTranslatef(-0.55 - obj.counter/18.f, 3.f, 0.f);
					else
						glTranslatef(-3.f, 3.f, 0.f);
				}
				scale(3.f);

				if(obj.lives != 0)
				{
					if(obj.counter < 50)
						glScalef(0.5 + obj.counter/50.f, 1.f, 1.f);
					else
						glScalef(1.5, 1.f, 1.f);
				}
				else
					glScalef(0.25, 1.f, 1.f);
				DrawCupol();
				break;

			case GO_INFLAME_FLY:
			case GO_FLY_MOVE:
			case GO_FLY_SIN:
			case GO_FLY_KAMIKAZE:
			case GO_STUPID_FLY:
				DrawEnemyFly(obj.type - GO_STUPID_FLY, obj.type != GO_INFLAME_FLY);
				break;

			case GO_SMOKE:
				glDisable(GL_DEPTH_TEST);
				glEnable(GL_BLEND);
				scale(obj.scale);
				glColor4ub(80 + obj.counter, 80 + obj.counter, 80 + obj.counter, 255 - obj.counter*4);
				DrawDisc();
				glEnable(GL_DEPTH_TEST);
				glDisable(GL_BLEND);
				break;

			case GO_ISKRY:
			case GO_EXPLO:
				glDisable(GL_DEPTH_TEST);
				glEnable(GL_BLEND);
				scale(obj.scale);
				glColor4ub(255, 0, 0, 255 - obj.counter*4);
				DrawBoom();
				glColor4ub(250, 125, 0, 255 - obj.counter*4);
				scale(0.2);
				DrawBoom();
				glEnable(GL_DEPTH_TEST);
				glDisable(GL_BLEND);
				break;
			case GO_WEAPON:
				glColor3ub(0, 255, 0);
				DrawDisc();
				glColor3ub(255, 255, 0);
				glTranslatef(-0.45, -0.05, 0.05);	
				scale(0.12);
				DrawText("WEAPON", 1.f);
				break;
			case GO_LIFE:
				glColor3ub(200, 0, 0);
				DrawDisc();
				glColor3ub(0, 255, 0);
				glTranslatef(-0.3, -0.05, 0.05);	
				scale(0.12);
				DrawText("LIFE", 1.f);
				break;
		}

		glColor4f(1.f, 1.f, 1.f, 1.f);

		glPopMatrix();
	}
}

void StartGameplay()
{
	weapon = 1;
	health = 1;
	objects.clear();
	lives = 3;
	score = 100;
	shotp = 100;
	px = -0.48;
	py = 0.f;
	voxel_counter = 0;
}

void DrawGameplay()
{
	glPushMatrix();
	glTranslatef(0.f, 0.f, -1.f);

	//Map
	glPushMatrix();

	glTranslatef(0.f, 0.f, -0.5);

	if(counter < GAMEPLAY_PART_1 + 300 || counter > GAMEPLAY_PART_2)
	{
		glPushMatrix();

		if(counter > GAMEPLAY_PART_2 + 100)
		{
			if(counter - GAMEPLAY_PART_2 < 200)
				glTranslatef(10.f, -1.1 + (counter - (GAMEPLAY_PART_2 + 100))/500.f, -0.1f);
			else
				glTranslatef(10.f, -1.1 + 100.f/500.f, -0.1f);
		}
		else
		{
			if(counter > GAMEPLAY_PART_1)
				glTranslatef(10.f, -0.4 - (counter - GAMEPLAY_PART_1)/500.f, -0.1f);
			else
				glTranslatef(10.f, -0.4, -0.1f);
		}

		glScalef(30.f, 0.7f, 1.f);
		glBegin(GL_QUADS);
		glColor3ub(44, 34, 242);
		glVertex2f(-0.5, 0.5);
		glVertex2f(0.5, 0.5);
		glColor3ub(13, 89, 255);
		glVertex2f(0.5, -0.5);
		glVertex2f(-0.5, -0.5);
		glVertex2f(0.5, -0.5);
		glVertex2f(-0.5, -0.5);
		glVertex2f(0.5, -15.5);
		glVertex2f(-0.5, -15.5);
		glEnd();
		glPopMatrix();
	}

	if(counter > GAMEPLAY_PART_1 - 300 && counter < GAMEPLAY_PART_2 + 300)
	{
		glPushMatrix();
		if(counter < GAMEPLAY_PART_2)
		{
			if(counter <= GAMEPLAY_PART_1 + 250 )
				glTranslatef(-0.8f, 1.f - (counter - GAMEPLAY_PART_1)/500.f, -0.4f);
			else
				glTranslatef(-0.8f, 1.f - (GAMEPLAY_PART_1 + 250 - GAMEPLAY_PART_1)/500.f, -0.4f);
		}
		else
		{
				glTranslatef(-0.8f, 1.f - (GAMEPLAY_PART_1 + 250 - GAMEPLAY_PART_1)/500.f + (counter - GAMEPLAY_PART_2)/500.f, -0.4f);
		}
		glColor3ub(234, 255, 0);
		glRotatef(sin(counter/200.f)*30.f, 0.f, 0.f, 1.f);
		scale(0.2 + cos(counter/50.f)*0.02f);
		DawSun();
		glPopMatrix();
	}

	glColor3ub(255,255,255);

	glPopMatrix();

	if(lives >= 0 && (health == 0 || health % 5 != 0))
	{
		glPushMatrix();
		glTranslatef(px, py, 0.f);
		scale(0.03);
		DrawPlayer(shotp < 25, shotp < 10);
		glPopMatrix();
	}

	//GameObjects
	DrawObjects();

	glPopMatrix();
}

void ProcessGameplay(bool keys[256])
{
	if(lives >= 0 && voxel_counter == 0)
	{
		if(keys[KEY_UP]) py += 0.003;
		if(keys[KEY_DOWN]) py -= 0.003;

		if(py > 0.365) py = 0.365;
		if(py < -0.395) py = -0.395;

		if(keys[KEY_ACTION] && shotp > 20)
		{
			if(pShot) pShot->Play();

			if(weapon == 1)
			{
				objects.push_back(TGameObject(GO_BULLET, px + 0.055, py - 0.01, 0.f));
				score -= 1;
			}
			else
				if(weapon == 2)
				{
					objects.push_back(TGameObject(GO_BULLET, px + 0.055, py - 0.015, 0.f));
					objects.push_back(TGameObject(GO_BULLET, px + 0.055, py - 0.005, 0.f));
					score -= 2;
				}
				else
				if(weapon == 3)
					{
						objects.push_back(TGameObject(GO_BULLET, px + 0.055, py - 0.01, -15.f));
						objects.push_back(TGameObject(GO_BULLET, px + 0.055, py - 0.01, 0.f));
						objects.push_back(TGameObject(GO_BULLET, px + 0.055, py - 0.01, 15.f));
						score -= 3;
					}
					else
					if(weapon == 4)
						{
							objects.push_back(TGameObject(GO_BULLET, px + 0.055, py - 0.01, -15.f));
							objects.push_back(TGameObject(GO_BULLET, px + 0.055, py - 0.015, 0.f));
							objects.push_back(TGameObject(GO_BULLET, px + 0.055, py - 0.005, 0.f));
							objects.push_back(TGameObject(GO_BULLET, px + 0.055, py - 0.01, 15.f));
							score -= 4;
						}
					else
					if(weapon == 5)
						{
							objects.push_back(TGameObject(GO_BULLET, px + 0.055, py, -15.f));
							objects.push_back(TGameObject(GO_BULLET, px + 0.055, py - 0.01, -15.f));
							objects.push_back(TGameObject(GO_BULLET, px + 0.055, py - 0.015, 0.f));
							objects.push_back(TGameObject(GO_BULLET, px + 0.055, py - 0.005, 0.f));
							objects.push_back(TGameObject(GO_BULLET, px + 0.055, py - 0.01, 15.f));
							objects.push_back(TGameObject(GO_BULLET, px + 0.055, py - 0.02, 15.f));
							score -= 5;
						}

			shotp = 0;
			if(score < 0) score = 0;
		}
		else
			shotp++;

		if(health == 0)
		{
			if(counter % 3 == 0)
				objects.push_back(TGameObject(GO_SMOKE, px, py, -220.f));
			
			if(rand()%10 == 5)
				objects.push_back(TGameObject(GO_ISKRY, px, py, rand()%360));
		}
	}

	if(voxel_counter >= 1)
	{
		voxel_counter++;
		px += voxel_counter/5000.f;
	}

	if(lives >= 0 && voxel_counter == 0)
		for(int i = 0; i < objects.size(); i++)
		{
			if(objects[i].type == GO_LIFE && CheckCollide(objects[i].x, objects[i].y, objects[i].size, px, py, 0.5 * 0.04))
			{
				if(pPixel) pPixel->Play();
				lives++;
				objects.erase(objects.begin() + i);
				break;
			}

			if(objects[i].type == GO_WEAPON && CheckCollide(objects[i].x, objects[i].y, objects[i].size, px, py, 0.5 * 0.04))
			{
				weapon++;
				score += 500;
				if(weapon > 5) weapon = 5;
				objects.erase(objects.begin() + i);
				break;
			}

			if((objects[i].type == GO_BULLET || objects[i].type >= GO_STUPID_FLY) && CheckCollide(objects[i].x, objects[i].y, objects[i].size*0.5, px, py, 0.5 * 0.04) && health <= 1)
			{
				objects.push_back(TGameObject(GO_ISKRY, objects[i].x, objects[i].y, rand()%360));
				
				if(objects[i].type >= GO_STUPID_FLY)
				{
					if(pBoom) pBoom->Play();
					objects.push_back(TGameObject(GO_EXPLO, objects[i].x, objects[i].y, rand()%360));
					health = -1;
				}
				else
				{
					if(pBang) pBang->Play();
					health--;
				}

				objects.erase(objects.begin() + i);

				if(health < 0)
				{
					if(pBoom) pBoom->Play();
					objects.push_back(TGameObject(GO_EXPLO, px, py, rand()%360));
					score -= 1500;
					lives--;
					if(lives >= 0)
					{
						if(counter > GAMEPLAY_PART_1)
							weapon = 2;
						else
							weapon = 1;
						health = 100;
						px = -0.48;
						py = 0.f;
					}
					else
					{
						SaveBestScore();
						tmp_counter = counter;
					}
					if(score < 0) score = 0;
				}
				break;
			}
		}

	if(health > 1) health--;

	if(counter == GAMEPLAY_PART_1 && weapon < 2) weapon = 2;

	if(counter < GAMEPLAY_PART_1)
	{
		if(counter%20 == 0 && counter < GAMEPLAY_PART_1 - 1100)
			objects.push_back(TGameObject(GO_WAVE, 1.9,  -1.f + 0.9*(float(rand()%100)/100.f), 0.f));

		if(rand()%200 == 100 && counter < GAMEPLAY_PART_1 - 1000)
			objects.push_back(TGameObject(GO_CLOUD, 1.9,  0.1 + 0.9*(float(rand()%100)/100.f), 0.f));

		if(counter == 700 || (counter > 800 && counter%250 == 0))
			objects.push_back(TGameObject(GO_STUPID_FLY, 0.8, -0.25 + 0.5*(float(rand()%100)/100.f), 180.f));
		
		if(counter > GAMEPLAY_PART_1/2 && counter%350 == 0)
			objects.push_back(TGameObject(GO_FLY_MOVE, 0.8, -0.25 + 0.5*(float(rand()%100)/100.f), 180.f));
		
		if(counter > GAMEPLAY_PART_1/3 && counter < GAMEPLAY_PART_1 - 2000 && counter % 500 == 0)
			objects.push_back(TGameObject(GO_SHOOTER_VOX, 0.85, -0.35 + 0.2*(float(rand()%100)/100.f), 0.f));

	}
	else
	if(counter < GAMEPLAY_PART_2)
	{
		if(rand()%100 == 50 && counter < GAMEPLAY_PART_1 + (GAMEPLAY_PART_2 - GAMEPLAY_PART_1)/2)
			objects.push_back(TGameObject(GO_CLOUD, 1.9, -0.9 + 1.8*(float(rand()%100)/100.f), 0.f));

		if(counter < GAMEPLAY_PART_1 + (GAMEPLAY_PART_2 - GAMEPLAY_PART_1)/2 && counter%650 == 0)
			objects.push_back(TGameObject(GO_FLY_KAMIKAZE, 0.8, -0.35 + 0.7*(float(rand()%100)/100.f), 180.f));

		if(counter < GAMEPLAY_PART_1 + (GAMEPLAY_PART_2 - GAMEPLAY_PART_1)/2 && counter%250 == 0)
			objects.push_back(TGameObject(GO_FLY_MOVE, 0.8, -0.35 + 0.7*(float(rand()%100)/100.f), 180.f));

		if(counter > GAMEPLAY_PART_1 + (GAMEPLAY_PART_2 - GAMEPLAY_PART_1)/3 && counter % 50 ==0)
			objects.push_back(TGameObject(GO_ROCKET, 0.8, -0.35 + 0.7*(float(rand()%100)/100.f), 180.f));

		if(counter > GAMEPLAY_PART_1 + (GAMEPLAY_PART_2 - GAMEPLAY_PART_1)/2 && counter % 400 < 100 && counter % 10 ==0)
			objects.push_back(TGameObject(GO_FLY_SIN, 0.8, -0.35 + 0.7*(float(rand()%100)/100.f), 180.f));
	}
	else
	if(counter < GAMEPLAY_PART_3)
	{
		if(rand()%200 == 100)
			objects.push_back(TGameObject(GO_CLOUD, 1.9,  0.1 + 0.9*(float(rand()%100)/100.f), 0.f));

		if(counter - GAMEPLAY_PART_2 > 300)
		{
			if(counter%450 == 0 && counter < GAMEPLAY_PART_3 - 1000)
				objects.push_back(TGameObject(GO_SHOOTER_VOX, 0.87, -0.35 + 0.15*(float(rand()%100)/100.f), 0.f));

			if(counter%1000 == 0)
				objects.push_back(TGameObject(GO_FLY_KAMIKAZE, 0.8, -0.25 + 0.4*(float(rand()%100)/100.f), 180.f));

			if(counter%350 == 0)
				objects.push_back(TGameObject(GO_STUPID_FLY, 0.8, -0.25 + 0.5*(float(rand()%100)/100.f), 180.f));

			if(counter%250 == 0)
				objects.push_back(TGameObject(GO_FLY_MOVE, 0.8, -0.25 + 0.4*(float(rand()%100)/100.f), 180.f));

			if(counter%1500 == 0)
			objects.push_back(TGameObject(GO_ROCKET_AI, 0.8, -0.35 + 0.7*(float(rand()%100)/100.f), 180.f));
		}
	}
	else//BOSS
	{
		if(counter == GAMEPLAY_PART_3)
		{
			if(pVoxel) pVoxel->Play();
			objects.push_back(TGameObject(GO_VOXEL, 0.8, -0.1, 0.f));
		}

		if(counter%500 == 250)
			objects.push_back(TGameObject(GO_ROCKET_AI, 0.42, -0.1, 90.f));

		//if(counter%500 == 400)
		//	objects.push_back(TGameObject(GO_FLY_KAMIKAZE, 0.8, -0.25 + 0.4*(float(rand()%100)/100.f), 180.f));

		if(counter%500 > 300 && counter%500 > 400 && counter % 10 ==0)
			objects.push_back(TGameObject(GO_FLY_SIN, 0.8, -0.35 + 0.7*(float(rand()%100)/100.f), 180.f));
	}

	ProcessObjects();
}
