📄 field.c
字号:
// PVector(PENALTY_AREA_LENGTH, PENALTY_AREA_WIDTH)) ;// if (!(pta.inArea(goalie->pos)))// goalie->pos = pta.nearestEdge(goalie->pos) ;}void Stadium::check_field_before_goalkick(){ 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)) ; RArea* fld ; int oppside ; if (mode == PM_GoalKick_Left) { oppside = RIGHT ; fld = &p_l ; } else { oppside = LEFT ; fld = &p_r ; } int i ; for (i = 0 ; i < MAX_PLAYER * 2 ; i++) { if (player[i]->alive == DISABLE) continue ; if (player[i]->team->side == oppside) { if ((fld->inArea(player[i]->pos))) player[i]->pos = fld->nearestEdge(player[i]->pos) ; if ( player[i]->pos.x * oppside >= PITCH_LENGTH/2) player[i]->pos.x = (PITCH_LENGTH/2 - PENALTY_AREA_LENGTH) * oppside ; } } if(!(fld->inArea(ball->pos))){ check_player_in_field() ; //change_play_mode(PM_PlayOn) ; Moved to FreeKickRef }}void Stadium::set_players(){ static RArea fld_l(PVector(-PITCH_LENGTH/4,0.0), PVector(PITCH_LENGTH/2, PITCH_WIDTH)) ; static RArea fld_r(PVector(PITCH_LENGTH/4,0.0), PVector(PITCH_LENGTH/2, PITCH_WIDTH)) ; static CArea c(PVector(0.0,0.0),KICK_OFF_CLEAR_DISTANCE) ; int i ; c.center = ball->pos ; for (i = 0 ; i < MAX_PLAYER * 2; i++) { if (player[i]->alive == DISABLE) continue ; switch (player[i]->team->side) { case LEFT: if(!(fld_l.inArea(player[i]->pos))) player[i]->pos = fld_l.randomize() ; break ; case RIGHT: if(!(fld_r.inArea(player[i]->pos))) player[i]->pos = fld_r.randomize() ; break ; } if(player[i]->team->side != kick_off_side) if(c.inArea(player[i]->pos)) player[i]->pos = c.nearestEdge(player[i]->pos) ; }}void Stadium::recovery_players(){ int i ; for (i = 0 ; i < MAX_PLAYER * 2; i++) { if (player[i]->alive == DISABLE) continue ; player[i]->stamina = ServerParam::instance().stamina_max ; player[i]->recovery = 1.0 ; player[i]->effort = player[i]->player_type->effortMax () ; player[i]->hear_capacity_from_teammate = ServerParam::instance().hearMax(); player[i]->hear_capacity_from_opponent = ServerParam::instance().hearMax(); }}void Stadium::announce_goal(Team& tm){#ifdef HAVE_SSTREAM std::ostringstream msg; msg << "goal_" << SideStr(tm.side) << "_" << tm.point; say( msg.str().c_str() );#else std::ostrstream msg; msg << "goal_" << SideStr(tm.side) << "_" << tm.point << std::ends; say( msg.str() ); msg.freeze( false );#endif}BallPosInfo Stadium::check_ball_pos(){ static RArea g_l( PVector( ( -PITCH_LENGTH-GOAL_DEPTH )*0.5 - ServerParam::instance().bsize, 0.0 ), PVector( GOAL_DEPTH , ServerParam::instance().gwidth + ServerParam::instance().goalPostRadius() ) ); static RArea g_r( PVector( ( +PITCH_LENGTH+GOAL_DEPTH )*0.5 + ServerParam::instance().bsize, 0.0 ), PVector( GOAL_DEPTH, ServerParam::instance().gwidth + ServerParam::instance().goalPostRadius() ) ) ; static RArea pt( PVector( 0.0, 0.0 ), PVector( PITCH_LENGTH + ServerParam::instance().bsize * 2 , PITCH_WIDTH + ServerParam::instance().bsize * 2) ); if(g_l.inArea(ball->pos)) return BPI_GoalL ; if(g_r.inArea(ball->pos)) return BPI_GoalR ; if(!(pt.inArea(ball->pos))) return BPI_OutOfField ; return BPI_InField ;}Logical Stadium::cross_gline(Side side){// static double tmp ; if( prev_ball_pos.x == ball->pos.x ) { // ball cannot have crossed gline// std::cout << time << ": vertcal movement\n"; return false ; } if( fabs( ball->pos.x ) <= PITCH_LENGTH*0.5 + ServerParam::instance().bsize ) { // ball hasn't crossed gline// std::cout << time << ": hasn't crossed\n"; return false; } if( fabs( prev_ball_pos.x ) > PITCH_LENGTH*0.5 + ServerParam::instance().bsize ) { // ball aready over the gline// std::cout << time << ": already crossed\n"; return false; } if( ( side * ball->pos.x ) >= 0 ) { //ball in wrong half// std::cout << time << ": wrong_half\n"; return false; } if( fabs( prev_ball_pos.y ) > ( ServerParam::instance().gwidth*0.5 + ServerParam::instance().goalPostRadius() ) && fabs( prev_ball_pos.x ) > PITCH_LENGTH*0.5 ) { // then the only goal that could have been scored would be // from going behind the goal post. I'm pretty sure that // isn't possible anyway, but just in case this function acts // as a double check// std::cout << time << ": behind_half\n"; return false; } // this calculation determines the y co-ordinate where the ball actually crosses the goal line// tmp = ( ( ( prev_ball_pos.y - ball->pos.y )// * ( PITCH_LENGTH/2.0 + ServerParam::instance().bsize )// * ( -side )// + prev_ball_pos.x * ball->pos.y - ball->pos.x * prev_ball_pos.y )// / ( prev_ball_pos.x - ball->pos.x ) ) ; // new more readable (thus maintainable) version of the same calc // line => y = gradient * x + offset double delta_x = ball->pos.x - prev_ball_pos.x; double delta_y = ball->pos.y - prev_ball_pos.y; // we already checked above that ball->pos.x != prev_ball_pos.x, so delta_x cannot be zero. double gradient = delta_y / delta_x; double offset = prev_ball_pos.y - gradient * prev_ball_pos.x; // determine y for x = PITCH_LENGTH*0.5 + ServerParam::instance().bsize * -side double x = ( PITCH_LENGTH*0.5 + ServerParam::instance().bsize ) * -side; double y_intercept = gradient * x + offset;// std::cout << time << ": prev = " << prev_ball_pos << std::endl;// std::cout << time << ": curr = " << ball->pos << std::endl;// std::cout << time << ": delta_x = " << delta_x << std::endl;// std::cout << time << ": delta_y = " << delta_y << std::endl;// std::cout << time << ": grad = " << gradient << std::endl;// std::cout << time << ": off = " << offset << std::endl;// std::cout << time << ": x = " << x << std::endl;// std::cout << time << ": y_inter = " << y_intercept << std::endl; return fabs( y_intercept ) <= ( ServerParam::instance().gwidth*0.5 + ServerParam::instance().goalPostRadius() ); // if( tmp >= -ServerParam::instance().gwidth/2 && tmp <= ServerParam::instance().gwidth/2 )// return TRUE ;// else// return false ;}boolStadium::check_goal(){ if( mode == PM_AfterGoal_Left || mode == PM_AfterGoal_Right || mode == PM_TimeOver ) { return false; } if( m_indirect ) { return false; } // FIFA rules: Ball has to be completely outside of the pitch to be considered out// static RArea pt( PVector(0.0,0.0),// PVector( PITCH_LENGTH// + ServerParam::instance().bsize * 2,// PITCH_WIDTH// + ServerParam::instance().bsize * 2 ) ); if( fabs( ball->pos.x ) <= PITCH_LENGTH * 0.5 + ServerParam::instance().bsize ) { return false; } if( ( !M_caught_ball || M_caught_ball->team->side == LEFT ) && cross_gline( LEFT ) && !penaltyShootOut( ) ) { if (team_r) { team_r->point++ ; //renameLogs (); announce_goal(*team_r) ; after_g_time = 0 ; set_ball(ball->pos, LEFT) ; if( ServerParam::instance().halfTime() >= 0 && time >= ServerParam::instance().halfTime() * ServerParam::instance().nr_normal_halfs ) change_play_mode(PM_TimeOver) ; else { mode = PM_AfterGoal_Right ; dinfo.body.show.pmode = (char)PM_AfterGoal_Right ; dinfo2.body.show.pmode = (char)PM_AfterGoal_Right ; } } return true; } else if( ( !M_caught_ball || M_caught_ball->team->side == RIGHT ) && cross_gline( RIGHT ) && !penaltyShootOut( ) ) { if( team_l ) { team_l->point++ ; //renameLogs (); announce_goal(*team_l) ; after_g_time = 0 ; set_ball(ball->pos, RIGHT) ; if( ServerParam::instance().halfTime() >= 0 && time >= ServerParam::instance().halfTime() * ServerParam::instance().nr_normal_halfs ) change_play_mode(PM_TimeOver) ; else { mode = PM_AfterGoal_Left ; dinfo.body.show.pmode = (char)PM_AfterGoal_Left ; dinfo2.body.show.pmode = (char)PM_AfterGoal_Left ; } } return true; } return false;}bool Stadium::penaltyShootOut( Side side ){ bool bLeft = false, bRight = true; switch( mode ) { case PM_PenaltySetup_Left: case PM_PenaltyReady_Left: case PM_PenaltyTaken_Left: case PM_PenaltyMiss_Left: case PM_PenaltyScore_Left: bLeft = true; break; case PM_PenaltySetup_Right: case PM_PenaltyReady_Right: case PM_PenaltyTaken_Right: case PM_PenaltyMiss_Right: case PM_PenaltyScore_Right: bRight = true; break; default: return false; } if( side == NEUTRAL && ( bLeft == true || bRight == true ) ) return true; else if( side == LEFT && bLeft == true ) return true; else if( side == RIGHT && bRight == true ) return true; else return false;}void Stadium::check_ball_in_pitch(){ // move to touch ref}void Stadium::check_player_in_field(){ static RArea fld(PVector(0.0,0.0), PVector(PITCH_LENGTH+PITCH_MARGIN*2.0, PITCH_WIDTH+PITCH_MARGIN*2.0)) ; int i ; for (i = 0 ; i < MAX_PLAYER * 2; i++ ) { if (player[i]->alive == DISABLE) continue ; if(!(fld.inArea(player[i]->pos))) player[i]->pos = fld.nearestEdge(player[i]->pos) ; } if (mode != PM_PlayOn && mode != PM_GoalKick_Left && mode != PM_GoalKick_Right) { static CArea c(PVector(0.0,0.0), KICK_OFF_CLEAR_DISTANCE) ; c.center = ball->pos ; for(i = 0 ; i < MAX_PLAYER * 2; i++ ) { if (player[i]->alive == DISABLE) continue ; if(player[i]->team->side != kick_off_side) if(c.inArea(player[i]->pos)) player[i]->pos = c.nearestEdge(player[i]->pos) ; } } if (ServerParam::instance().kickoffoffside == TRUE) { if (mode == PM_KickOff_Left) { for(i = 0 ; i < MAX_PLAYER * 2 ; i++ ) { if (player[i]->alive == DISABLE) continue ; if(player[i]->team->side == kick_off_side) { if(player[i]->pos.x > 0) player[i]->pos.x = 0 ; } else { if(player[i]->pos.x < 0) player[i]->pos.x = 0 ; } } } if(mode == PM_KickOff_Right) { for(i = 0 ; i < MAX_PLAYER * 2 ; i++ ) { if (player[i]->alive == DISABLE) continue ; if(player[i]->team->side == kick_off_side) { if(player[i]->pos.x < 0) player[i]->pos.x = 0 ; } else { if(player[i]->pos.x > 0) player[i]->pos.x = 0 ; } } } }}void Stadium::change_play_mode(PlayMode pm){ static char *PlayModeString[] = PLAYMODE_STRINGS ; int i ; mode = pm ; dinfo.body.show.pmode = (char)pm ; dinfo2.body.show.pmode = (char)pm ; for_each( M_referees.begin(), M_referees.end(), Referee::doPlayModeChange( pm ) ); if( pm == PM_Free_Kick_Fault_Left || pm == PM_Free_Kick_Fault_Right ) M_after_free_kick_fault_time = 0; if( pm == PM_CatchFault_Left || pm == PM_CatchFault_Right ) m_after_catch_fault_time = 0; if (pm == PM_KickOff_Left || pm == PM_KickIn_Left || pm == PM_FreeKick_Left || pm == PM_IndFreeKick_Left || pm == PM_CornerKick_Left || pm == PM_GoalKick_Left) { kick_off_side = LEFT ; //since we decrement first, if this is <=0, we will never drop// drop_ball_time = ServerParam::instance().drop_time; clearPlayersFromBall( RIGHT ); } else if (pm == PM_KickOff_Right || pm == PM_KickIn_Right || pm == PM_FreeKick_Right || pm == PM_IndFreeKick_Right || pm == PM_CornerKick_Right || pm == PM_GoalKick_Right) { kick_off_side = RIGHT ; //since we decrement first, if this is <=0, we will never drop// drop_ball_time = ServerParam::instance().drop_time; clearPlayersFromBall( LEFT ); } else if (pm == PM_Drop_Ball) { clearPlayersFromBall( NEUTRAL ); kick_off_side = NEUTRAL ; } if( pm == PM_GoalKick_Left || pm == PM_GoalKick_Right ) { M_free_kicker = NULL; } if( pm != PM_PlayOn ) { for (i = 0; i < MAX_PLAYER * 2; i++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -