📄 player.cc
字号:
// -*-c++-*-/*************************************************************************** player.cc - A class for field players and goalies ------------------- begin : 26-NOV-2001 copyright : (C) 2001, 2002 by The RoboCup Soccer Server Maintenance Group. email : sserver-admin@lists.sourceforge.net ***************************************************************************//*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU LGPL as published by the Free Software * * Foundation; either version 2 of the License, or (at your option) any * * later version. * * * ***************************************************************************/#include "player.h"#include "field.h"#include "types.h"#include "visualsensor.h"#include "random.h"#include "serverparam.h"#include "playerparam.h"extern void write_log(Stadium& stad, Player& p, const char *message, int flag) ;static char *PlayModeString[] = PLAYMODE_STRINGS ;Player::Player(Team *tm, Stadium *stad, ID number) : MPObject( PObject::OT_PLAYER ), M_arm ( ServerParam::instance().pointToBan (), ServerParam::instance().pointToDuration () ), M_tackle_cycles( 10 ), M_tackle_count( 0 ), M_clang_min_ver( 0 ), M_clang_max_ver( 0 ), M_parser( *this ){ stadium = stad; team = tm; unum = number; name = new char[128]; name_far = new char[128]; name_toofar = new char[128]; /* th 19.05.00 */ short_name = new char[128]; short_name_far = new char[128]; short_name_toofar = new char[128]; stamina = ServerParam::instance().stamina_max ; //inertia_moment = ServerParam::instance().inertia_moment ; recovery = ServerParam::instance().recover_init; //effort = 1.0 ; vis_angle = defangle = ServerParam::instance().visAngle(); vis_distance = ServerParam::instance().visdist; vis_send = 4; sendcnt = 0; highquality = TRUE ; weight = ServerParam::instance().pweight; weather = &(stad->weather); //max_speed = ServerParam::instance().pspeed_max ; max_accel = ServerParam::instance().paccel_max; command_done = FALSE; turn_neck_done = FALSE; offside_mark = FALSE; goalie = FALSE; alive = DISABLE; goalie_catch_ban = FALSE; goalie_catch_probability = ServerParam::instance().catch_prob; goalie_moves_since_catch = 0; hear_capacity_from_teammate = ServerParam::instance().hearMax(); hear_capacity_from_opponent = ServerParam::instance().hearMax(); pos.x = -(unum * 3 * tm->side); pos.y = -PITCH_WIDTH/2.0 - 3.0; angle_neck = 0.0; angle_neck_committed = 0.0; angle_body = 0.0; // pfr 8/14/00: for RC2000 evaluation //kick_rand = ServerParam::instance().kick_rand; count_kick = count_dash = count_turn = count_say = count_turn_neck = count_move = count_catch = count_change_view = 0; setPlayerType ( 0 ); effort = player_type->effortMax ();}void Player::init(Value version_tmp, int goalie_flag){ version = version_tmp; goalie = goalie_flag; alive = STAND; version = version_tmp; if ( goalie ){ alive |= GOALIE; } goalie_catch_ban = FALSE; goalie_moves_since_catch = 0; sprintf(name,PLAYER_NAME_FORMAT,team->name,unum); sprintf(name_far,PLAYER_NAME_FAR_FORMAT,team->name); sprintf(name_toofar,PLAYER_NAME_TOOFAR_FORMAT); /* th 19.05.00 */ /* pfr, we'll also show the goalie */ sprintf( short_name,PLAYER_NAME_FORMAT_SHORT,team->name,unum, goalie ? GOALIE_VISUAL_STRING : "" ); sprintf( short_name_far,PLAYER_NAME_FAR_FORMAT_SHORT,team->name ); sprintf( short_name_toofar,PLAYER_NAME_TOOFAR_FORMAT_SHORT ); // pfr 8/14/00: for RC2000 evaluation Value my_prand = ServerParam::instance().prand; if (ServerParam::instance().team_actuator_noise) { my_prand *= team->prand_factor_team; kick_rand *= team->kick_rand_factor_team; } Set( MPO_Player, pos, //ServerParam::instance().psize, player_type->playerSize (), SideDirection(team->side), PVector(0.0,0.0),PVector(0.0,0.0), //ServerParam::instance().pdecay, player_type->playerDecay (), my_prand);#ifdef NEW_QSTEP dist_qstep_player = team->dist_qstep_team; land_qstep_player = team->land_qstep_team; dir_qstep_player = team->dir_qstep_team;#endif}void Player::setPlayerType( const int& id ){ player_type_id = id; player_type = stadium->player_types[ id ]; max_speed = player_type->playerSpeedMax(); inertia_moment = player_type->inertiaMoment(); decay = player_type->playerDecay(); size = player_type->playerSize(); kick_rand = player_type->kickRand();}int Player::getPlayerType() const{ return player_type_id;}void Player::substitute( const int& type ){ setPlayerType( type ); // reset stamina etc. stamina = ServerParam::instance().stamina_max; recovery = 1.0; effort = player_type->effortMax (); hear_capacity_from_teammate = ServerParam::instance().hearMax(); hear_capacity_from_opponent = ServerParam::instance().hearMax();}void Player::disable(){ if( goalie == TRUE && this == stadium->M_caught_ball ){ stadium->M_caught_ball = NULL; } enable = FALSE; alive = DISABLE; pos.x = -(unum * 3 * team->side); pos.y = -PITCH_WIDTH/2.0 - 3.0; RemoteClient::close(); std::cout << "A player disconnected\n";}void Player::dash( double power ){ if ( command_done == FALSE ){ // calculate stamina double power_need = (power < 0.0) ? NormalizeDashPower(power) * -2.0 : NormalizeDashPower(power); if ( power_need > stamina + player_type->extraStamina() ){ power_need = stamina + player_type->extraStamina(); } stamina -= power_need; if ( stamina < 0.0 ){ stamina = 0.0; } power = (power < 0) ? power_need / -2.0 : power_need; double effective_dash_power = effort * power; MPObject::dash( ReduceDashPower(effective_dash_power) ); count_dash++; command_done = TRUE; }}void Player::turn( double moment ){ if ( command_done == FALSE ) { angle_body = normalize_angle( angle + (1.0 + drand(-randp, randp)) * NormalizeMoment(moment) / (1.0 + inertia_moment * vel.r()) ); count_turn++; command_done = TRUE; }}void Player::turn_neck( double moment){ if ( turn_neck_done == FALSE ) { angle_neck = NormalizeNeckAngle( angle_neck + NormalizeNeckMoment(moment) ); count_turn_neck++; turn_neck_done = TRUE; }}void Player::kick( double power, double dir ){ if ( command_done == FALSE ) { power = NormalizeKickPower(power); dir = NormalizeMoment(dir); MPObject* ball = stadium->ball; PVector tmp; Value dir_diff; Value dist_ball; alive |= KICK; if ( stadium->mode == PM_BeforeKickOff || stadium->mode == PM_AfterGoal_Left || stadium->mode == PM_AfterGoal_Right || stadium->mode == PM_OffSide_Left || stadium->mode == PM_OffSide_Right || stadium->mode == PM_Back_Pass_Left || stadium->mode == PM_Back_Pass_Right || stadium->mode == PM_Free_Kick_Fault_Left || stadium->mode == PM_Free_Kick_Fault_Right || stadium->mode == PM_TimeOver ) { return; } if( pos.distance(ball->pos) > (player_type->playerSize () + ball->size + player_type->kickableMargin()) ) { alive |= KICK_FAULT; return; } if ( ServerParam::instance().useoffside ){ if ( stadium->mark_offside_mark(this) ){ return; } } dir_diff = fabs( this->vangle(*ball) ); tmp = ball->pos - this->pos; dist_ball = ( tmp.r() - player_type->playerSize() - ServerParam::instance().bsize ); Value eff_power = power * ServerParam::instance().kprate * (1.0 - 0.25*dir_diff/PI - 0.25*dist_ball/player_type->kickableMargin ()); ball->push( Polar2PVector( eff_power, dir + angle ) ); ball->angle = dir + angle; // pfr 8/14/00: for RC2000 evaluation // add noise to kick Value maxrnd = kick_rand * power / ServerParam::instance().maxp; PVector kick_noise( drand(-maxrnd, maxrnd), drand(-maxrnd, maxrnd) ); //std::cout << "Kick noise (" << power << "): " << kick_noise << std::endl; ball->push( kick_noise ); stadium->kickTaken( *this ); //stadium->last_touch = this; stadium->last_kicker = this; stadium->setPossibleBackPasser( *this ); stadium->M_caught_ball = NULL; ball->countKick(); count_kick++; command_done = TRUE; }}void Player::goalieCatch( double dir ){ if ( command_done == FALSE ) { static RArea p_l( PVector( -PITCH_LENGTH/2+PENALTY_AREA_LENGTH/2.0, 0.0 ), PVector( PENALTY_AREA_LENGTH, PENALTY_AREA_WIDTH )) ; static RArea p_r( PVector( +PITCH_LENGTH/2-PENALTY_AREA_LENGTH/2.0, 0.0 ), PVector( PENALTY_AREA_LENGTH, PENALTY_AREA_WIDTH ) ) ; double cal = ServerParam::instance().catch_area_l; RArea catchable( PVector( cal/2.0, 0.0 ), PVector( ServerParam::instance().catch_area_l, ServerParam::instance().catch_area_w ) ); PVector tmp; MPObject* ball = stadium->ball; alive |= CATCH; //pfr: we should only be able to catch in PlayOn mode //tom: actually the goalie can catch the ball in any playmode, but //infringements should be awarded. Maybe later. if ( !this->goalie || this->goalie_catch_ban || ( stadium->mode != PM_PlayOn && ! stadium->penaltyShootOut() )) /* stadium->mode == PM_BeforeKickOff || stadium->mode == PM_AfterGoal_Left || stadium->mode == PM_AfterGoal_Right || stadium->mode == PM_OffSide_Left || stadium->mode == PM_OffSide_Right || stadium->mode == PM_Back_Pass_Left || stadium->mode == PM_Back_Pass_Right || stadium->mode == PM_Free_Kick_Fault_Left || stadium->mode == PM_Free_Kick_Fault_Right ) */ { return; }// Tom: Catches can now occur an any position, but the ref will award and infringement if the ball is outside of the penalty area// switch (this->team->side)// {// case LEFT:// if ( !(p_l.inArea(this->pos)) ){// alive |= CATCH_FAULT;// return;// }// break;// case RIGHT:// if ( !(p_r.inArea(this->pos)) ){// alive |= CATCH_FAULT;// return;// }// break ;// } tmp = ball->pos - this->pos; tmp.rotate( -(this->angle + NormalizeMoment(dir)) ); if ( !(catchable.inArea(tmp) ) || ( drand(1,0) >= goalie_catch_probability) ) { alive |= CATCH_FAULT ; return ; } if( !ball->wasMultiKicked() && stadium->getPossibleBackPasser() != this && stadium->getPossibleBackPasser() != NULL && stadium->getPossibleBackPasser()->team == team && ServerParam::instance().backPasses() ) { stadium->confirmBackPasser(); stadium->backPass( team->side ); } else { this->goalie_catch_ban = ServerParam::instance().cban_cycle; relative_ball_ang = ball->pos - this->pos; relative_ball_ang /= relative_ball_ang.r(); goalie_moves_since_catch = 0; // reset the number of times the goalie moved stadium->goalie_catch( this ); stadium->ballCaught( *this ); } count_catch++; command_done = TRUE; }}void Player::say( std::string message ){ if( message.size() > ServerParam::instance().sayMsgSize() ){ return; } stadium->sendPlayerAudio( *this, message.c_str() ); count_say++;}void Player::sense_body(){ if ( alive != DISABLE && connected () ) { sendBody(); return; } if ( alive != DISABLE && connected () ) { if ( version >= 8.0 ) send ( BodySensor_v8::data_t ( *this ) ); else if ( version >= 7.0 ) send ( BodySensor_v7::data_t ( *this ) ); else if ( version >= 6.0 ) send ( BodySensor_v6::data_t ( *this ) ); else if ( version >= 5.0 ) send ( BodySensor_v5::data_t ( *this ) ); else send ( BodySensor_v1::data_t ( *this ) ); }}void Player::score(){ sendScore();// std::ostrstream ost;// ost << "(score " << stadium->time
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -