#include "map.h"

Map::Map()
{
	mainship=0;
	this->DestroyObjects();
}
Map::~Map()
{
	this->DestroyObjects();
}
void Map::Init(float zzoom)
{
	zoom=zzoom;
}
void Map::AddMainShip(Unit *object)
{
	mainship=object;
}
void Map::AddToObjects(MapObject *object)
{
	objects.push_back(object);
}
void Map::AddToStations(Station *object)
{
	stations.push_back(object);
}
void Map::AddToActiveObjects(Unit *object)
{
	actobjects.push_back(object);
}
void Map::RemoveFromActiveObjects(int index)
{
	std::deque<Unit*>::iterator where = std::find(actobjects.begin(), actobjects.end(), actobjects[index]);
	actobjects.erase(where);
}
void Map::AddToShootingObjects(Unit *object, int aishipindex)
{
	MapBullet *bullet=new MapBullet;
	bullet->enemyfire=false;
	bullet->bullet=object;
	bullet->ticks=SDL_GetTicks();
	bullet->target=aishipindex;
	sobjects.push_back(bullet);
}
void Map::AddToAIShootingObjects(Unit *object)
{
	MapBullet *bullet=new MapBullet;
	bullet->enemyfire=true;
	bullet->bullet=object;
	bullet->ticks=SDL_GetTicks();
	bullet->target=-1;
	sobjects.push_back(bullet);
}
void Map::RemoveFromShootingObjects(int index)
{
	std::deque<MapBullet*>::iterator where = std::find(sobjects.begin(), sobjects.end(), sobjects[index]);
	sobjects.erase(where);
}
void Map::DestroyObjects()
{
	units.clear();
	objects.clear();
	stations.clear();
	actobjects.clear();
	sobjects.clear();
	anims.clear();
	activeanims.clear();
}
void Map::DisplayMinimap(int x, int y, int shipx, int shipy, int range)
{
	SDL_Surface *screen=SDL_GetVideoSurface();
	int i, centx, centy, tx, ty;
	Uint8 r, g, b;
	centx=x+30;
	centy=y+30;
	boxRGBA(screen, x, y, x+60, y+60, 128,128,128,164);
	for (i=0; i<(int)objects.size(); i++)
	{
		if (objects[i]->GetX() >= shipx-(range*1000) && objects[i]->GetX() <= shipx+(range*1000) && objects[i]->GetY() >= shipy-(range*1000) && objects[i]->GetY() <= shipy+(range*1000))
		{
			r=objects[i]->GetMMR();
			g=objects[i]->GetMMG();
			b=objects[i]->GetMMB();
			tx=(int)(((objects[i]->GetX()-shipx)/((range*1000)/30))+30+x);
			ty=(int)(((objects[i]->GetY()-shipy)/((range*1000)/30))+30+y);
			boxRGBA(screen, tx-1, ty-1, tx+1, ty+1, r,g,b,255);
		}
	}
	for (i=0; i<(int)stations.size(); i++)
	{
		if (stations[i]->GetX() >= shipx-(range*1000) && stations[i]->GetX() <= shipx+(range*1000) && stations[i]->GetY() >= shipy-(range*1000) && stations[i]->GetY() <= shipy+(range*1000))
		{
			r=stations[i]->GetMMR();
			g=stations[i]->GetMMG();
			b=stations[i]->GetMMB();
			tx=(int)(((stations[i]->GetX()-shipx)/((range*1000)/30))+30+x);
			ty=(int)(((stations[i]->GetY()-shipy)/((range*1000)/30))+30+y);
			boxRGBA(screen, tx-1, ty-1, tx+1, ty+1, r,g,b,255);
		}
	}
	for (i=0; i<(int)actobjects.size(); i++)
	{
		if (actobjects[i]->GetX() >= shipx-(range*1000) && actobjects[i]->GetX() <= shipx+(range*1000) && actobjects[i]->GetY() >= shipy-(range*1000) && actobjects[i]->GetY() <= shipy+(range*1000))
		{
			r=actobjects[i]->GetMMR();
			g=actobjects[i]->GetMMG();
			b=actobjects[i]->GetMMB();
			tx=(int)(((actobjects[i]->GetX()-shipx)/((range*1000)/30))+30+x);
			ty=(int)(((actobjects[i]->GetY()-shipy)/((range*1000)/30))+30+y);
			boxRGBA(screen, tx-1, ty-1, tx+1, ty+1, r,g,b,255);
		}
	}
	for (i=0; i<(int)sobjects.size(); i++)
	{
		if (sobjects[i]->bullet->GetX() >= shipx-(range*1000) && sobjects[i]->bullet->GetX() <= shipx+(range*1000) && sobjects[i]->bullet->GetY() >= shipy-(range*1000) && sobjects[i]->bullet->GetY() <= shipy+(range*1000))
		{
			r=sobjects[i]->bullet->GetMMR();
			g=sobjects[i]->bullet->GetMMG();
			b=sobjects[i]->bullet->GetMMB();
			tx=(int)(((sobjects[i]->bullet->GetX()-shipx)/((range*1000)/30))+30+x);
			ty=(int)(((sobjects[i]->bullet->GetY()-shipy)/((range*1000)/30))+30+y);
			boxRGBA(screen, tx-1, ty-1, tx+1, ty+1, r,g,b,255);
		}
	}
	for (i=0; i<(int)units.size(); i++)
	{
		if (units[i]!=mainship)
		{
			if (units[i]->GetX() >= shipx-(range*1000) && units[i]->GetX() <= shipx+(range*1000) && units[i]->GetY() >= shipy-(range*1000) && units[i]->GetY() <= shipy+(range*1000))
			{
				r=units[i]->GetMMR();
				g=units[i]->GetMMG();
				b=units[i]->GetMMB();
				tx=(int)(((units[i]->GetX()-shipx)/((range*1000)/30))+30+x);
				ty=(int)(((units[i]->GetY()-shipy)/((range*1000)/30))+30+y);
				boxRGBA(screen, tx-1, ty-1, tx+1, ty+1, r,g,b,255);
				if (i==target)
				{
					rectangleRGBA(screen, tx-3, ty-3, tx+3, ty+3, 0, 255, 0, 255);
				}

			}
		}
	}
	boxRGBA(screen, centx-1, centy-1, centx+1, centy+1, 0,0,255,255);
}
void Map::DisplayOnScreenObjects(int x, int y, int w, int h)
{
	SDL_Surface *screen=SDL_GetVideoSurface();
	int i, blitx, blity, scanx, scany;
	blitx=-10000;
	blity=-10000;
	scanx=(int)((w/2)/zoom);
	scany=(int)((h/2)/zoom);
	for (i=0; i<(int)objects.size(); i++)
	{
		if (objects[i]->IsLoaded())
		{
			if (objects[i]->GetX() < (x+scanx+(objects[i]->GetWidth()/2)/zoom) &&
				objects[i]->GetX() > (x-scanx-(objects[i]->GetWidth()/2)/zoom) &&
				objects[i]->GetY() < (y+scany+(objects[i]->GetHeight()/2)/zoom) &&
				objects[i]->GetY() > (y-scany-(objects[i]->GetHeight()/2)/zoom))
			{
				blitx=(int)(((objects[i]->GetX()-(x-scanx))*zoom)-(objects[i]->GetWidth()/2));
				blity=(int)(((objects[i]->GetY()-(y-scany))*zoom)-(objects[i]->GetHeight()/2));
			}
			if (blitx!=-10000 && blity!=-10000)
			{
				objects[i]->Display(blitx, blity);
			}
		}
		blitx=-10000;
		blity=-10000;
	}
	for (i=0; i<(int)stations.size(); i++) {
		if (stations[i]->IsLoaded())
		{
			if (stations[i]->GetX() < (x+scanx+(stations[i]->GetWidth()/2)/zoom) &&
				stations[i]->GetX() > (x-scanx-(stations[i]->GetWidth()/2)/zoom) &&
				stations[i]->GetY() < (y+scany+(stations[i]->GetHeight()/2)/zoom) &&
				stations[i]->GetY() > (y-scany-(stations[i]->GetHeight()/2)/zoom))
			{
				blitx=(int)(((stations[i]->GetX()-(x-scanx))*zoom)-(stations[i]->GetWidth()/2));
				blity=(int)(((stations[i]->GetY()-(y-scany))*zoom)-(stations[i]->GetHeight()/2));
			}
			if (blitx!=-10000 && blity!=-10000)
			{
				stations[i]->Display(blitx, blity);
				if (stations[i]->GetX()-(int)((stations[i]->GetWidth()/2)/zoom)<=mainship->GetX() &&
					stations[i]->GetY()-(int)((stations[i]->GetHeight()/2)/zoom)<=mainship->GetY() &&
					stations[i]->GetX()+(int)((stations[i]->GetWidth()/2)/zoom)>=mainship->GetX() &&
					stations[i]->GetY()+(int)((stations[i]->GetHeight()/2)/zoom)>=mainship->GetY())
				{
					rectangleRGBA(screen, blitx, blity, blitx+stations[i]->GetWidth(), blity+stations[i]->GetHeight(), 255, 255, 255, 255);
				}
			}
		}
		blitx=-10000;
		blity=-10000;
	}
	for (i=0; i<(int)actobjects.size(); i++)
	{
		if (actobjects[i]->IsOrbiter())
		{
			actobjects[i]->Orbit();
		}
		if (actobjects[i]->IsLoaded(actobjects[i]->GetAngle()/5))
		{
			if (actobjects[i]->GetX() < (x+scanx+(actobjects[i]->GetWidth()/2)/zoom) &&
				actobjects[i]->GetX() > (x-scanx-(actobjects[i]->GetWidth()/2)/zoom) &&
				actobjects[i]->GetY() < (y+scany+(actobjects[i]->GetHeight()/2)/zoom) &&
				actobjects[i]->GetY() > (y-scany-(actobjects[i]->GetHeight()/2)/zoom))
			{
				blitx=(int)(((actobjects[i]->GetX()-(x-scanx))*zoom)-(actobjects[i]->GetWidth()/2));
				blity=(int)(((actobjects[i]->GetY()-(y-scany))*zoom)-(actobjects[i]->GetHeight()/2));
			}
			if (blitx!=-10000 && blity!=-10000)
			{
				actobjects[i]->Display(blitx, blity);
			}
		}
		blitx=-10000;
		blity=-10000;
	}
	for (i=0; i<(int)sobjects.size(); i++)
	{
		if (sobjects[i]->bullet->IsLoaded(sobjects[i]->bullet->GetAngle()/5))
		{
			if (sobjects[i]->bullet->GetX() < (x+scanx+(sobjects[i]->bullet->GetWidth()/2)/zoom) &&
				sobjects[i]->bullet->GetX() > (x-scanx-(sobjects[i]->bullet->GetWidth()/2)/zoom) &&
				sobjects[i]->bullet->GetY() < (y+scany+(sobjects[i]->bullet->GetHeight()/2)/zoom) &&
				sobjects[i]->bullet->GetY() > (y-scany-(sobjects[i]->bullet->GetHeight()/2)/zoom))
			{
				blitx=(int)(((sobjects[i]->bullet->GetX()-(x-scanx))*zoom)-(sobjects[i]->bullet->GetWidth()/2));
				blity=(int)(((sobjects[i]->bullet->GetY()-(y-scany))*zoom)-(sobjects[i]->bullet->GetHeight()/2));
			}
			if (blitx!=-10000 && blity!=-10000)
			{
				sobjects[i]->bullet->Display(blitx, blity);
			}
		}
		blitx=-10000;
		blity=-10000;
	}
	for (i=0; i<(int)activeanims.size(); i++)
	{
		if (activeanims[i]->GetCurFrame()!=-1)
		{
			if (activeanims[i]->GetX() < (x+scanx+(activeanims[i]->GetWidth()/2)/zoom) &&
				activeanims[i]->GetX() > (x-scanx-(activeanims[i]->GetWidth()/2)/zoom) &&
				activeanims[i]->GetY() < (y+scany+(activeanims[i]->GetHeight()/2)/zoom) &&
				activeanims[i]->GetY() > (y-scany-(activeanims[i]->GetHeight()/2)/zoom))
			{
				blitx=(int)(((activeanims[i]->GetX()-(x-scanx))*zoom)-(activeanims[i]->GetWidth()/2));
				blity=(int)(((activeanims[i]->GetY()-(y-scany))*zoom)-(activeanims[i]->GetHeight()/2));
			}
			if (blitx!=-10000 && blity!=-10000)
			{
				activeanims[i]->DisplayNext(blitx, blity);
			}
			else activeanims[i]->IncNext();
		}
		if (activeanims[i]->GetCurFrame()==-1)
		{
			this->RemoveFromActiveAnims(i);
		}
		blitx=-10000;
		blity=-10000;
	}
	for (i=0; i<(int)units.size(); i++)
	{
		if (units[i]->IsLoaded(units[i]->GetAngle()/5))
		{
			if (units[i]->GetX() < (x+scanx+(units[i]->GetWidth()/2)/zoom) &&
				units[i]->GetX() > (x-scanx-(units[i]->GetWidth()/2)/zoom) &&
				units[i]->GetY() < (y+scany+(units[i]->GetHeight()/2)/zoom) &&
				units[i]->GetY() > (y-scany-(units[i]->GetHeight()/2)/zoom))
			{
				blitx=(int)(((units[i]->GetX()-(x-scanx))*zoom)-(units[i]->GetWidth()/2));
				blity=(int)(((units[i]->GetY()-(y-scany))*zoom)-(units[i]->GetHeight()/2));
				if (i==target)
				{
					int tgx = (int)(((units[i]->GetX()-(x-scanx))*zoom)-(50*zoom));
					int tgy = (int)(((units[i]->GetY()-(y-scany))*zoom)-(50*zoom));
					rectangleRGBA(screen, tgx, tgy, tgx+(int)(100*zoom), tgy+(int)(100*zoom), 0, 255, 0, 255);
				}
			}
			if (blitx!=-10000 && blity!=-10000)
			{
				units[i]->Display(blitx, blity);
			}
		}
		blitx=-10000;
		blity=-10000;
	}
}
void Map::CheckSectors(int sectorx, int sectory)
{
	int i, objectsx, objectsy, aobjectsx, aobjectsy;
	for (i=0; i<(int)objects.size(); i++)
	{
		objectsx=objects[i]->GetSectorX();
		objectsy=objects[i]->GetSectorY();
		if (objectsx <= sectorx+1 && objectsx >= sectorx-1 && objectsy <= sectory+1 && objectsy >= sectory-1)
		{
			if (!objects[i]->IsLoaded()) { objects[i]->LoadImage(); }
		}
		else
		{
			if (objects[i]->IsLoaded()) { objects[i]->FreeImage(); }
		}
	}
	for (i=0; i<(int)stations.size(); i++)
	{
		objectsx=stations[i]->GetSectorX();
		objectsy=stations[i]->GetSectorY();
		if (objectsx <= sectorx+1 && objectsx >= sectorx-1 && objectsy <= sectory+1 && objectsy >= sectory-1)
		{
			if (!stations[i]->IsLoaded()) { stations[i]->LoadImage(); }
		}
		else
		{
			if (stations[i]->IsLoaded()) { stations[i]->FreeImage(); }
		}
	}
	for (i=0; i<(int)actobjects.size(); i++)
	{
		aobjectsx=actobjects[i]->GetSectorX();
		aobjectsy=actobjects[i]->GetSectorY();
		if (aobjectsx <= sectorx+1 && aobjectsx >= sectorx-1 && aobjectsy <= sectory+1 && aobjectsy >= sectory-1)
		{
			if (!actobjects[i]->IsLoaded(actobjects[i]->GetAngle()/5)) { actobjects[i]->LoadImages(0,71); }
		}
		else
		{
			if (actobjects[i]->IsLoaded(actobjects[i]->GetAngle()/5)) { actobjects[i]->FreeImages(); }
		}
	}
	for (i=0; i<(int)units.size(); i++)
	{
		aobjectsx=units[i]->GetSectorX();
		aobjectsy=units[i]->GetSectorY();
		if ((aobjectsx <= sectorx+1 && aobjectsx >= sectorx-1 && aobjectsy <= sectory+1 && aobjectsy >= sectory-1) || i==target)
		{
			if (!units[i]->IsLoaded(units[i]->GetAngle()/5)) { units[i]->LoadImages(0,71); }
		}
		else
		{
			if (units[i]->IsLoaded(units[i]->GetAngle()/5) && i!=target) { units[i]->FreeImages(); }
		}
	}
}
int Map::CheckCollisions(Unit *a)
{
	int i, x, y;
	bitmask *mask1;
	bitmask *mask2;
	SDL_Rect ar, br;
	bool go;
	mask1=a->mask[a->GetAngle()/5];
	ar.x=(int)(a->GetX()-((a->GetWidth()/2)/a->GetZoom()));
	ar.y=(int)(a->GetY()-((a->GetHeight()/2)/a->GetZoom()));
	ar.w=(int)(a->GetWidth()/a->GetZoom());
	ar.h=(int)(a->GetHeight()/a->GetZoom());
	for (i=0; i<(int)actobjects.size(); i++)
	{
		if (actobjects[i]->IsLoaded(actobjects[i]->GetAngle()/5))
		{
			br.x=(int)(actobjects[i]->GetX()-((actobjects[i]->GetWidth()/2)/actobjects[i]->GetZoom()));
			br.y=(int)(actobjects[i]->GetY()-((actobjects[i]->GetHeight()/2)/actobjects[i]->GetZoom()));
			br.w=(int)(actobjects[i]->GetWidth()/actobjects[i]->GetZoom());
			br.h=(int)(actobjects[i]->GetHeight()/actobjects[i]->GetZoom());

			go=BoxCollision(br, ar);

			if (go)
			{
				mask2=actobjects[i]->mask[actobjects[i]->GetAngle()/5];
				x=br.x-ar.x;
				y=br.y-ar.y;

				if (bitmask_overlap(mask1,mask2,x,y))
				{
					return i;
				}
			}
		}
	}
	return -1;
}
int Map::CheckUnitCollisions(Unit *a)
{
	int i, x, y;
	bitmask *mask1;
	bitmask *mask2;
	SDL_Rect ar, br;
	bool go;
	mask1=a->mask[a->GetAngle()/5];
	ar.x=(int)(a->GetX()-((a->GetWidth()/2)/a->GetZoom()));
	ar.y=(int)(a->GetY()-((a->GetHeight()/2)/a->GetZoom()));
	ar.w=(int)(a->GetWidth()/a->GetZoom());
	ar.h=(int)(a->GetHeight()/a->GetZoom());
	for (i=0; i<(int)units.size(); i++)
	{
		if (units[i]!=mainship && units[i]->IsLoaded(units[i]->GetAngle()/5))
		{
			br.x=(int)(units[i]->GetX()-((units[i]->GetWidth()/2)/units[i]->GetZoom()));
			br.y=(int)(units[i]->GetY()-((units[i]->GetHeight()/2)/units[i]->GetZoom()));
			br.w=(int)(units[i]->GetWidth()/units[i]->GetZoom());
			br.h=(int)(units[i]->GetHeight()/units[i]->GetZoom());

			go=BoxCollision(br, ar);

			if (go)
			{
				mask2=units[i]->mask[units[i]->GetAngle()/5];
				x=br.x-ar.x;
				y=br.y-ar.y;

				if (bitmask_overlap(mask1,mask2,x,y))
				{
					return i;
				}
			}
		}
	}
	return -1;
}
int Map::CheckShipCollisions(Unit *a)
{
	int x, y;
	bitmask *mask1;
	bitmask *mask2;
	SDL_Rect ar, br;
	bool go;
	mask1=a->mask[a->GetAngle()/5];
	ar.x=(int)(a->GetX()-((a->GetWidth()/2)/a->GetZoom()));
	ar.y=(int)(a->GetY()-((a->GetHeight()/2)/a->GetZoom()));
	ar.w=(int)(a->GetWidth()/a->GetZoom());
	ar.h=(int)(a->GetHeight()/a->GetZoom());
	if (mainship->IsLoaded(mainship->GetAngle()/5))
	{
		br.x=(int)(mainship->GetX()-((mainship->GetWidth()/2)/mainship->GetZoom()));
		br.y=(int)(mainship->GetY()-((mainship->GetHeight()/2)/mainship->GetZoom()));
		br.w=(int)(mainship->GetWidth()/mainship->GetZoom());
		br.h=(int)(mainship->GetHeight()/mainship->GetZoom());

		go=BoxCollision(br, ar);

		if (go)
		{
			if(mainship->HasShield()) mask2=mainship->smask[mainship->GetAngle()/5];
			else mask2=mainship->mask[mainship->GetAngle()/5];
			x=br.x-ar.x;
			y=br.y-ar.y;

			if (bitmask_overlap(mask1,mask2,x,y))
			{
				return 1;
			}
		}
	}
	return 0;
}
void Map::SpawnBullet(int x, int y, int speed, int angle, std::string img, std::string fpk, SDL_Surface *image, int aishipindex, int slotid)
{
	Unit *bullet = new Unit;
	bullet->Init(x,y,img,image,fpk,zoom);
	if (slotid) mainship->ReduceAmmo(slotid);
	Log::WriteVerbose("Bullet spawned and ammo reduced, bay id=%d",slotid);
	bullet->SetSpeed(speed);
	bullet->SetAngle(angle);
	//bullet->SetZoom(zoom);
	//bullet->LoadImages(0,71);
	bullet->SetMMR(255);
	bullet->SetMMG(0);
	bullet->SetMMB(0);
	if (aishipindex!=-1) bullet->SetAI("HEATSEEK");
	this->AddToShootingObjects(bullet, aishipindex);
}
void Map::SpawnAIBullet(int x, int y, int speed, int angle, std::string img, std::string fpk, SDL_Surface *image, bool target)
{
	if (image)
	{
		Unit *bullet = new Unit;
		bullet->Init(x,y,img,image,fpk,zoom);
		bullet->SetSpeed(speed);
		bullet->SetAngle(angle);
		//bullet->SetZoom(zoom);
		//bullet->LoadImages(0,71);
		bullet->SetMMR(255);
		bullet->SetMMG(0);
		bullet->SetMMB(0);
		if (target) bullet->SetAI("HEATSEEK");
		this->AddToAIShootingObjects(bullet);
	}
}
void Map::MoveBullets()
{
	int i, obj;
	for (i=0; i<(int)units.size(); i++)
	{
		if (units[i]->IsAIFiring())
		{
			SDL_Surface *aibulletimg=units[i]->GetCurWeaponSlot().image;
			if(aibulletimg)
			{
				Mix_PlayChannel(0,shot,0);
				this->SpawnAIBullet(units[i]->GetShootX(),units[i]->GetShootY(),units[i]->GetSpeed()+11,units[i]->GetAngle(),"gfx/object/bullet.png","base.fpk",aibulletimg);
			}
		}
	}
	for (i=0; i<(int)sobjects.size(); i++)
	{
		if (SDL_GetTicks()>=sobjects[i]->ticks+5000)
		{
			this->RemoveFromShootingObjects(i);
		}
	}
	i=0;
	while(i<(int)sobjects.size())
	{
		obj = this->CheckCollisions(sobjects[i]->bullet);
		if (obj!=-1 && !sobjects[i]->enemyfire)
		{
			if (!strcmp(actobjects[obj]->GetName().c_str(),"asteroid"))
			{
				this->SpawnAnim(0,actobjects[obj]->GetX(), actobjects[obj]->GetY());
				Mix_PlayChannel(1,explode,0);
				mainship->SetCredits(mainship->GetCredits()+actobjects[obj]->GetCredits());
				this->RemoveFromActiveObjects(obj);
				this->RemoveFromShootingObjects(i);
				break;
			}
		}
		obj = this->CheckUnitCollisions(sobjects[i]->bullet);
		if (obj!=-1 && !sobjects[i]->enemyfire)
		{
			this->RemoveFromShootingObjects(i);
			units[obj]->Hit();
			if (units[obj]->GetHullHits()>=units[obj]->GetMaxHullHits())
			{
				this->SpawnAnim(0,units[obj]->GetX(), units[obj]->GetY());
				Mix_PlayChannel(1,explode,0);
				mainship->SetCredits(mainship->GetCredits()+units[obj]->GetCredits());
				this->RemoveFromUnits(obj);
				break;
			}
		}
		obj = this->CheckShipCollisions(sobjects[i]->bullet);
		if (obj && sobjects[i]->enemyfire)
		{
			mainship->Hit();
			this->RemoveFromShootingObjects(i);
			if (mainship->GetHullHits()==mainship->GetMaxHullHits())
			{
				this->SpawnAnim(0,mainship->GetX(), mainship->GetY());
				Mix_PlayChannel(1,explode,0);
				break;
			}
			break;
		}
		i++;
	}
	for (i=0; i<(int)sobjects.size(); i++)
	{
		int tx=0;
		int ty=0;
		if (sobjects[i]->target!=-1)
		{
			tx=units[sobjects[i]->target]->GetX();
			ty=units[sobjects[i]->target]->GetY();
			sobjects[i]->bullet->Move(tx,ty);
		}
		else if (sobjects[i]->enemyfire) sobjects[i]->bullet->Move(mainship->GetX(),mainship->GetY());
	}
}
void Map::MoveAI(int sx, int sy)
{
	int i;
	for(i=0; i<(int)units.size(); i++)
	{
		if (units[i]!=mainship) units[i]->Move(sx,sy);
	}
}
void Map::SetZoom(float szoom)
{
	int i;
	zoom=szoom;
	for (i=0; i<(int)objects.size(); i++)
	{
		objects[i]->SetZoom(zoom);
		if (objects[i]->IsLoaded()) objects[i]->LoadImage();
	}
	for (i=0; i<(int)stations.size(); i++)
	{
		stations[i]->SetZoom(zoom);
		if (stations[i]->IsLoaded()) stations[i]->LoadImage();
	}
	for (i=0; i<(int)actobjects.size(); i++)
	{
		actobjects[i]->SetZoom(zoom);
		if (actobjects[i]->IsLoaded(actobjects[i]->GetAngle()/5)) actobjects[i]->ReloadImages();
	}
	for (i=0; i<(int)sobjects.size(); i++)
	{
		sobjects[i]->bullet->SetZoom(zoom);
		sobjects[i]->bullet->ReloadImages();
	}
	for (i=0; i<(int)anims.size(); i++)
	{
		anims[i]->SetZoom(zoom);
		anims[i]->LoadFrames(anims[i]->GetBase());
	}
	for (i=0; i<(int)activeanims.size(); i++)
	{
		activeanims[i]->SetZoom(zoom);
		activeanims[i]->LoadFrames(activeanims[i]->GetBase());
	}
	for (i=0; i<(int)units.size(); i++)
	{
		units[i]->SetZoom(zoom);
		if (units[i]->IsLoaded(units[i]->GetAngle()/5)) units[i]->ReloadImages();
	}
}
void Map::AddToAnimations(StaticAnim *anim)
{
	if (zoom!=1)
	{
		anim->SetZoom(zoom);
		anim->LoadFrames(anim->GetBase());
	}
	anims.push_back(anim);
}
void Map::RemoveFromActiveAnims(int index)
{
	std::deque<StaticAnim*>::iterator where = std::find(activeanims.begin(), activeanims.end(), activeanims[index]);
	activeanims.erase(where);
}
void Map::AddToUnits(Unit *unit)
{
	unit->SetZoom(zoom);
	units.push_back(unit);
}
void Map::RemoveFromUnits(int index)
{
	std::deque<Unit*>::iterator where = std::find(units.begin(), units.end(), units[index]);
	units.erase(where);
}
void Map::SpawnAnim(int index, int x, int y)
{
	StaticAnim *anim=new StaticAnim(*anims[index]);
	anim->SetX(x);
	anim->SetY(y);
	activeanims.push_back(anim);
}
int Map::GetUnitX(int index)
{
	return units[index]->GetX();
}
int Map::GetUnitY(int index)
{
	return units[index]->GetY();
}
void Map::SetTarget(int index)
{
	target=index;
}
void Map::DisplayAITarget(int sx, int sy, int sw, int sh, TTF_Font *font, int targetx, int targety)
{
	SDL_Color white = { 0xFF, 0xFF, 0xFF, 0 };
	SDL_Surface *screen=SDL_GetVideoSurface();
	char disp[300];
	boxRGBA(screen, sx, sy, sx+sw, sy+sh, 128,128,128,164);
	sprintf(disp, "Target Sector: (%d,%d)", (int)targetx/1000, (int)targety/1000);
	drawString(font, sx+5, sy, disp, white);
	if (target!=-1)
	{
		int shipx=sx+((sw-units[target]->GetDispImageW())/2);
		int shipy=sy+((sh-units[target]->GetDispImageH())/2);
		units[target]->DisplayDispImage(shipx,shipy);
	}
	else centerString(font, sx+(sw/2), sy+(sh/2), "No Target", white);
}
int Map::GetUnitImageW(int index)
{
	return units[index]->GetDispImageW();
}
int Map::GetUnitImageH(int index)
{
	return units[index]->GetDispImageH();
}
void Map::Dock(int x, int y)
{
	int i;
	for (i=0; i<(int)stations.size(); i++)
	{
		if (stations[i]->IsLoaded())
		{
			if (stations[i]->GetX()-(int)((stations[i]->GetWidth()/2)/zoom)<=x &&
				stations[i]->GetY()-(int)((stations[i]->GetHeight()/2)/zoom)<=y &&
				stations[i]->GetX()+(int)((stations[i]->GetWidth()/2)/zoom)>=x &&
				stations[i]->GetY()+(int)((stations[i]->GetHeight()/2)/zoom)>=y)
			{
				stations[i]->Dock(mainship);
				stations[i]->ChangeSupply();
			}
		}
	}
}
int Map::GetObjCount()
{
	return (int)objects.size();
}
int Map::GetUnitCount()
{
	int retval=(int)units.size();
	if (mainship) retval--;
	return retval;
}
void Map::SendPauseTime(Uint32 time)
{
	int i;
	for (i=0; i<(int)stations.size(); i++)
	{
		stations[i]->AddToWaitTime(time);
	}
	for (i=0; i<(int)sobjects.size(); i++)
	{
		sobjects[i]->ticks+=time;
	}
}
