📄 referee.cc
字号:
} else if( M_stadium.player[i]->team->side == RIGHT ) { x = -ServerParam::instance().ka_length * 0.5 + drand( 0, 3 ); y = ServerParam::instance().ka_width * 0.5 - drand( 0, 3 ); M_stadium.player[i]->place( PVector( x, y ) ); } } } M_stadium.set_ball( PVector( -ServerParam::instance().ka_length * 0.5 + 4.0, -ServerParam::instance().ka_width * 0.5 + 4.0 ), NEUTRAL); M_take_time = 0;}//************// CatchRef//************voidCatchRef::analyse(){ if( M_stadium.penaltyShootOut( ) ) return; if( M_stadium.M_caught_ball && !M_stadium.check_goal() && M_stadium.mode != PM_AfterGoal_Left && M_stadium.mode != PM_AfterGoal_Right && M_stadium.mode != PM_TimeOver && !inPenaltyArea( M_stadium.M_caught_ball->team->side, M_stadium.ball->pos ) ) { callCatchFault( -M_stadium.M_caught_ball->team->side, M_stadium.ball->pos ); } }voidCatchRef::ballCaught( Player& catcher ){ if( M_stadium.penaltyShootOut( ) ) return; if( !M_stadium.check_goal() && M_stadium.mode != PM_AfterGoal_Left && M_stadium.mode != PM_AfterGoal_Right && M_stadium.mode != PM_TimeOver && !inPenaltyArea( catcher.team->side, M_stadium.ball->pos ) ) { callCatchFault( -catcher.team->side, M_stadium.ball->pos ); } else { M_stadium.M_caught_ball = &catcher; awardFreeKick( catcher.team->side, M_stadium.ball->pos ); }}//************// PenaltyRef//************voidPenaltyRef::analyse(){ static char *PlayModeString[] = PLAYMODE_STRINGS; static bool bFirstTime = true; // if normal and extra time are over -> start the penalty procedure or quit if( ( ServerParam::instance().halfTime() < 0 && ( ServerParam::instance().nr_normal_halfs + ServerParam::instance().nr_extra_halfs == 0 ) || ( M_stadium.time >= ServerParam::instance().halfTime() * ( ServerParam::instance().nr_normal_halfs + ServerParam::instance().nr_extra_halfs ) ) ) && ServerParam::instance().penalty_shoot_outs && M_stadium.team_l->point == M_stadium.team_r->point && bFirstTime && M_stadium.mode != PM_BeforeKickOff ) { if( ServerParam::instance().penalty_shoot_outs ) { if( drand( 0, 1 ) < 0.5 ) // choose random side of the playfield M_pen_side = LEFT; // and inform players else M_pen_side = RIGHT; M_stadium.say( (M_pen_side == LEFT ) ? "penalty_onfield_l" : "penalty_onfield_r" ); // choose at random who starts (note that in penalty_init, actually the // opposite player is chosen since there the playMode changes) M_cur_pen_taker = ( drand(0,1) < 0.5 ) ? LEFT : RIGHT ; // place the goalkeeper of the opposite field close to the penalty goal // otherwise it is hard to get there before pen_setup_wait cycles Side side = (M_pen_side == LEFT ) ? RIGHT : LEFT ; for ( int i = 0 ; i < 2 * MAX_PLAYER ; i++) { if ( M_stadium.player[i]->alive != DISABLE && M_stadium.player[i]->team->side == side && M_stadium.player[i]->goalie ) M_stadium.player[i]->pos = PVector(-M_pen_side*(PITCH_LENGTH/2-10),10); } penalty_init(); bFirstTime = false; } else { M_stadium.say("time_up") ; M_stadium.change_play_mode(PM_TimeOver); return; } } PlayMode pm = M_stadium.mode; if( M_stadium.penaltyShootOut( ) ) { int iPenTakerLeft, iPenTakerRight; bool bCheckLeft = penalty_check_players( LEFT , &iPenTakerLeft ); bool bCheckRight = penalty_check_players( RIGHT, &iPenTakerRight ); if( M_bDebug ) cerr << "timer " << PlayModeString[M_stadium.mode] << " " << M_stadium.time << " " << M_timer << " " << bCheckLeft << " " << bCheckRight << endl; // if ready or taken make sure all players keep well-positioned if( ( pm == PM_PenaltyReady_Left || pm == PM_PenaltyReady_Right || pm == PM_PenaltyTaken_Left || pm == PM_PenaltyTaken_Right ) && ServerParam::instance().pen_coach_moves_players ) { if( bCheckLeft == false ) penalty_place_all_players( LEFT, &iPenTakerLeft ); if( bCheckRight == false ) penalty_place_all_players( RIGHT, &iPenTakerRight ); bCheckLeft = bCheckRight = true; } if( M_bDebug ) cerr << "after placement" ; if( M_timer < 0 ) cerr << "(PenaltyRef::analyse) timer cannot be negative?" << endl; else if( M_timer == 0 ) { if( M_bDebug ) cerr << M_stadium.time << " timer reached zero" << endl; // when setup has finished and still players are positioned incorrectly // replace them and go to ready mode. if( ServerParam::instance().pen_coach_moves_players && ( pm == PM_PenaltySetup_Left || pm == PM_PenaltySetup_Right ) && ( bCheckLeft == false || bCheckRight == false ) ) { if( bCheckLeft == false ) penalty_place_all_players( LEFT, &iPenTakerLeft ); if( bCheckRight == false ) penalty_place_all_players( RIGHT, &iPenTakerRight ); bCheckLeft = bCheckRight = true; } if( pm == PM_PenaltyMiss_Left || pm == PM_PenaltyScore_Left || pm == PM_PenaltyMiss_Right || pm == PM_PenaltyScore_Right ) { penalty_init( ); } else if( bCheckLeft == true && bCheckRight == true) { if( pm == PM_PenaltySetup_Left ) { M_stadium.change_play_mode( PM_PenaltyReady_Left ); } else if( pm == PM_PenaltySetup_Right ) { M_stadium.change_play_mode( PM_PenaltyReady_Right ); } // time elapsed -> missed goal else if( pm == PM_PenaltyTaken_Left || pm == PM_PenaltyReady_Left ) penalty_miss( LEFT ); else if( pm == PM_PenaltyTaken_Right || pm == PM_PenaltyReady_Right ) penalty_miss( RIGHT ); } // if incorrect positioned , place them correctly else if( M_cur_pen_taker == LEFT ) // && bCheckLeft == false ) { penalty_foul( ( bCheckLeft == false ) ? LEFT : RIGHT ); } else if( M_cur_pen_taker == RIGHT ) { penalty_foul( ( bCheckRight == false ) ? RIGHT : LEFT ); } } else { M_timer--;// cerr << "time " << M_stadium.time << " " << pm << endl; if( pm == PM_PenaltyScore_Left || pm == PM_PenaltyScore_Right || pm == PM_PenaltyMiss_Left || pm == PM_PenaltyMiss_Right ) return; else if( bCheckLeft == true && bCheckRight == true) { // if ball crossed goalline, process goal and set ball on goalline if( M_stadium.cross_gline( M_pen_side ) ) { if( pm == PM_PenaltyTaken_Left ) penalty_score( LEFT ); else if( pm == PM_PenaltyTaken_Right ) penalty_score( RIGHT ); // set the ball M_stadium.set_ball(M_stadium.ball->pos, M_pen_side ); } else if( /* M_stadium.M_caught_ball != NULL || */ // moved to PenaltyRef::ballCaught fabs( M_stadium.ball->pos.x ) > PITCH_LENGTH * 0.5 + ServerParam::instance().bsize ) { if( M_bDebug ) cerr << "MISSED" << endl; // if( M_stadium.M_caught_ball == NULL ) M_stadium.set_ball(M_stadium.ball->pos, M_pen_side ); if( pm == PM_PenaltyTaken_Left ) penalty_miss( LEFT ); else if( pm == PM_PenaltyTaken_Right ) penalty_miss( RIGHT ); } } // if someone makes foul and we are not in setup -> replace the players else if( pm == PM_PenaltyReady_Left || pm == PM_PenaltyReady_Right || pm == PM_PenaltyTaken_Left || pm == PM_PenaltyTaken_Right ) { if( ServerParam::instance().pen_coach_moves_players ) { if( bCheckLeft == false ) penalty_place_all_players( LEFT ); if( bCheckRight == false ) penalty_place_all_players( RIGHT ); } else penalty_foul( (bCheckLeft == false) ? LEFT : RIGHT ); } } }}voidPenaltyRef::ballCaught( Player& ){ if( M_stadium.penaltyShootOut() ) { if( M_bDebug ) cerr << "GOALIE CATCH" << endl; if( M_stadium.mode == PM_PenaltyTaken_Left ) penalty_miss( LEFT ); else if( M_stadium.mode == PM_PenaltyTaken_Right ) penalty_miss( RIGHT ); M_stadium.ball->vel.x = M_stadium.ball->vel.y = 0; }}voidPenaltyRef::kickTaken( Player& kicker ){ if( M_stadium.penaltyShootOut( ) ) { if( M_bDebug ) cerr << "kick taken in mode " << M_stadium.mode << endl; if( M_stadium.M_caught_ball != NULL ) cerr << "player kicked and goalie catched at the same time" << endl; // if in setup it is not allowed to kick the ball else if( M_stadium.mode == PM_PenaltySetup_Left || M_stadium.mode == PM_PenaltySetup_Right ) penalty_foul( kicker.team->side ); // left cannot kick second time after penalty was taken else if( M_stadium.mode == PM_PenaltyTaken_Left && kicker.team->side == LEFT && ServerParam::instance().pen_allow_mult_kicks == false ) penalty_foul( LEFT ); // right cannot kick second time after penalty was taken else if( M_stadium.mode == PM_PenaltyTaken_Right && kicker.team->side == RIGHT && ServerParam::instance().pen_allow_mult_kicks == false ) penalty_foul( RIGHT ); // if we were ready for penalty -> change play mode if( M_stadium.mode == PM_PenaltyReady_Left ) { // when penalty is taken, add player, multiple copies are deleted M_sLeftPenTaken.insert( kicker.unum ); if( M_sLeftPenTaken.size() == MAX_PLAYER ) M_sLeftPenTaken.clear(); M_stadium.change_play_mode( PM_PenaltyTaken_Left ); } else if( M_stadium.mode == PM_PenaltyReady_Right ) { M_sRightPenTaken.insert( kicker.unum ); if( M_sRightPenTaken.size() == MAX_PLAYER ) M_sRightPenTaken.clear(); M_stadium.change_play_mode( PM_PenaltyTaken_Right ); } // if it was not allowed to kick, don't move ball else if( M_stadium.mode != PM_PenaltyTaken_Left && M_stadium.mode != PM_PenaltyTaken_Right ) M_stadium.set_ball(M_stadium.ball->pos, M_pen_side ); }}voidPenaltyRef::playModeChange( PlayMode pm ){ // if mode changes, reset the timer if( M_stadium.penaltyShootOut( ) ) { if( pm == PM_PenaltySetup_Left || pm == PM_PenaltySetup_Right ) M_timer = ServerParam::instance().pen_setup_wait; else if( pm == PM_PenaltyReady_Left || pm == PM_PenaltyReady_Right ) M_timer = ServerParam::instance().pen_ready_wait; else if( pm == PM_PenaltyTaken_Left || pm == PM_PenaltyTaken_Right ) M_timer = ServerParam::instance().pen_taken_wait; else if( pm == PM_PenaltyMiss_Left || pm == PM_PenaltyMiss_Right || pm == PM_PenaltyScore_Right || pm == PM_PenaltyScore_Right ) M_timer = ServerParam::instance().pen_before_setup_wait; }}void PenaltyRef::penalty_init(){ if( M_bDebug ) cerr << "init penalty" << endl; PlayMode pm = M_stadium.mode; // change the play mode such that the other side can take the penalty // and place the ball at the penalty spot M_cur_pen_taker = (M_cur_pen_taker == LEFT ) ? RIGHT : LEFT ; pm = (M_cur_pen_taker== LEFT) ? PM_PenaltySetup_Left : PM_PenaltySetup_Right ; M_stadium.placeBall( pm, NEUTRAL, PVector(-M_pen_side*(PITCH_LENGTH/2-ServerParam::instance().pen_dist_x),0)); return;}void PenaltyRef::penalty_score( Side side ){// M_stadium.say( (side==LEFT) ? "penalty_score_l" : "penalty_score_r" ); M_stadium.change_play_mode( (side==RIGHT) ? PM_PenaltyScore_Right : PM_PenaltyScore_Left ); if( side == RIGHT ) { M_stadium.team_r->pen_point++; M_stadium.team_r->pen_taken++; } else { M_stadium.team_l->pen_point++; M_stadium.team_l->pen_taken++; } M_pen_nr_taken++; penalty_check_score();}void PenaltyRef::penalty_miss( Side side ){// M_stadium.say( (side==LEFT) ? "penalty_miss_l" : "penalty_miss_r"); M_stadium.change_play_mode( (side==LEFT) ? PM_PenaltyMiss_Left : PM_PenaltyMiss_Right ); M_pen_nr_taken++; if( side == RIGHT ) { M_stadium.team_r->pen_taken++; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -