#include "units.h"
#include "gui.h"

Unit::Unit()
{
	Reset();
}
Unit::~Unit()
{
	CleanUp();
}
void Unit::Reset()
{
	int i;
	for (i=0; i<UNITS_NUM_FRAMES; i++)
	{
		mask[i]=0; smask[i]=0; image[i]=0; shield[i]=0;
	}
	dispimg=0;
	for (i=0; i<__MAXSHIPSLOTS; i++)
	{
		slots[i].image=0;
	}
}
void Unit::CleanUp()
{
	int i;
	for (i=0; i<UNITS_NUM_FRAMES; i++)
	{
		if (mask[i]) { bitmask_free(mask[i]); mask[i]=0; }
		if (smask[i]) { bitmask_free(smask[i]); smask[i]=0; }
		if (image[i]) { SDL_FreeSurface(image[i]); image[i]=0; }
		if (shield[i]) { SDL_FreeSurface(shield[i]); shield[i]=0; }
	}
	if (dispimg) { SDL_FreeSurface(dispimg); dispimg=0; }
	for (i=0; i<numslots; i++)
	{
		if (slots[i].image) SDL_FreeSurface(slots[i].image);
	}
	angleinc=5;
	angle=0;
	angle2=0;
	speed=0;
	zoom=1;
	name="";
}
void Unit::Init(int sx, int sy, std::string img, std::string fpk, float zzoom)
{
	int i;
	SDL_Surface *temp;
	angleinc=5;
	angle=0;
	angle2=0;
	speed=0;
	zoom=zzoom;
	name="";
	usingfpk=fpk;
	x=sx;
	y=sy;
	dx=x*1.0;
	dy=y*1.0;
	aiscript="";
	aiwait=SDL_GetTicks();
	aistate=AI_STATE_STOP;
	aiwaitfor=0;
	imgload=img;
	if (!strcmp(usingfpk.c_str()," ")) temp=LoadIMG(imgload);
	else temp=FPK_LoadIMG(usingfpk, imgload);
	dispimg=rotozoomSurface(temp, 0, 0.5, SMOOTH);
	mmr=255;
	mmg=255;
	mmb=0;
	cr=0;
	cg=0;
	cb=0;
	hasShield=false;
	for(i=0; i<UNITS_NUM_FRAMES; i++)
	{
		image[i]=0;
		shield[i]=0;
	}
	for(i=0; i<UNITS_NUM_FRAMES; i++)
	{
		image[i]=rotozoomSurface(temp, 360-i*angleinc, zoom, SMOOTH);
		SDL_Surface *image100=rotozoomSurface(temp, 360-i*angleinc, 1, SMOOTH);
		mask[i]=MakeMask(image100);
		SDL_FreeSurface(image100);
		image100=0;
	}
	warp=false;
	warpenabled=true;
	orbiter=false;
	maxspeed=50;
	maxwarp=50;
	maxsafewarp=50;
	curweapon=0;
	hullhitmax=1;
	shieldhitmax=1;
	numhullhits=0;
	numshieldhits=0;
	aifire=false;
	credits=0;
	origshootx=0;
	origshooty=0;
	this->AdjustShootPoint();
	overheatcount=0;
	overheatmax=1;
	overheatwait=SDL_GetTicks();
	for(i=0; i<__MAXSHIPSLOTS; i++)
	{
		slots[i].image=0;
	}
	this->ZeroSlots();
	cargounits=0;
	cargofill=0;
	SDL_FreeSurface(temp);
}
void Unit::Init(int sx, int sy, std::string img, SDL_Surface *img2, std::string fpk, float zzoom)
{
	int i;
	SDL_Surface *temp;
	angleinc=5;
	angle=0;
	angle2=0;
	speed=0;
	zoom=zzoom;
	name="";
	usingfpk=fpk;
	x=sx;
	y=sy;
	dx=x*1.0;
	dy=y*1.0;
	aiscript="";
	aiwait=SDL_GetTicks();
	aistate=AI_STATE_STOP;
	aiwaitfor=0;
	imgload=img;
	temp=img2;
	dispimg=rotozoomSurface(temp, 0, 0.5, SMOOTH);
	mmr=255;
	mmg=255;
	mmb=0;
	cr=0;
	cg=0;
	cb=0;
	hasShield=false;
	for(i=0; i<UNITS_NUM_FRAMES; i++)
	{
		image[i]=0;
		shield[i]=0;
	}
	for(i=0; i<UNITS_NUM_FRAMES; i++)
	{
		image[i]=rotozoomSurface(temp, 360-i*angleinc, zoom, SMOOTH);
		SDL_Surface *image100=rotozoomSurface(temp, 360-i*angleinc, 1, SMOOTH);
		mask[i]=MakeMask(image100);
		SDL_FreeSurface(image100);
		image100=0;
	}
	warp=false;
	warpenabled=true;
	orbiter=false;
	maxspeed=50;
	maxwarp=50;
	maxsafewarp=50;
	curweapon=0;
	hullhitmax=1;
	shieldhitmax=1;
	numhullhits=0;
	numshieldhits=0;
	aifire=false;
	credits=0;
	origshootx=0;
	origshooty=0;
	this->AdjustShootPoint();
	overheatcount=0;
	overheatmax=1;
	overheatwait=SDL_GetTicks();
	for(i=0; i<__MAXSHIPSLOTS; i++)
	{
		slots[i].image=0;
	}
	this->ZeroSlots();
	cargounits=0;
	cargofill=0;
}
void Unit::Display(int sx, int sy)
{
	int ang;
	ang=(int)angle/angleinc;
	int centx, centy, shx, shy;
	centx=sx+(image[ang]->w/2);
	centy=sy+(image[ang]->h/2);
	DrawIMG(image[ang], sx, sy);
	if (hasShield && shield[ang])
	{
		shx=centx-(shield[ang]->w/2);
		shy=centy-(shield[ang]->h/2);
		DrawIMG(shield[ang], shx, shy);
	}
}
void Unit::StatusDisplay(int sx, int sy, int sw, int sh, TTF_Font *font)
{
	char disp[300];
	SDL_Color white = { 0xFF, 0xFF, 0xFF, 0 };
	SDL_Color red = { 0xFF, 0x88, 0x88, 0 };
	SDL_Surface *screen=SDL_GetVideoSurface();
	//Uint8 r, g, b;
	int shipx, shipy;
	boxRGBA(screen, sx, sy, sx+sw, sy+sh, 128,128,128,164);
	if (!warp) sprintf(disp, "Speed: %d", speed);
	if (warp && speed!=maxwarp) sprintf(disp, "Speed: Warp %.2f", SpeedToFWarp(speed));
	if (warp && speed==maxwarp) sprintf(disp, "Speed: Warp %.1f", SpeedToFWarp(speed));
	if (speed<=maxsafewarp) drawString(font, sx+5, sy, disp, white);
	if (speed>maxsafewarp) drawString(font, sx+5, sy, disp, red);
	sprintf(disp, "Sector: (%d,%d)", (int)x/1000, (int)y/1000);
	drawString(font, sx+5, sy+9, disp, white);
	sprintf(disp, "Credits: %d", credits);
	drawString(font, sx+5, sy+18, disp, white);
	int shieldpercent=(int)((((float)shieldhitmax-numshieldhits)/shieldhitmax)*100);
	if (!hasShield) shieldpercent=0;
	int hullpercent=(int)((((float)hullhitmax-numhullhits)/hullhitmax)*100);
	sprintf(disp, "Shields: %d%%", shieldpercent);
	drawString(font, sx+5, sy+27, disp, white);
	sprintf(disp, "Hull Integrity: %d%%", hullpercent);
	drawString(font, sx+5, sy+36, disp, white);
	int enginetemp=(int)((((float)overheatcount)/overheatmax)*100);
	sprintf(disp, "Engine Temp: %d%%", enginetemp);
	if (enginetemp<50) drawString(font, sx+5, sy+45, disp, white);
	if (enginetemp>=50) drawString(font, sx+5, sy+45, disp, red);
	shipx=sx+((sw-dispimg->w)/2);
	shipy=sy+18+((sh-dispimg->h)/2);
	if (curweapon)
	{
		DrawIMG(this->GetCurWeaponSlot().image, sx+(sw/2)-(this->GetCurWeaponSlot().image->w/2), sy+sh-(this->GetCurWeaponSlot().image->h/2)-18);
		drawString(font, sx+5, sy+sh-25, "Weapon:", white);
		int ammo=this->GetCurWeaponSlot().ammoamount;
		if (ammo)
		{
			sprintf(disp, "Ammo: %d", ammo);
			drawString(font, sx+5, sy+sh-15, disp, white);
		}
	}
	else centerString(font, sx+(sw/2), sy+sh-25, "No Weapon", white);
	DrawIMG(dispimg, shipx, shipy);
}
void Unit::SetSpeed(int sSpeed)
{
	speed=sSpeed;
	if (speed>maxspeed && !warp && !orbiter) speed=maxspeed;
	if (speed>maxwarp && warp && !orbiter) speed=maxwarp;
}
void Unit::SetAngle(int sAngle)
{
	angle=sAngle;
}
void Unit::SetX(int sx)
{
	x=sx;
	dx=x*1.0;
}
void Unit::SetY(int sy)
{
	y=sy;
	dy=y*1.0;
}
void Unit::SetAI(std::string ai)
{
	aiscript=ai;
}
void Unit::SetAIState(int state)
{
	aistate=state;
}
void Unit::Move(int sx, int sy)
{
	double dangle;
	int destangle, dstangle;
	if (!strcmp(aiscript.c_str(),"SIMPLE"))
	{
		dangle=atan2((sy-y),(sx-x));
		destangle=(int)(dangle*(180/PI))+90;
		if (destangle<0) destangle+=360;
		dstangle=destangle-(destangle%5);
		int xd = (sx/1000)-(x/1000);
		int yd = (sy/1000)-(y/1000);
		int distance = (int)sqrt(xd*xd + yd*yd);
		if (Abs((double)distance)>=2 && aistate!=AI_STATE_LOOK) aistate=AI_STATE_WAITLOOK;
		if (SDL_GetTicks()>=aiwait+aiwaitfor)
		{
			switch (aistate)
			{
				case AI_STATE_LOOK:
					if (speed>0) speed-=1;
					else if (speed<0) speed+=1;
					if (dstangle!=angle)
					{
						if (angle<destangle && destangle-angle>=180) this->Rotate(0);
						else if (angle<destangle && destangle-angle>=0) this->Rotate(1);
						else if (angle<destangle && destangle-angle<0) this->Rotate(0);
						else if (angle>destangle && destangle-angle>=-180) this->Rotate(0);
						else if (angle>destangle && destangle-angle<-180) this->Rotate(1);
					}
					aiwaitfor=50;
					aiwait=SDL_GetTicks();
					break;
				case AI_STATE_WAITLOOK:
					if (speed>0) speed-=1;
					else if (speed<0) speed+=1;
					if (dstangle!=angle)
					{
						if (angle<destangle && destangle-angle>=180) this->Rotate(0);
						else if (angle<destangle && destangle-angle>=0) this->Rotate(1);
						else if (angle<destangle && destangle-angle<0) this->Rotate(0);
						else if (angle>destangle && destangle-angle>=-180) this->Rotate(0);
						else if (angle>destangle && destangle-angle<-180) this->Rotate(1);
					}
					if (Abs((double)distance)<=0.5)
					{
						int random=rand()%2;
						if (random) aistate=AI_STATE_ATTACK;
						else aistate=AI_STATE_RUN;
					}
					aiwaitfor=50;
					aiwait=SDL_GetTicks();
					break;
				case AI_STATE_RUN:
					destangle=(destangle+180)%360;
					if (angle<destangle && destangle-angle>=180) this->Rotate(0);
					else if (angle<destangle && destangle-angle>=0) this->Rotate(1);
					else if (angle<destangle && destangle-angle<0) this->Rotate(0);
					else if (angle>destangle && destangle-angle>=-180) this->Rotate(0);
					else if (angle>destangle && destangle-angle<-180) this->Rotate(1);
					if (speed<maxspeed) speed+=1;
					aiwaitfor=200;
					aiwait=SDL_GetTicks();
					break;
				case AI_STATE_ATTACK:
					aiwaitfor=100+rand()%50;
					if (Abs((double)distance)>=0.4 && speed<maxspeed)
					{
						speed+=1;
						aiwaitfor=rand()%50;
					}
					else if (Abs((double)distance)>=2) aistate=AI_STATE_WAITLOOK;
					else if (speed>2 && dstangle==angle) speed-=1;
					else if (speed>1) speed-=1;
					if (dstangle!=angle)
					{
						if (angle<destangle && destangle-angle>=180) this->Rotate(0);
						else if (angle<destangle && destangle-angle>=0) this->Rotate(1);
						else if (angle<destangle && destangle-angle<0) this->Rotate(0);
						else if (angle>destangle && destangle-angle>=-180) this->Rotate(0);
						else if (angle>destangle && destangle-angle<-180) this->Rotate(1);
					}
					if (!(rand()%10) && !aifire) aifire=true;
					aiwait=SDL_GetTicks();
					break;
				default:
					break;
			}
		}
	}
	if (!strcmp(aiscript.c_str(),"HEATSEEK"))
	{
		dangle=atan2((sy-y),(sx-x));
		destangle=(int)(dangle*(180/PI))+90;
		if (destangle<0) destangle+=360;
		dstangle=destangle-(destangle%5);
		if (SDL_GetTicks()>=aiwait+aiwaitfor)
		{
			aiwaitfor=rand()%100;
			if (dstangle!=angle)
			{
				if (angle<destangle && destangle-angle>=180) this->Rotate(0);
				else if (angle<destangle && destangle-angle>=0) this->Rotate(1);
				else if (angle<destangle && destangle-angle<0) this->Rotate(0);
				else if (angle>destangle && destangle-angle>=-180) this->Rotate(0);
				else if (angle>destangle && destangle-angle<-180) this->Rotate(1);
			}
			aiwait=SDL_GetTicks();
		}
	}
	dx+=speed*(sin(angle*(PI/180)));
	dy+=speed*-(cos(angle*(PI/180)));
	if (speed>maxsafewarp)
	{
		if (SDL_GetTicks()>=overheatwait+2000 && overheatcount<overheatmax)
		{
			overheatcount++;
			overheatwait=SDL_GetTicks();
		}
	}
	else if (speed<=maxsafewarp)
	{
		if (SDL_GetTicks()>=overheatwait+2000 && overheatcount>0)
		{
			overheatcount--;
			overheatwait=SDL_GetTicks();
		}
	}
	x=(int)dx;
	y=(int)dy;
}
void Unit::SetMMR(Uint8 sr)
{
	mmr=sr;
}
void Unit::SetMMG(Uint8 sg)
{
	mmg=sg;
}
void Unit::SetMMB(Uint8 sb)
{
	mmb=sb;
}
void Unit::SetWarp(bool sw)
{
	warp=sw;
}
void Unit::SetName(std::string sname)
{
	name=sname;
}
void Unit::SetZoom(float szoom)
{
	zoom=szoom;
}
void Unit::SetMaxSpeed(int ms)
{
	maxspeed=ms;
}
void Unit::SetMaxWarp(int mw)
{
	maxwarp=mw;
}
void Unit::SetMaxSafeWarp(int msw)
{
	maxsafewarp=msw;
}
void Unit::SetTurnDelay(int td)
{
	turndelay=td;
}
void Unit::SetWarpTurnDelay(int tdw)
{
	warpturndelay=tdw;
}
void Unit::SetHullHitMax(int hhm)
{
	hullhitmax=hhm;
}
void Unit::SetShieldHitMax(int shm)
{
	if (hasShield && shield[0]) shieldhitmax=shm;
	else shieldhitmax=0;
}
void Unit::SetOverHeatMax(int ohm)
{
	overheatmax=ohm;
	overheatcount=0;
	overheatwait=SDL_GetTicks();
}
void Unit::SetShootPoint(int sx, int sy)
{
	int tempangle=angle;
	angle=0;
	origshootx=sx-((int)(image[0]->w/zoom)/2);
	origshooty=sy-((int)(image[0]->h/zoom)/2);
	angle=tempangle;
	this->AdjustShootPoint();
}
void Unit::SetCredits(unsigned int cred)
{
	credits=cred;
}
void Unit::SetPriceBought(unsigned int spricebought)
{
	pricebought=spricebought;
}
void Unit::AdjustShootPoint()
{
	double theta=(((angle)*(PI/180))+(atan2(origshooty,origshootx)))-(90*(PI/180));
	int r = (int)sqrt(origshootx*origshootx + origshooty*origshooty);
	shootx = (int)(r*-sin(theta));
	shooty = (int)(r*cos(theta));
}
void Unit::ResetHits()
{
	numhullhits=0;
	numshieldhits=0;
}
void Unit::SetHullHits(int hh)
{
	numhullhits=hh;
}
void Unit::SetShieldHits(int sh)
{
	numshieldhits=sh;
	if (numshieldhits<shieldhitmax) this->AddShield(shieldload);
}
void Unit::PrevWeapon()
{
	int i;
	int cur=-1;
	int oldcur=-1;
	for(i=0; i<numslots; i++)
	{
		if (slots[i].id==curweapon && curweapon) cur=i;
	}
	if (cur==-1) curweapon=0;
	else
	{
		if (cur==0)
		{
			oldcur=cur;
			cur=numslots-1;
		}
		else
		{
			oldcur=cur;
			cur--;
		}
		for(i=cur; i>=0; i--)
		{
			if (slots[i].weaponfull)
			{
				curweapon=slots[i].id;
				break;
			}
			if (i<=0)
			{
				i=numslots;
			}
			if (i==oldcur)
			{
				break;
			}
		}
	}
}
void Unit::NextWeapon()
{
	int i;
	int cur=-1;
	int oldcur=-1;
	for(i=0; i<numslots; i++)
	{
		if (slots[i].id==curweapon && curweapon) cur=i;
	}
	if (cur==-1) curweapon=0;
	else
	{
		if (cur+1>=numslots)
		{
			oldcur=cur;
			cur=0;
		}
		else
		{
			oldcur=cur;
			cur++;
		}
		for(i=cur; i<numslots; i++)
		{
			if (slots[i].weaponfull)
			{
				curweapon=slots[i].id;
				break;
			}
			if (i+1>=numslots)
			{
				i=-1;
			}
			if (i==oldcur)
			{
				break;
			}
		}
	}
}
void Unit::Rotate(int rotation)
{
	if (rotation==1)
	{
		if (angle+angleinc<360)
		{
			angle+=angleinc;
		}
		else
		{
			angle=0;
		}
		this->AdjustShootPoint();
	}
	else
	{
		if (angle-angleinc>=0)
		{
			angle-=angleinc;
		}
		else
		{
			angle=360-angleinc;
		}
		this->AdjustShootPoint();
	}
}
void Unit::EnableWarp()
{
	warpenabled=true;
}
void Unit::DisableWarp()
{
	warpenabled=false;
}
void Unit::AddShield(std::string shieldpic)
{
	int i;
	shieldload=shieldpic;
	hasShield=true;
	hadShield=true;
	SDL_Surface *temp;
	if (!strcmp(usingfpk.c_str()," ")) temp=LoadIMG(shieldpic);
	else temp=FPK_LoadIMG(usingfpk, shieldpic);
	SDL_Surface *temp2;
	for(i=0; i<UNITS_NUM_FRAMES; i++)
	{
		shield[i]=rotozoomSurface(temp, 360-i*angleinc, zoom, SMOOTH);
		temp2=rotozoomSurface(temp, 360-i*angleinc, 1, SMOOTH);
		smask[i]=MakeMask(temp2);
		SDL_FreeSurface(temp2);
		temp2=0;
	}
	SDL_FreeSurface(temp);
	if (temp2) SDL_FreeSurface(temp2);
}
void Unit::AddWeaponToSlot(int slotid, std::string fpk, std::string fn, int amount)
{
	int i;
	for (i=0; i<numslots; i++)
	{
		if (slots[i].id==slotid && (!strcmp(slots[i].type.c_str(),"weapon") || !strcmp(slots[i].type.c_str(),"")))
		{
			slots[i].fpk=fpk;
			slots[i].fn=fn;
			slots[i].fulltype="weapon";
			if (!slots[i].image) slots[i].image=FPK_LoadIMG(slots[i].fpk,slots[i].fn);
			slots[i].full=true;
			slots[i].weaponfull=true;
			if (amount) slots[i].ammoamount+=amount;
			if (slots[i].ammoamount>slots[i].holdamount) slots[i].ammoamount=slots[i].holdamount;
			if (!curweapon) curweapon=slots[i].id;
		}
	}
}
void Unit::RemoveWeaponFromSlot(int slotid)
{
	int i;
	for (i=0; i<numslots; i++)
	{
		if (slots[i].id==slotid && !strcmp(slots[i].fulltype.c_str(),"weapon"))
		{
			slots[i].fpk="";
			slots[i].fn="";
			slots[i].fulltype="";
			SDL_FreeSurface(slots[i].image);
			slots[i].ammoamount=0;
			slots[i].image=0;
			slots[i].weaponfull=false;
		}
	}
}
void Unit::ReduceAmmo(int slotid)
{
	int i, j;
	i=0;
	for(j=0; j<numslots; j++)
	{
		if (slots[j].id==slotid) i=j;
	}
	if (slots[i].ammoamount) slots[i].ammoamount-=1;
	if (slots[i].ammoamount<=0 && slots[i].holdamount)
	{
		this->RemoveWeaponFromSlot(slotid);
		this->NextWeapon();
		Log::WriteVerbose("Removed and changed weapon");
	}
}
void Unit::AddWeaponBayToSlot(int slotid, std::string holdweapon, int holdamount)
{
	int i;
	for (i=0; i<numslots; i++)
	{
		if (slots[i].id==slotid && (!strcmp(slots[i].type.c_str(),"weapon") || !strcmp(slots[i].type.c_str(),"")))
		{
			slots[i].full=true;
			slots[i].weaponfull=false;
			slots[i].fulltype="weapon";
			slots[i].holdweapon=holdweapon;
			slots[i].holdamount=holdamount;
			slots[i].ammoamount=0;
			slots[i].fpk="";
			slots[i].fn="";
		}
	}
}
void Unit::RemoveWeaponBayFromSlot(int slotid)
{
	int i;
	for (i=0; i<numslots; i++)
	{
		if (slots[i].id==slotid && !strcmp(slots[i].fulltype.c_str(),"weapon"))
		{
			slots[i].fpk="";
			slots[i].fn="";
			slots[i].fulltype="";
			if (slots[i].image) SDL_FreeSurface(slots[i].image);
			slots[i].image=0;
			slots[i].full=false;
			slots[i].weaponfull=false;
			slots[i].holdweapon="";
		}
	}
}
void Unit::AddCargoBayToSlot(int slotid, int units)
{
	int i;
	for (i=0; i<numslots; i++)
	{
		if (slots[i].id==slotid && (!strcmp(slots[i].type.c_str(),"cargo") || !strcmp(slots[i].type.c_str(),"")))
		{
			slots[i].full=true;
			slots[i].weaponfull=false;
			slots[i].fulltype="cargo";
			slots[i].fpk="";
			slots[i].fn="";
			slots[i].cargounits=units;
			cargounits+=units;
		}
	}
}
void Unit::RemoveCargoBayFromSlot(int slotid)
{
	int i;
	for (i=0; i<numslots; i++)
	{
		if (slots[i].id==slotid && !strcmp(slots[i].fulltype.c_str(),"cargo"))
		{
			slots[i].fpk="";
			slots[i].fn="";
			slots[i].fulltype="";
			slots[i].full=false;
			cargounits-=slots[i].cargounits;
			slots[i].cargounits=0;
		}
	}
}
void Unit::AddToCargo(__cargo newcargo)
{
	cargo[cargofill].type=newcargo.type;
	cargo[cargofill].priceBought=newcargo.priceBought;
	cargofill++;
	this->SortCargo();
}
void Unit::SortCargo()
{
	int j=1;
	while (j<cargofill)
	{
		__cargo key = cargo[j];
		int i = j - 1;
		while ((i >=0) && (cargo[i].type > key.type))
		{
			cargo[i+1] = cargo[i];
			i = i - 1;
		}
		cargo[i+1] = key;
		j+=1;
	}
}
void Unit::RemoveFromCargo(int cargoindex)
{
	int i;
	for(i=cargoindex; i<cargofill-1; i++)
	{
		cargo[i].type=cargo[i+1].type;
		cargo[i].priceBought=cargo[i+1].priceBought;
	}
	cargofill--;
}
void Unit::RemoveAmountFromCargo(std::string type, int quantity)
{
	int i, j;
	i=0;
	j=0;
	while (i<quantity)
	{
		if (!strcmp(type.c_str(),cargo[j].type.c_str()))
		{
			this->RemoveFromCargo(j);
			i++;
		}
		else j++;
		if (j>cargofill) i=quantity;
	}
}
__ship_slot Unit::GetCurWeaponSlot()
{
	int i;
	int cur=-1;
	for(i=0; i<numslots; i++)
	{
		if (slots[i].id==curweapon && curweapon) cur=i;
	}
	if (cur==-1)
	{
		__ship_slot st;
		st.image=0;
		return st;
	}
	return slots[cur];
}
int Unit::GetWidth()
{
	int ang;
	ang=(int)angle/angleinc;
	if (hasShield) return MAX(image[ang]->w,shield[ang]->w);
	else return image[ang]->w;
}
int Unit::GetHeight()
{
	int ang;
	ang=(int)angle/angleinc;
	if (hasShield) return MAX(image[ang]->h,shield[ang]->h);
	else return image[ang]->h;
}
int Unit::GetImageWidth()
{
	int ang;
	ang=(int)angle/angleinc;
	return image[ang]->w;
}
int Unit::GetImageHeight()
{
	int ang;
	ang=(int)angle/angleinc;
	return image[ang]->h;
}
int Unit::GetDispImageW()
{
	return dispimg->w;
}
int Unit::GetDispImageH()
{
	return dispimg->h;
}
Uint8 Unit::GetMMR()
{
	return mmr;
}
Uint8 Unit::GetMMG()
{
	return mmg;
}
Uint8 Unit::GetMMB()
{
	return mmb;
}
int Unit::GetSpeed()
{
	return speed;
}
int Unit::GetAngle()
{
	return angle;
}
int Unit::GetX()
{
	return x;
}
int Unit::GetY()
{
	return y;
}
double Unit::GetDX()
{
	return dx;
}
double Unit::GetDY()
{
	return dy;
}
int Unit::GetNegX()
{
	return -x;
}
int Unit::GetNegY()
{
	return -y;
}
int Unit::GetSectorX()
{
	return (int)x/1000;
}
int Unit::GetSectorY()
{
	return (int)y/1000;
}
int Unit::GetMaxSpeed()
{
	return maxspeed;
}
int Unit::GetMaxWarp()
{
	return maxwarp;
}
int Unit::GetMaxSafeWarp()
{
	return maxsafewarp;
}
int Unit::GetTurnDelay()
{
	return turndelay;
}
int Unit::GetWarpTurnDelay()
{
	return warpturndelay;
}
int Unit::GetMaxHullHits()
{
	return hullhitmax;
}
int Unit::GetHullHits()
{
	return numhullhits;
}
int Unit::GetMaxShieldHits()
{
	return shieldhitmax;
}
int Unit::GetShieldHits()
{
	return numshieldhits;
}
int Unit::GetShootX()
{
	return shootx+x;
}
int Unit::GetShootY()
{
	return shooty+y;
}
unsigned int Unit::GetCredits()
{
	return credits;
}
unsigned int Unit::GetPriceBought()
{
	return pricebought;
}
int Unit::GetCargoUnits()
{
	return cargounits;
}
int Unit::GetCargoFill()
{
	return cargofill;
}
float Unit::GetZoom()
{
	return zoom;
}
std::string Unit::GetName()
{
	return name;
}
std::string Unit::GetCurWeaponFN()
{
	return curweaponfn;
}
std::string Unit::GetCurWeaponFPK()
{
	return curweaponfpk;
}
bool Unit::AtWarp()
{
	return warp;
}
bool Unit::WarpEnabled()
{
	return warpenabled;
}
bool Unit::HasShield()
{
	return hasShield;
}
void Unit::Hit()
{
	int i;
	if (hasShield) numshieldhits+=1;
	else numhullhits+=1;
	if (numshieldhits>=shieldhitmax)
	{
		for (i=0; i<UNITS_NUM_FRAMES; i++)
		{
			if (hasShield && shield[i])
			{
				SDL_FreeSurface(shield[i]);
				shield[i]=0;
				bitmask_free(smask[i]);
				smask[i]=0;
			}
		}
		hasShield=false;
	}
}
bool Unit::IsAIFiring()
{
	bool temp=aifire;
	aifire=false;
	return temp;
}
bool Unit::IsOverHeated()
{
	if (overheatcount<overheatmax) return false;
	else return true;
}
void Unit::Orbit()
{
	double xloc, yloc, ts, factor;
	ts=(double)speed;
	factor=ts/radius;
	if (angle2+factor>=360) {angle2=angle2+factor-360;}
	else {angle2+=factor;}
	xloc = orbitx + radius*cos(angle2);
	yloc = orbity + radius*sin(angle2);
	x=(int)xloc;
	y=(int)yloc;
	if (angle+angleinc<360) { angle+=angleinc; }
	else { angle=0; }
}
void Unit::Orbit(int sx, int sy, int rad)
{
	angle2=rand()%360;
	double xloc, yloc, ts, factor;
	orbitx=sx;
	orbity=sy;
	radius=rad;
	ts=(double)speed;
	factor=ts/radius;
	if (angle2+factor>=360) {angle2=angle2+factor-360;}
	else {angle2+=factor;}
	xloc = orbitx + radius*cos(angle2);
	yloc = orbity + radius*sin(angle2);
	x=(int)xloc;
	y=(int)yloc;
}
void Unit::SetOrbit(bool orbit)
{
	orbiter=orbit;
}
bool Unit::IsOrbiter()
{
	return orbiter;
}
void Unit::FreeImages()
{
	int i;
	for (i=0; i<UNITS_NUM_FRAMES; i++)
	{
		if (image[i])
		{
			SDL_FreeSurface(image[i]);
			image[i]=0;
		}
		if (shield[i])
		{
			SDL_FreeSurface(shield[i]);
			shield[i]=0;
		}
		if (dispimg)
		{
			SDL_FreeSurface(dispimg);
			dispimg=0;
		}
	}
}
void Unit::FPK_NewImages(std::string fpk, std::string imagename)
{
	Log::WriteVerbose("FPK_NewImages: Loading new image (%s) from fpk %s",imagename.c_str(),fpk.c_str());
	usingfpk=fpk;
	imgload=imagename;
	Log::WriteVerbose("FPK_NewImages: Freeing existing images");
	FreeImages();
	if(hasShield)
	{
		int i;
		for(i=0; i<UNITS_NUM_FRAMES; i++)
		{
			bitmask_free(smask[i]);
			smask[i]=0;
		}
		hasShield=false;
	}
	Log::WriteVerbose("FPK_NewImages: Loading new images");
	LoadImages(0, 71);
	int i;
	Log::WriteVerbose("FPK_NewImages: Making new bitmasks");
	for (i=0; i<UNITS_NUM_FRAMES; i++)
	{
		bitmask_free(mask[i]);
		mask[i]=0;
		mask[i]=MakeMask(image[i]);
	}
}
void Unit::ReloadImages()
{
	LoadImages(0,71);
}
void Unit::LoadImages(int start, int end)
{
	int i;
	SDL_Surface *temp;
	if (end>71) { end=71; }
	if (start>71) { start=71; }
	if (end<0) { end=0; }
	if (start<0) { start=0; }
	Log::WriteVerbose("Unit::LoadImages: Loading base image (%s) from fpk %s",imgload.c_str(),usingfpk.c_str());
	temp=FPK_LoadIMG(usingfpk, imgload);
	if (dispimg)
	{
		SDL_FreeSurface(dispimg);
		dispimg=0;
	}
	Log::WriteVerbose("Unit::LoadImages: Setting display image");
	dispimg=rotozoomSurface(temp, 0, 0.5, SMOOTH);
	if (cr>0 || cg>0 || cb>0)
	{
		Log::WriteVerbose("Unit::LoadImages: Colorizing images");
		ColorizeSurface(temp, cr, cg, cb);
		ColorizeSurface(dispimg, cr, cg, cb);
	}
	Log::WriteVerbosen("Unit::LoadImages: Freeing images and reloading: ");
	for (i=start; i<=end; i++)
	{
		Log::WriteVerbosen("%d, ",i);
		if (image[i])
		{
			SDL_FreeSurface(image[i]);
			image[i]=0;
		}
		image[i]=rotozoomSurface(temp, 360-i*angleinc, zoom, SMOOTH);
	}
	Log::WriteVerbosen("\n");
	if (hasShield)
	{
		Log::WriteVerbose("Loading shield");
		SDL_FreeSurface(temp);
		temp=0;
		if (!strcmp(usingfpk.c_str()," ")) temp=LoadIMG(shieldload);
		else temp=FPK_LoadIMG(usingfpk, shieldload);
		for (i=start; i<=end; i++)
		{
			if (shield[i])
			{
				SDL_FreeSurface(shield[i]);
				shield[i]=0;
			}
			shield[i]=rotozoomSurface(temp, 360-i*angleinc, zoom, SMOOTH);
		}
	}
	SDL_FreeSurface(temp);
}
bool Unit::IsLoaded(int pic)
{
  return bool(image[pic]!=0);
}
bool Unit::ShieldIsLoaded(int pic)
{
  return bool(shield[pic]!=0);
}
SDL_Surface *Unit::GetCurImage()
{
	return image[angle/5];
}
void Unit::DisplayDispImage(int x, int y)
{
	DrawIMG(dispimg,x,y);
}
void Unit::ZeroSlots()
{
	int i;
	for (i=0; i<__MAXSHIPSLOTS; i++)
	{
		slots[i].id=0;
		slots[i].w=0;
		slots[i].l=0;
		slots[i].d=0;
		slots[i].holdamount=0;
		slots[i].ammoamount=0;
		slots[i].cargounits=0;
		slots[i].type="";
		slots[i].full=false;
		slots[i].weaponfull=false;
		slots[i].fulltype="";
		slots[i].fpk="";
		slots[i].fn="";
		if (slots[i].image) SDL_FreeSurface(slots[i].image);
		slots[i].image=0;
	}
	numslots=0;
}
void Unit::FillSlots(__ship_slot *sls, int max)
{
	int i;
	for (i=0; i<max; i++)
	{
		slots[i].id=sls[i].id;
		slots[i].w=sls[i].w;
		slots[i].l=sls[i].l;
		slots[i].d=sls[i].d;
		slots[i].holdamount=sls[i].holdamount;
		slots[i].ammoamount=sls[i].ammoamount;
		slots[i].type=sls[i].type;
		slots[i].full=sls[i].full;
		slots[i].weaponfull=sls[i].weaponfull;
		slots[i].fulltype=sls[i].fulltype;
		slots[i].holdweapon=sls[i].holdweapon;
		slots[i].fpk=sls[i].fpk;
		slots[i].fn=sls[i].fn;
		if (slots[i].image) SDL_FreeSurface(slots[i].image);
		slots[i].image=sls[i].image;
	}
	numslots=max;
	curweapon=0;
}
__ship_slot *Unit::GetSlots()
{
	return slots;
}
__cargo *Unit::GetCargo()
{
	return cargo;
}
int Unit::GetNumSlots()
{
	return numslots;
}
int Unit::GetHeatSeekingBay()
{
	int id=0;
	bool got=false;
	int i;
	for (i=0; i<numslots; i++)
	{
		if (!strcmp(slots[i].holdweapon.c_str(),"heatseeking") && !got && slots[i].ammoamount<slots[i].holdamount)
		{
			id=slots[i].id;
			got=true;
		}
	}
	return id;
}
int Unit::GetHeatSeekingAmmoFill()
{
	int ammoamount=0;
	int i;
	for (i=0; i<numslots; i++)
	{
		if (!strcmp(slots[i].holdweapon.c_str(),"heatseeking"))
		{
			ammoamount+=slots[i].ammoamount;
		}
	}
	return ammoamount;
}
int Unit::GetHeatSeekingAmmoSpace()
{
	int holdamount=0;
	int i;
	for (i=0; i<numslots; i++)
	{
		if (!strcmp(slots[i].holdweapon.c_str(),"heatseeking"))
		{
			holdamount+=slots[i].holdamount;
		}
	}
	return holdamount;
}
void Unit::Colorize(Uint8 r, Uint8 g, Uint8 b)
{
	int i;
	cr=r;
	cg=g;
	cb=b;
	for(i=0; i<UNITS_NUM_FRAMES; i++)
	{
		if (image[i])
		{
			if (cr>0 || cg>0 || cb>0) ColorizeSurface(image[i], cr, cg, cb);
		}
	}
	if (dispimg)
	{
		if (cr>0 || cg>0 || cb>0) ColorizeSurface(dispimg, cr, cg, cb);
	}
}

