
#include "includes.h"

//type, team, hp, max_hp, R, U, D
ACTOR * create_actor(int type, int team, int hp, int max_hp, int r1, int r2, int r3, int u1, int u2, int u3, int d1, int d2, int d3)
{	
	ACTOR * a = (ACTOR*)malloc((sizeof(ACTOR)));
	if (a==NULL){return(NULL);}
	
	memset(a, 0, sizeof(ACTOR));
	
	a->type=type;
	a->team=team;
	a->hp=hp;
	a->max_hp=max_hp;
	a->anim=0;
	a->anim_d=1;
	a->counter=0;
	a->max_counter=10;
	a->walk_speed=1;
	a->alive=true;
	a->shoot_cntr=0;
	a->shoot_max=30;
	
	
	a->bmp[A_RT][0]=tiles[r1];
	a->bmp[A_RT][1]=tiles[r2];
	a->bmp[A_RT][2]=tiles[r3];
	
	a->bmp[A_UP][0]=tiles[u1];
	a->bmp[A_UP][1]=tiles[u2];
	a->bmp[A_UP][2]=tiles[u3];
	
	a->bmp[A_DN][0]=tiles[d1];
	a->bmp[A_DN][1]=tiles[d2];
	a->bmp[A_DN][2]=tiles[d3];
	
	
	if ((a->bmp[A_RT][0]) && (a->bmp[A_RT][1]) && (a->bmp[A_RT][2]))
	{
				
		a->bmp[A_LF][0]=create_bitmap(16, 16);
		a->bmp[A_LF][1]=create_bitmap(16, 16);
		a->bmp[A_LF][2]=create_bitmap(16, 16);
	
		if (!(a->bmp[A_LF][0]))
		{
			free(a);
			return(NULL);
		}
		
		if (!(a->bmp[A_LF][1]))
		{
			destroy_bitmap(a->bmp[A_LF][0]);
			free(a);
			return(NULL);
		}
		
		if (!(a->bmp[A_LF][2]))
		{
			destroy_bitmap(a->bmp[A_LF][0]);
			destroy_bitmap(a->bmp[A_LF][1]);
			free(a);
			return(NULL);
		}
		
		clear_to_color(a->bmp[A_LF][0], 0);
		draw_sprite_h_flip(a->bmp[A_LF][0], a->bmp[A_RT][0], 0, 0);
		
		clear_to_color(a->bmp[A_LF][1], 0);
		draw_sprite_h_flip(a->bmp[A_LF][1], a->bmp[A_RT][1], 0, 0);
		
		clear_to_color(a->bmp[A_LF][2], 0);
		draw_sprite_h_flip(a->bmp[A_LF][2], a->bmp[A_RT][2], 0, 0);
		
	}
	else if (a->bmp[A_RT][0])
	{
		a->bmp[A_LF][0]=create_bitmap(16, 16);
		if (!(a->bmp[A_LF][0]))
		{
			free(a);
			return(NULL);
		}
		
		clear_to_color(a->bmp[A_LF][0], makecol(255,0, 255));
		draw_sprite_h_flip(a->bmp[A_LF][0], a->bmp[A_RT][0], 0, 0);		
	}
	
	if (a->bmp[A_DN][1])
	{a->mask = create_box_pmask(a->bmp[A_DN][1]);}
	else if (a->bmp[A_DN][0])
	{a->mask = create_box_pmask(a->bmp[A_DN][0]);}
	
	return(a);
}

void destroy_actor(ACTOR * a)
{
	if (!a){return;}
	
	for (int i=0; i<3; i++)
	{
		if (a->bmp[A_LF][i])
		{
			destroy_bitmap(a->bmp[A_LF][i]);
			a->bmp[A_LF][i]=NULL;
		}
	}
	
	if (a->mask)
	{ 
		destroy_pmask(a->mask);
	}
	
	free(a);
}

void draw_actor(int cx, int cy, ACTOR * a)
{
	if (!a){return;}
	if (!a->alive){return;}
	
	draw_sprite(apage, a->bmp[a->dir][a->anim], a->x-cx, a->y-cy);
}

void walk_actor(ACTOR * a, int DIR)
{
	if (DIR==A_RT){a->x+=a->walk_speed;}
	if (DIR==A_UP){a->y-=a->walk_speed;}
	if (DIR==A_LF){a->x-=a->walk_speed;}
	if (DIR==A_DN){a->y+=a->walk_speed;}
	a->dir=DIR;
	a->needs_animate=true;
}

void animate_actor(ACTOR * a)
{
	if (!a){return;}
	
	a->counter++;
	if (a->counter>a->max_counter)
	{
		a->anim += a->anim_d;
		a->counter=0;
	}
	
	if (a->anim<0){a->anim=1; a->anim_d=1;}
	if (a->anim>2){a->anim=1; a->anim_d=-1;}	
	
	a->needs_animate=false;
	
	return;	
}

int new_actor(int type, int team, int hp, int max_hp, int r1, int r2, int r3, int u1, int u2, int u3, int d1, int d2, int d3)
{
	int c=-1;
	for (int i=0; i<100; i++)
	{
		if (npc[i]==NULL)
		{
			c=i;
			i=100;
		}
		else
		if (!npc[i]->alive)
		{
			destroy_actor(npc[i]);
			npc[i]=NULL;
			c=i;
			i=100;
		}
	}
	
	if (c>=0)
	{
		npc[c]=create_actor(type, team, hp, max_hp, r1, r2, r3, u1, u2, u3, d1, d2, d3);
	}
	return(c);
}

ACTOR * copy_actor(ACTOR * a)
{
	if (!a){return(NULL);}
	if (!a->alive){return(NULL);}
	
	ACTOR * a2=create_actor(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
	if (a2)
	{
		memcpy(a2, a, sizeof(ACTOR));
		a2->mask=NULL;
		
		for (int i=0; i<4; i++)
		{
			for (int j=0; j<3; j++)
			{
				if (a->bmp[i][j])
				{
					if (i==A_LF)
					{
						a2->bmp[i][j]=create_bitmap(a->bmp[i][j]->w, a->bmp[i][j]->h);
						if (a2->bmp[i][j])
						{blit(a->bmp[i][j], a2->bmp[i][j], 0, 0, 0, 0, a->bmp[i][j]->w, a->bmp[i][j]->h);}
					}
					else
					{
						a2->bmp[i][j]=a->bmp[i][j];
					}
				}
			}
		}
		
		if (a2->bmp[A_DN][1])
		{a2->mask = create_box_pmask(a2->bmp[A_DN][1]);}
		else if (a2->bmp[A_DN][0])
		{a2->mask = create_box_pmask(a2->bmp[A_DN][0]);}
	}

	return(a2);
}

int create_skeleton(int x, int y, int hp, int smart)
{
	int i=new_actor(1, 2, hp, hp, 50, 51, 52, 60, 61, 62, 70, 71, 72);
	if (i>=0)
	{
		npc[i]->x=x;
		npc[i]->y=y;
		npc[i]->state[0]=true;	//first-timer
		npc[i]->state[1]=smart;
	}
	
	return i;
}

int create_goblin(int x, int y, int hp, int smart)
{
	int i=new_actor(2, 2, hp, hp, 7, 8, 9, 17, 18, 19, 27, 28, 29);
	if (i>=0)
	{
		npc[i]->x=x;
		npc[i]->y=y;
		npc[i]->state[0]=true;	//first-timer
		npc[i]->state[1]=smart;
	}
	
	return i;
}

void npcs_think()
{
	for (int i=0; i<100; i++)
	{
		if (npc[i])
		{
			if (npc[i]->alive)
			{
				npc_think(npc[i]);
			}
		}
	}
}

void npc_think(ACTOR * n)
{
	////////////////////////////////////////////////////////////////////////////
	if (n->type==1)	//skeleton
	{
		if (n->state[0])
		{
			n->state[0]=false;
			n->dir=rand()%4;	
			n->state[2]=(1+(rand()%10))*8;
			n->walk_speed=1;
			n->state[5]=0;
			n->max_counter=2;
			
		}
		
		if (n->state[10]<1)
		{
			shoot_bone(n->team, (n->x+8)+(dir_x[n->dir]*8), (n->y+8)+(dir_y[n->dir]*8), n->dir);
			n->state[10]=120+(rand()%120);
		}
		else
		{n->state[10]--;}
		
		if (n->state[5]<1)
		{
			n->state[5]=2;
			
			move_npc(n, n->dir);
		
			n->state[2]--;
			if (n->state[2]<1)
			{
				n->state[0]=true;	
			}
			
		}
		else
		{
			n->state[5]--;
		}
		
		if (n->team != player->team)
		{
			if (n->mask)
			{
				if (check_pmask_collision(n->mask, player->mask, n->x, n->y, player->x, player->y))
				{
					if (plr_blinky<1)
					{
						hurt_actor(player, (player->x-8)-(n->x-8), (player->y-8)-(n->y-8));
						player->hp-=n->hp/3;
					}
				}	
			}	
		}
		
		if (n->hp<0)
		{
			give_exp(n->max_hp);
			n->alive=false;
			explode(n->x, n->y, 4, 16, WHITE, GRAY, WHITE, GRAY);
		}
	}
	////////////////////////////////////////////////////////////////////////////
	else if (n->type==2) //goblin
	{
		if (n->state[0])
		{
			n->state[0]=false;
			n->dir=rand()%4;	
			n->state[2]=(1+(rand()%10))*8;
			n->walk_speed=1;
			n->max_counter=2;
		}
		
		if (n->state[10]<1)
		{
			shoot_boomberang(n->team, (n->x+8)+(dir_x[n->dir]*8), (n->y+8)+(dir_y[n->dir]*8), n->dir);
			n->state[10]=100+(rand()%200);
		}
		else
		{n->state[10]--;}
					
		move_npc(n, n->dir);
		
		n->state[2]--;
		if (n->state[2]<1)
		{
			n->state[0]=true;	
		}
		
		if (n->team != player->team)
		{
			if (n->mask)
			{
				if (check_pmask_collision(n->mask, player->mask, n->x, n->y, player->x, player->y))
				{
					if (plr_blinky<1)
					{
						hurt_actor(player, (player->x-8)-(n->x-8), (player->y-8)-(n->y-8));
						player->hp-=n->hp/3;
					}
				}	
			}	
		}
		
		if (n->hp<0)
		{
			give_exp(n->max_hp);
			n->alive=false;
			explode(n->x, n->y, 4, 16, GREEN, DK_GREEN, RED, DK_RED);
		}
	}
	////////////////////////////////////////////////////////////////////////////
}

void move_npc(ACTOR * n, int dir)
{
	int ox, oy, od, oa;
	int wox, woy;
	wox=n->x;	//way old x
	woy=n->y;	//way old y
	
	ox=n->x; oy=n->y; od=n->dir; oa=n->needs_animate;
	walk_actor(n, dir);
	if (collision(n))
	{
		n->x=ox;n->y=oy; n->dir=od; n->needs_animate=oa;
		if (n->type==1)
		{
			n->state[2]=0;
		}	
	}
	
	if (n->needs_animate){animate_actor(n);}
	
	if (n->x==wox && n->y==woy)
	{ n->dir=dir; }
	
	
}

void hurt_actor(ACTOR * a, int vx, int vy)
{
	if (vx>4){vx=4;}
	if (vy>4){vy=4;}
	if (vx<-4){vx=-4;}
	if (vy<-4){vy=-4;}
		
	if (!a){return;}
	if (collision(a)){return;}
	if ((a==player) && (plr_blinky>0))
	{return;}
	
	int mx=vx;
	int my=vy;
	
	int dx=1;
	int dy=1;
	if (mx<0){dx=-1;mx*=-1;}
	if (my<0){dy=-1;my*=-1;}
	
	while (mx>0)
	{
		if (my>0)
		{
			a->y+=dy;
			if (collision(a))
			{a->y-=dy;}
			my--;
		}
		
		a->x+=dx;
		if (collision(a))
		{a->x-=dx;}
		mx--;
	}
	
	while (my>0)
	{
		a->y+=dy;
		if (collision(a))
		{a->y-=dy;}
		my--;
	}
	
	if (a==player)
	{
		if (plr_blinky<1)
		{
			plr_blinky=120;
			
		}
	}
}
