/* 
    TowBowlTactics: Adaptation of the tabletop game Blood Bowl

    Copyright (C) 2001-2003 Pascal Bourut (toweld@rocketmail.com)

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include "Player.h"

Player::Player(char* name,int number,char* position,int position_id,int ma,int st,int ag,int av,int cost,char* race,char*picture_name,int team){
	DEBUG ( printf("-> Player::Player(%d,%d)\n",number,team); );
	set_name(name);
	set_position(position);
	set_race(race);
	set_picture_name(picture_name);

	this->number=number;
	this->position_id=position_id;
	this->ma=ma;
	this->st=st;
	this->ag=ag;
	this->av=av;
	this->cost=cost;
	this->team=team;
	xps = 0;
	skills = new std::list<char*>;
	square = NULL;
	reserve_square = NULL;
	status = OK;
	team_reroll_used = false;
	played = false;
	selected = false;
	has_ball = false;
	on_playground = false;
	overmove_count = 0;
	team_reroll_used = false;
	move_reroll_used = false;
	move_count = 0;
	block_done = false;
	aggress_done = false;
	gather_done = false;
	throw_done = false;
	blitz_done = false;
	team_blitz_done = false;
	team_aggress_done = false;
	team_throw_done = false;
	receive_done = false;
	throw_team_mate_done = false;
	//////////////////////
	// Ragnar Modif2
	get_up_done = false;
	//////////////////////
	// Ragnar Modif3
	mighty_blow_used = false;
	dirty_player_used = false;
	pilling_on_used = false;
	/////////////////////////
	// Ragnar Modif4
	frenzy_block_done = false;
	//////////////////////
	// Ragnar Modif6 : nouveaux champs dans Player
	bone_head_tested = false;
	really_stupid_tested = false;
	//////////////////////
	d6 = new Dice(D6);
	DEBUG ( printf("<- Player::Player(%d,%d)\n",number,team); );
}

Player::~Player(){
	DEBUG ( printf("-> Player::~Player() %d %s %i\n",number,name,team); );
	free(name);
	free(race);
	free(position);
	free(picture_name);

	if(skills) delete skills;
	if(square) delete square;
	if(reserve_square) delete reserve_square;
	delete d6;
	DEBUG ( printf("<- Player::~Player() %d %i\n",number,team); );
}

void Player::set_name(char* n){
	if(n) {
		name = (char*)malloc( CHAR_64 );
		sprintf(name,"%s",n);
	}
	else {
		name=NULL;
	}
}

void Player::set_position(char* t){
	if(t){
		position = (char*)malloc( CHAR_64 );
		sprintf(position,"%s",t);	
	}
	else {
		position=NULL;
	}
}

void Player::set_race(char* r){
	if(r){
		race = (char*)malloc( CHAR_64 );
		sprintf(race,"%s",r);	
	}
	else {
		race=NULL;
	}
}

void Player::set_picture_name(char* pn){
	if(pn){
		picture_name = (char*)malloc( CHAR_128 );
		sprintf(picture_name,"%s",pn);	
	}
	else {
		picture_name=NULL;
	}
}

void Player::set_skills(std::list<char*> *skills){
	DEBUG ( printf("-> Player::set_skills\n"); );
	this->skills=skills;
	DEBUG ( printf("<- Player::set_skills\n"); );
}

std::list<char*>* Player::get_skills(){
	return skills;
}

void Player::add_skill(char* skill){
	skills->push_back(skill);
}

bool Player::has_got_skill(char* skill){
	if(!skills) return false;
	std::list<char*>::iterator it;
	for(it=skills->begin();it!=skills->end();it++)
		if( strstr((*it),skill) && strlen((*it)) == strlen(skill)  ) 
			return true;
	return false;
}

int Player::hit(Player *vs){
	if(!vs) fprintf(stderr, "Player->hit(NULL)\n");
	int d = d6->roll(2);
	if( this->has_got_skill(MIGHTY_BLOW) ) d+=1;
	return d;
}

bool Player::is_affected_by_sunstroke(){
	return (d6->roll()==1)?true:false;
}

bool Player::is_throwable(){
	return (/*get_st()<=2 && */has_got_skill(RIGHT_STUFF) )?true:false;
}

bool Player::can_throw_team_mate(){
	return (/*get_st()>=6 && */has_got_skill(THROW_TEAM_MATE) )?true:false;
}

char* Player::get_name(){ return name; }

void Player::set_number(int p){ number=p; }
int Player::get_number(){ return number;}
  
char* Player::get_picture_name(){ return picture_name; }

SDL_Surface* Player::get_picture(){ return picture; }
void Player::set_picture(SDL_Surface* s){ picture = s; }

char* Player::get_position(){ return position; }

void Player::set_position_id(int t){ position_id=t; }
int Player::get_position_id(){ return position_id; }

void Player::set_cost(int c){ cost=c; }
int Player::get_cost(){ return cost; }

void Player::set_carac(int a,int b,int c,int d){ ma=a;st=b;ag=c;av=d; }

void Player::set_ma(int m){ma=m;}
int Player::get_ma(){
	// Ragnar Modif5 : very long legs
	int modified_ma = ma;
	if(has_got_skill(VERY_LONG_LEGS)) modified_ma++;
	return modified_ma;
}

void Player::set_st(int s){ st=s; }
int Player::get_st(){ return st; }

void Player::set_ag(int a){ ag=a; }
int Player::get_ag(){ return ag; }

void Player::set_av(int a){ av=a; }
int Player::get_av(){
	////////////////////////////////
	// Ragnar Modif5 : spikes
	int modified_av = av;
	if(has_got_skill(SPIKES)) modified_av++;
	return modified_av;
}

void Player::set_xps(int x){ xps=x; }
int Player::get_xps(){ return xps; }

char* Player::get_race(){ return race; }

void Player::set_status_only(int s){ status=s; }
  
void Player::set_status(int s){
	status=s;
    if(status>=KO && square) {
		Shared::set_playground( square->get_x() , square->get_y() , NULL );
		delete square;
		square=NULL;
    }
}

int Player::get_status(){return status;}

void Player::set_team(int t){team=t;}
int Player::get_team(){return team;}

void Player::set_team_reroll_used(bool b){team_reroll_used=b;}
bool Player::is_team_reroll_used(){return team_reroll_used;}

void Player::set_on_playground(bool b){on_playground=b;}
bool Player::is_on_playground(){return on_playground;}

void Player::set_selected(bool b){selected=b;}
bool Player::is_selected(){return selected;}

void Player::set_has_ball(bool b){has_ball=b;}
bool Player::has_got_ball(){return has_ball;}

void Player::set_has_played(bool b){played=b;}
bool Player::has_played(){return played;}

void Player::place(Square *s){
	if(square) {
		Shared::set_playground( square->get_x() , square->get_y() , NULL);
    }

    if(reserve_square) {
		Shared::set_reserve_box(get_team() , reserve_square->get_y() , reserve_square->get_x() , NULL);
    	delete reserve_square;
		reserve_square = NULL;
	}
    
	if(s){
		if(square) {
			square->set_xy(s->get_x(),s->get_y());
		}
		else {
			square = new Square(s->get_x(),s->get_y()); 
		} 
		Shared::set_playground( square->get_x() , square->get_y() , this );
	}
	else {
		delete square;
		square = NULL;
	}
  	on_playground=true;
    if(get_status()==RESERVE) set_status(OK);
}

void Player::place(int a,int b){
   	if(square) {
		Shared::set_playground( square->get_x() , square->get_y() , NULL );
	}

    if(reserve_square) {
		Shared::set_reserve_box( get_team() , reserve_square->get_y() , reserve_square->get_x() , NULL );
		delete reserve_square;
		reserve_square = NULL;
	}

    if(square) {
		square->set_xy(a,b);
	}
	else {
		square = new Square(a,b);
	} 

  	Shared::set_playground( a , b , this );

	on_playground=true; 
    if(get_status()==RESERVE) set_status(OK);
}

void Player::place_in_reserve(int i,int j){
	if(reserve_square) {
		Shared::set_reserve_box( get_team() , reserve_square->get_y() , reserve_square->get_x() , NULL );
    }

    if(square) {
		Shared::set_playground( square->get_x() , square->get_y() , NULL) ;
    }
    
	Shared::set_reserve_box( get_team() , j , i , this);
    set_status(RESERVE);
    on_playground=false;
    if(square){
		delete square;
		square = NULL;
	}
    reserve_square = new Square(i,j);
}
  
void Player::place_in_reserve(){
	for(int i=0;i<RESERVE_PAGE_W*RESERVE_PAGE_COUNT;i++){
		for(int j=0;j<RESERVE_PAGE_H;j++){ 
			if(! Shared::get_reserve_box( get_team() , j ,  i )  ){
				if(reserve_square) {
					Shared::set_reserve_box( get_team(), reserve_square->get_y(), reserve_square->get_x(), NULL);
				}
			
				if(square) {
					Shared::set_playground( square->get_x(), square->get_y(), NULL);
				}

				Shared::set_reserve_box(get_team(), j, i, this);
				set_status(RESERVE);
				on_playground=false; 
				if(square){
					delete square;
					square = NULL;
				}
				reserve_square = new Square(i,j);
				return;
			}
		}
    }
}

void Player::set_square(Square *s){ 
	if(s==NULL) {
		if(square) {
			delete square;
			square = NULL;
		}
	}	 
	else {
		if(square){
			square->set_xy(s->get_x(),s->get_y());
		}
		else {
			square = new Square(s->get_x(),s->get_y());
		}

		if(reserve_square) {
			delete reserve_square;// on ne peut pas etre dans la reserve et sur le terrain
			reserve_square = NULL;
		}
	} 
}

void Player::set_square(int x,int y){ 
	if(square){
		square->set_xy(x,y);
	}
	else {
		square = new Square(x,y);
	}
		
	if(reserve_square) {
		delete reserve_square;// on ne peut pas etre dans la reserve et sur le terrain
		reserve_square = NULL;
	}
}

void Player::set_reserve_square(Square *s){
	if(s==NULL) {
		if(reserve_square) {
			delete reserve_square;
			reserve_square = NULL;
		}
	}	 
	else {
		if(reserve_square){
			reserve_square->set_xy(s->get_x(),s->get_y());
		}
		else {
			reserve_square = new Square(s->get_x(),s->get_y());
		}
			
		if(square) {
			delete square;// on ne peut pas etre dans la reserve et sur le terrain
			square = NULL;
		}
	} 
}

void Player::set_reserve_square(int x,int y){
	if(reserve_square){
		reserve_square->set_xy(x,y);
	}
	else {
		reserve_square = new Square(x,y);
	}
		
	if(square) {
		delete square;// on ne peut pas etre dans la reserve et sur le terrain
		square = NULL;
	}
}

Square* Player::get_reserve_square(){return reserve_square;}

Square* Player::get_square(){return square;}
  
std::list<Player*>* Player::get_neighbours(){
    std::list<Player*> *nb = new std::list<Player*>; //MMGR
    int x=square->get_x();
    int y=square->get_y();
    int i;
    int j;
    for(i=x-1;i<=x+1;i++){
		for(j=y-1;j<=y+1;j++){
			if(i>=0 &&
				j>=0 &&
				i<PLAYGROUND_WIDTH && 
				j<PLAYGROUND_HEIGHT && 
				Shared::get_playground(i,j) &&
				!(i==x && j==y)){ 
					nb->push_back(Shared::get_playground(i,j));
			}
		}
    }
    return nb;
}

bool Player::friend_neighbours_has_got_skill(char* s){
	std::list<Player*> *neighbour = get_friend_neighbours();
	std::list<Player*> ::iterator it;
	for(it=neighbour->begin();it!=neighbour->end();it++){
		if( (*it)  
			&& (*it)->get_status()==OK
			&& (*it)->get_team() == get_team()
			&& (*it)->has_got_skill(s) ) {
			delete neighbour;
			return true;
		}
	}
	delete neighbour;
	return false;
}

bool Player::neighbours_has_got_skill(char* s){
	std::list<Player*> *neighbour = get_neighbours();
	std::list<Player*> ::iterator it;
	for(it=neighbour->begin();it!=neighbour->end();it++){
		if( (*it)  
			&& (*it)->get_status()==OK
			&& (*it)->get_team() != get_team()
			&& (*it)->has_got_skill(s) ) {
			delete neighbour;
			return true;
		}
	}
	delete neighbour;
	return false;
}

int Player::get_tackle_zone(int x_test,int y_test){
    int x = x_test;
    int y = y_test;
    int i = 0;
    int j = 0;
    int k = 0;
    for(i=x-1;i<=x+1;i++){
		for(j=y-1;j<=y+1;j++){
			if(i>=0 &&
				j>=0 &&
				i<PLAYGROUND_WIDTH && j<PLAYGROUND_HEIGHT
				&& Shared::get_playground(i,j) 
			    && get_team() != NONE
			    && Shared::get_playground(i,j)->get_team() != NONE
			    && Shared::get_playground(i,j)->get_team() != get_team() 
			    && Shared::get_playground(i,j)->get_status()==OK){
					k++;
				}
		}
    }

    return k;		
}

int Player::get_tackle_zone(){
	return get_tackle_zone(square->get_x(),square->get_y());
}
  
int Player::move(int x_dest,int y_dest){
    int tz = get_tackle_zone(x_dest,y_dest);

    DEBUG( printf("tz  %i\n",tz); );
    ////////////////////////////////////////
	// Ragnar Modif2 : stunty
	int goal= 7 - (has_got_skill(BREAK_TACKLE)?get_st():get_ag()) + tz - 1 - (has_got_skill(STUNTY)?tz:0) - (has_got_skill(TWO_HEADS)?1:0) + (neighbours_has_got_skill(PREHENSILE_TAIL)?1:0);
    ////////////////////////////////////////

    return goal;
}

int Player::gather(){
    int goal=7-get_ag()+get_tackle_zone()-1;
	//////////////////////////////////////
	// Ragnar Modif2 : big hand
	if (has_got_skill(BIG_HAND)) goal = 2;
	//////////////////////////////////////
    return goal;
}

int Player::block(Player *vs){
    int i=get_st(); 
    int j=vs->get_st();

	////////////////////////////////
	// Ragnar Modif2 : prise d'élan nécessaire pour
	// justifier du bonus (cas où le gars s'est relevé)
	if( has_got_skill(HORNS) && move_count>=1){
		if (!get_up_done) i++;
		else if(has_got_skill(JUMP_UP) || move_count>4) i++;
	}
	////////////////////////////////

    DEBUG( printf("player->block force de l'attaquant=%d force de la victime=%d\n",i,j); );
    // soutien defensif: mecs de mon entourage autre que vs et libre de marquage
    std::list<Player*>* neighbour = get_neighbours();
    std::list<Player*>* vs_neighbour = vs->get_neighbours();
    std::list<Player*> ::iterator it;

////////////////////////////////////////////////////////////////////
	// Ragnar Modif6 : wild animal
	if(!vs->has_got_skill(WILD_ANIMAL)){
		for(it=neighbour->begin();it!=neighbour->end();it++)
		  if( (*it) 
		  && (*it) != vs 
		  && (*it)->get_status()==OK
		  && (*it)->get_team() != get_team()
		  ////////////////////////////////////////////////////
		  // Ragnar Modif : compétence garde
		  && ((*it)->get_tackle_zone()==1 || (*it)->has_got_skill(GUARD))
		  ////////////////////////////////////////////////////
		  ) j++; 
	}
    /////////////////////////////////////////////////////////////////////
	
	// soutien offensif: mes pots qui sont a cote de vs et libre de tout autre marquage 
    
	////////////////////////////////////////////////////////////////////
	// Ragnar Modif6 : wild animal
	if (!has_got_skill(WILD_ANIMAL)){
		for(it=vs_neighbour->begin();it!=vs_neighbour->end();it++)
			if( (*it) 
			&& (*it) != this 
			&& (*it)->get_status()==OK
			&& (*it)->get_team() == get_team()
			////////////////////////////////////////////////////
			// Ragnar Modif : compétence garde
			&& ((*it)->get_tackle_zone()==1 || (*it)->has_got_skill(GUARD))
			////////////////////////////////////////////////////
			) i++;
	}
	//////////////////////////////////////////////////////////////////////

    DEBUG( printf("player->block force de l'attaque=%d force de la defense=%d\n",i,j); );
    
	delete neighbour;
	delete vs_neighbour;

    if (i==j) return 1;
    if (i>(2*j)) return 3;
    if (i>j) return 2;
    if (j>(2*i)) return -3;
    if (j>i) return -2;
    return 0;
}

int Player::throw_ball(int dist){
	//int goal= 7 - get_ag() + get_tackle_zone() + dist - (has_got_skill(ACCURATE)?1:0);
	////////////////////////////////////////////
	// Ragnar Modif2
	int goal= 7 - get_ag() + (has_got_skill(NERVES_OF_STEEL)?0:get_tackle_zone()) + dist - (has_got_skill(ACCURATE)?1:0);
	////////////////////////////////////////////
	// throw_done = true;
    return goal;
}
  
int Player::receive_ball(bool perfect_throw){
	
	//////////////////////////////////
	// Ragnar Modif2 : nerves of steel
	  int goal= 7 - get_ag() + (has_got_skill(NERVES_OF_STEEL)?0:get_tackle_zone()) + (perfect_throw?-1:0) - (has_got_skill(TWO_ARMS)?1:0);
	//////////////////////////////////
   
   // receive_done = true;
    return goal;
}

int Player::receive_transmission(){
    return receive_ball(true);
}

int Player::try_to_intercept(){
    int goal=7-get_ag()+get_tackle_zone()+2; 
    ///////////////////////////////////////
	// Ragnar Modif2 : very long legs
	if (has_got_skill(VERY_LONG_LEGS)) goal--;
	///////////////////////////////////////
	return goal;
}

int Player::overmove(bool slippery){
    int goal=slippery?2:1;
    return goal;
}

	////////////////////////////////////////////////////////////////////////////
	// Ragnar Modif4 : cette version de la fonction remplace l'ancienne
	// décompte des soutiens offensif et défensifs comme pour un block classique
int Player::aggress(Player *vs){
    int goal=vs->get_av();

    std::list<Player*>* neighbour = get_neighbours();
    std::list<Player*>* vs_neighbour = vs->get_neighbours();
    std::list<Player*> ::iterator it;
  	
	//////////////////////////////////////////////////////////////
	// Ragnar Modif6 : wild animal
	// soutien defensif
	if(!vs->has_got_skill(WILD_ANIMAL)){
		for(it=neighbour->begin();it!=neighbour->end();it++)
		  if( (*it) 
		  && (*it) != vs 
		  && (*it)->get_status()==OK
		  && (*it)->get_team() != get_team()
		  && ((*it)->get_tackle_zone()==1 )
		  ) goal++;
	}
    // soutien offensif
    if(!has_got_skill(WILD_ANIMAL)){
		for(it=vs_neighbour->begin();it!=vs_neighbour->end();it++)
		  if( (*it) 
		  && (*it) != this 
		  && (*it)->get_status()==OK
		  && (*it)->get_team() == get_team()
		  && ((*it)->get_tackle_zone()==0)
		  ) goal--;
	}
	///////////////////////////////////////////////////////////////

	delete neighbour;
	delete vs_neighbour;
    return goal;
} 

int Player::landing(bool perfect_throw){
    int goal=(7-get_ag()+get_tackle_zone())+(perfect_throw?-1:0);
    return goal;
}

int Player::throw_team_mate(int dist){
    int goal=7-get_ag()+get_tackle_zone()+dist;
  //  throw_team_mate_done = true;
    return goal;
}
  
void Player::pursue(int x_diff,int y_diff){
    int x=square->get_x();x+=x_diff;
    int y=square->get_y();y+=y_diff;
    move_count++;
    place(x,y);
}
 
std::list<Player*>* Player::get_down_neighbours(){
	std::list<Player*> *nb = new std::list<Player*>;
    int x = square->get_x();
    int y = square->get_y();
    int i;
    int j;
    for(i=x-1;i<=x+1;i++){
		for(j=y-1;j<=y+1;j++){
			if(i>=0 &&
			   j>=0 &&
			   i<PLAYGROUND_WIDTH && 
			   j<PLAYGROUND_HEIGHT && 
			   Shared::get_playground(i,j) &&
			   Shared::get_playground(i,j)->get_status()>OK &&
			   Shared::get_playground(i,j)->get_team() != get_team() && 
			   !(i==x && j==y)){ 
					nb->push_back(Shared::get_playground(i,j));
			}
		}
    }
    return nb;
}
 
int Player::get_down_neighbours_count(){
    std::list<Player*>* down_neighbour = get_down_neighbours();
	int size = down_neighbour->size();
	delete down_neighbour;
    return size;
}

std::list<Player*>* Player::get_friend_neighbours(){
  
    std::list<Player*> *nb = new std::list<Player*>;
    int x = square->get_x();
    int y = square->get_y();
    int i;
    int j;
    for(i=x-1;i<=x+1;i++){
		for(j=y-1;j<=y+1;j++){
			if(i>=0 &&
			   j>=0 &&
			   i<PLAYGROUND_WIDTH && 
			   j<PLAYGROUND_HEIGHT && 
			   Shared::get_playground(i,j) &&
			   Shared::get_playground(i,j)->get_status()==OK &&
			   Shared::get_playground(i,j)->get_team() == get_team() && 
			   !(i==x && j==y)){ 
				nb->push_back(Shared::get_playground(i,j));
				}
			}
		}
	return nb;
}
 

int Player::get_friend_neighbours_count(){
    std::list<Player*>* friend_neighbour = get_friend_neighbours();
	int size = friend_neighbour->size();
	delete friend_neighbour;
    return size;
}
  
int Player::over_movement_left(){
	return ( ( MAX_OVERMOVE + (has_got_skill(SPRINT)?1:0) ) - overmove_count);
}

void Player::inc_move_count(){move_count++;}
void Player::inc_move_count(int i){move_count+=i;}
int Player::movement_left(){return (get_ma()-move_count);}
void Player::inc_overmove_count(){overmove_count++;}
int Player::get_overmove_count(){return overmove_count;}
void Player::reset_overmove_count(){overmove_count=0;}
int Player::get_move_count(){return move_count;}
void Player::set_move_count(int c){move_count = c;}
void Player::set_overmove_count(int c){overmove_count = c;}
  
bool Player::get_move_reroll_used(void){return move_reroll_used;}
void Player::set_move_reroll_used(bool b){move_reroll_used = b;}

void Player::reset_move_count(){move_count=0;}
void Player::set_block_done(bool b){block_done=b;}
bool Player::is_block_done(){return block_done;}

////////////////////////
// Ragnar Modif2
void Player::set_get_up_done(bool b){get_up_done=b;}
bool Player::is_get_up_done(){return get_up_done;}
////////////////////////
// Ragnar Modif3
void Player::set_mighty_blow_used(bool b){mighty_blow_used=b;}
bool Player::is_mighty_blow_used(){return mighty_blow_used;}
void Player::set_dirty_player_used(bool b){dirty_player_used=b;}
bool Player::is_dirty_player_used(){return dirty_player_used;}
void Player::set_pilling_on_used(bool b){pilling_on_used=b;}
bool Player::is_pilling_on_used(){return pilling_on_used;}
////////////////////////
// Ragnar Modif4
void Player::set_frenzy_block_done(bool b){frenzy_block_done=b;}
bool Player::is_frenzy_block_done(){return frenzy_block_done;}
////////////////////////
// Ragnar Modif6 : nouveaux champs dans Player
void Player::set_bone_head_tested(bool b){bone_head_tested=b;}
bool Player::is_bone_head_tested(){return bone_head_tested;}
void Player::set_really_stupid_tested(bool b){really_stupid_tested=b;}
bool Player::is_really_stupid_tested(){return really_stupid_tested;}
////////////////////////

void Player::set_throw_done(bool b){throw_done=b;}
bool Player::is_throw_done(){return throw_done;}

void Player::set_throw_team_mate_done(bool b){throw_team_mate_done=b;}
bool Player::is_throw_team_mate_done(){return throw_team_mate_done;}
 
void Player::set_aggress_done(bool b){aggress_done=b;}
bool Player::is_aggress_done(){return aggress_done;}

void Player::set_blitz_done(bool b){blitz_done=b;}
bool Player::is_blitz_done(){return blitz_done;}

void Player::set_team_blitz_done(bool b){team_blitz_done=b;}
bool Player::is_team_blitz_done(){return team_blitz_done;}

void Player::set_team_aggress_done(bool b){team_aggress_done=b;}
bool Player::is_team_aggress_done(){return team_aggress_done;}

void Player::set_team_throw_done(bool b){team_throw_done=b;}
bool Player::is_team_throw_done(){return team_throw_done;}
  
void Player::set_gather_done(bool b){gather_done=b;}
bool Player::is_gather_done(){return gather_done;}

void Player::set_receive_done(bool b){receive_done=b;}
bool Player::is_receive_done(){return receive_done;}

bool Player::can_transmit(){
	if(!square)return false;
   
	if(has_ball && get_friend_neighbours_count()>0 /*RM6*/&& !has_played()/*RM6*/){
		return true;
	}
	return false;
}

bool Player::can_move(){
   if(!square)return false;
   
	///////////////////////
	// Ragnar Modif5 : very long legs
	if((move_count<get_ma()) && 
	///////////////////////
       (!aggress_done) && 
       (!block_done)
       ) 
		return true;
	return false;
}

bool Player::can_overmove(){
	if(!square)return false;
   
	if( (overmove_count< ( MAX_OVERMOVE + ( has_got_skill(SPRINT)?1:0 ) ) ) && 
       (!aggress_done) && 
       (!block_done)
       ) 
		return true;
    return false;
}
  
bool Player::can_block(){
	if(!square)return false;
   
	if((!block_done)&&
       (move_count==0)&&
       (!throw_done)&&
       (!aggress_done)&&
       (get_tackle_zone()!=0)&&
	   (!blitz_done) /*RM6 &&
        - le ramassage n'est pas une action - (!gather_done) RM6*/
		)
		return true;
    return false;
}
  
bool Player::can_catch(Square *ball_location){
	if(!square)return false;
   
    if((!has_ball)&&
       (square->get_x() == ball_location->get_x()) &&
       (square->get_y() == ball_location->get_y()) &&
       (!aggress_done)&&
       (!throw_done) &&
       (!block_done) /*RM6 && 
        - le ramassage n'est pas une action - (!gather_done) RM6*/  
       ) 
		return true;
	return false;
}
  
bool Player::can_throw(){
   if(!square)return false;
   
	if((has_ball)&&
       (!aggress_done)&&
       (!throw_done) && 
       (!team_throw_done) &&
       (!block_done) &&
       (!blitz_done)) 
		return true;
    return false;
}
  
bool Player::can_aggress(){
	if(!square)return false;
   
    if((!aggress_done) && 
       (!team_aggress_done) &&
       (!throw_done) &&
       (!block_done) &&
       (!blitz_done) &&
       /*RM6 - le ramassage n'est pas une action - (!gather_done) && RM6*/
       (get_down_neighbours_count()!=0)) 
		return true;
    return false;
}

bool Player::can_move_and_blitz(){
	if(!square)return false;
   
	if((overmove_count<MAX_OVERMOVE) &&
       (!aggress_done) &&
       (!throw_done) &&
       (!block_done) &&
       (!blitz_done) &&
       /*RM6 - le ramassage n'est pas une action - (!gather_done) && RM6*/
       (!team_blitz_done) && 
       (get_tackle_zone()!=0) ) 
		return true;
    return false;
}

bool Player::can_blitz(){
	if(!square)return false;
   
	if((move_count<get_ma()) &&
       (!aggress_done) &&
       (!throw_done) &&
       (!block_done) &&
       (!blitz_done) &&
       /*RM6 - le ramassage n'est pas une action - (!gather_done) && RM6*/
       (!team_blitz_done) && 
       (get_tackle_zone()!=0) ) 
		return true;
    return false;
}

bool Player::can_do_something_more(Square *ball_location){
	if(!square)return false;
   
	return (can_move()||
	    can_move_and_blitz()||
	    can_overmove()||
	    can_block()||
	    can_catch(ball_location)||
	    can_throw()||
	    can_aggress()||
	    can_blitz());
}

bool Player::has_done_something(){
    if( move_count!=0 || 
		block_done || 
		aggress_done ||
		gather_done ||
		blitz_done ||
		throw_done )
		return true;
    return false;
}

void Player::debug(){ 
	printf("----------- player ------------\n");
	int i,j;
	for(i=0;i<PLAYGROUND_WIDTH;i++){
		for(j=0;j<PLAYGROUND_HEIGHT;j++){
			printf("%i,",(Shared::get_playground(i,j))?1:0);
		}
	printf("\n");
	}
	printf("----------- player ------------\n");
}

void Player::save_state(FILE* fd, int depth){
	char format[10];
	memset(format,0,10);
	
	for(int i=0;i<depth;i++)
		format[i] = ' ';
	format[depth-1] = '\0';
	fprintf(fd,"%s<player>\n",format);
	fprintf(fd,"%s<name>%s</name>\n",format,name);
    fprintf(fd,"%s<number>%i</number>\n",format,number);
	fprintf(fd,"%s<position>%s</position>\n",format,position);
	fprintf(fd,"%s<position_id>%i</position_id>\n",format,position_id);
	fprintf(fd,"%s<cost>%i</cost>\n",format,cost); 
	fprintf(fd,"%s<ma>%i</ma>\n",format,ma); 
	fprintf(fd,"%s<st>%i</st>\n",format,st); 
	fprintf(fd,"%s<ag>%i</ag>\n",format,ag); 
	fprintf(fd,"%s<av>%i</av>\n",format,av); 
	fprintf(fd,"%s<xps>%i</xps>\n",format,xps); 
	fprintf(fd,"%s<picture_name>%s</picture_name>\n",format,picture_name);
	fprintf(fd,"%s<status>%i</status>\n",format,status); 
	 
	if(skills){
		std::list<char*>::iterator it;
		for(it=skills->begin();it!=skills->end();it++){
			fprintf(fd,"%s<skill>%s</skill>\n",format,(*it));
		}
	}

	fprintf(fd,"%s<race>%s</race>\n",format,race); 
	fprintf(fd,"%s<on_playground>%i</on_playground>\n",format,on_playground);
	fprintf(fd,"%s<has_ball>%i</has_ball>\n",format,has_ball);
	fprintf(fd,"%s<selected>%i</selected>\n",format,selected);
	fprintf(fd,"%s<played>%i</played>\n",format,played);
	fprintf(fd,"%s<overmove_count>%i</overmove_count>\n",format,overmove_count);
	fprintf(fd,"%s<team_reroll_used>%i</team_reroll_used>\n",format,team_reroll_used);
	fprintf(fd,"%s<move_reroll_used>%i</move_reroll_used>\n",format,move_reroll_used);
	fprintf(fd,"%s<team>%i</team>\n",format,team);
	fprintf(fd,"%s<move_count>%i</move_count>\n",format,move_count);
	fprintf(fd,"%s<block_done>%i</block_done>\n",format,block_done);
	fprintf(fd,"%s<aggress_done>%i</aggress_done>\n",format,aggress_done);
	fprintf(fd,"%s<gather_done>%i</gather_done>\n",format,gather_done);
	fprintf(fd,"%s<throw_done>%i</throw_done>\n",format,throw_done);
	fprintf(fd,"%s<throw_team_mate_done>%i</throw_team_mate_done>\n",format,throw_team_mate_done);
	fprintf(fd,"%s<blitz_done>%i</blitz_done>\n",format,blitz_done);
	fprintf(fd,"%s<team_blitz_done>%i</team_blitz_done>\n",format,team_blitz_done);
	fprintf(fd,"%s<team_aggress_done>%i</team_aggress_done>\n",format,team_aggress_done);
	fprintf(fd,"%s<team_throw_done>%i</team_throw_done>\n",format,team_throw_done);
	fprintf(fd,"%s<receive_done>%i</receive_done>\n",format,receive_done);
	
	fprintf(fd,"%s<get_up_done>%i</get_up_done>\n",format,get_up_done);
	fprintf(fd,"%s<mighty_blow_used>%i</mighty_blow_used>\n",format,mighty_blow_used);
	fprintf(fd,"%s<dirty_player_used>%i</dirty_player_used>\n",format,dirty_player_used);
	fprintf(fd,"%s<pilling_on_used>%i</pilling_on_used>\n",format,pilling_on_used);
	fprintf(fd,"%s<frenzy_block_done>%i</frenzy_block_done>\n",format,frenzy_block_done);

	//////////////////////////////////////////////
	//Ragnar Modif6 : nouveaux champs dans Player
	fprintf(fd,"%s<bone_head_tested>%i</bone_head_tested>\n",format,bone_head_tested);
	fprintf(fd,"%s<really_stupid_tested>%i</really_stupid_tested>\n",format,really_stupid_tested);

    if(square) {fprintf(fd,"%s<square>\n",format); square->save_state(fd,depth+1); fprintf(fd,"%s</square>\n",format);}
	if(reserve_square) {fprintf(fd,"%s<reserve_square>\n",format); reserve_square->save_state(fd,depth+1); fprintf(fd,"%s</reserve_square>\n",format);}

	fprintf(fd,"%s</player>\n",format);
}








