void SoccerFormation::update_defend_formation(SoccerTeam *team) { SoccerBall *ball = team->get_match()->get_ball(); int ball_x = (int) ball->get_pos().x; int ball_y = (int) ball->get_pos().y; /* 后防线的基準座標 */ double index_x; /* 是否已經進入禁區了 */ int is_hot = 0; /* 球在大禁區的之內 */ if (ball_x <= A_FORBIDDEN_AREA_X) { index_x = MIDDLE_CIRCLE_B; } else if (ball_x <= (39.5 * 12) && ball_x > A_FORBIDDEN_AREA_X) { index_x = DEFEND_LINE_SEC; } else if (ball_x > (39.5 * 12) && ball_x <= DEFEND_LINE_SEC) { index_x = (((ball_x - 39.5 * 12) / (26 * 12)) * ((B_FORBIDDEN_AREA_X - 3 * METER_TO_POINT) - DEFEND_LINE_SEC)) + DEFEND_LINE_SEC; } else if (ball_x > DEFEND_LINE_SEC && ball_x <= B_FORBIDDEN_AREA_X) { index_x = (((ball_x - DEFEND_LINE_SEC) / (B_FORBIDDEN_AREA_X - DEFEND_LINE_SEC)) * (6 * METER_TO_POINT)) + B_FORBIDDEN_AREA_X; is_hot = 1; } else if (ball_x > B_FORBIDDEN_AREA_X && ball_x <= PITCH_WIDTH) { index_x = PITCH_WIDTH - (ball_x - B_FORBIDDEN_AREA_X) / (PITCH_WIDTH - B_FORBIDDEN_AREA_X) * 11 * METER_TO_POINT; is_hot = 1; } if(index_x > (PITCH_WIDTH - OUTSIDE_WIDTH - 2 * METER_TO_POINT)){ index_x = PITCH_WIDTH - OUTSIDE_WIDTH - 2 * METER_TO_POINT; } if(index_x < (MIDDLE_CIRCLE_B)){ index_x = MIDDLE_CIRCLE_B; } int mod_y = 0; mod_y = (((ball_y - PITCH_HEIGHT / 2) * 216) / (PITCH_HEIGHT / 2)); int ball_left_or_right = 0; if (ball_y < A_FORBIDDEN_AREA_Y) { ball_left_or_right = 1; } else if (ball_y > (A_GOAL_HEIGHT + FORBIDDEN_AREA_HEIGHT / 2)) { ball_left_or_right = -1; } int player_dis = 10; //TODO 如果球队喊话中有散开的话,三条线拉开12米(不影响进攻),横向7米 if(team->check_coach_speak(SPEAK_MORE_SPACE)){ player_dis = player_dis + 12/3; }else if(team->check_coach_speak(SPEAK_LESS_SPACE)){//三条线拉开8米(不影响进攻),横向5米 player_dis = player_dis + 8/3; } for (int i = 0; i < team->get_players_on_pitch_count(); ++i) { SoccerPlayer *pPlayer = team->get_player_on_pitch(i); int region_id = _position[i] - 1; SoccerRegion region = _region[region_id]; int region_width = (int) (region.x2 - region.x1); int region_height = (int) (region.y2 - region.y1); SoccerRegion tmpRegion; Vector2D vecPos; vecPos.x = (index_x - ((team->getBackLine() - (pPlayer->get_formation_pos() - 1) / 5) * player_dis * METER_TO_POINT)); vecPos.y = pPlayer->_init_pos.y + mod_y; if (ball_left_or_right == 0) { if (pPlayer->get_formation_pos() == 26 || pPlayer->get_formation_pos() == 30) { vecPos.x = vecPos.x - 2 * METER_TO_POINT; } } else if (ball_left_or_right == 1) { if (pPlayer->get_formation_pos() % 5 == 1) { vecPos.x = vecPos.x - 5 * METER_TO_POINT; } } else if (ball_left_or_right == -1) { if (pPlayer->get_formation_pos() % 5 == 0) { vecPos.x = vecPos.x - 5 * METER_TO_POINT; } } /* 假如突入大禁區,像中間收縮 */ if (is_hot == 1) { if (pPlayer->get_formation_pos() == 26) { vecPos.y = vecPos.y - 8 * METER_TO_POINT; } else if (pPlayer->get_formation_pos() == 27) { vecPos.y = vecPos.y - 5 * METER_TO_POINT; } else if (pPlayer->get_formation_pos() == 28) { vecPos.y = vecPos.y + 0 * METER_TO_POINT; } else if (pPlayer->get_formation_pos() == 29) { vecPos.y = vecPos.y + 5 * METER_TO_POINT; } else if (pPlayer->get_formation_pos() == 30) { vecPos.y = vecPos.y + 8 * METER_TO_POINT; } } region.x1 = vecPos.x - region_width / 2; region.x2 = vecPos.x + region_width / 2; region.x1 = vecPos.x - region_width / 2; region.x2 = vecPos.x + region_width / 2; region.y1 = vecPos.y - region_height / 2; region.y2 = vecPos.y + region_height / 2; region.fix_to_pitch(); pPlayer->set_home(region); tmpRegion.x1 = pPlayer->get_pos().x - 80; tmpRegion.x2 = pPlayer->get_pos().x + 30; tmpRegion.y1 = pPlayer->get_pos().y - 1 * 60; tmpRegion.y2 = pPlayer->get_pos().y + 1 * 60; tmpRegion.fix_to_pitch(); team->get_player_on_pitch(i)->set_markArea(tmpRegion); tmpRegion.x1 = pPlayer->get_pos().x - 17 * METER_TO_POINT; tmpRegion.x2 = pPlayer->get_pos().x + 3 * METER_TO_POINT; tmpRegion.y1 = pPlayer->get_pos().y - 7 * METER_TO_POINT; tmpRegion.y2 = pPlayer->get_pos().y + 7 * METER_TO_POINT; tmpRegion.fix_to_pitch(); team->get_player_on_pitch(i)->set_mindArea(tmpRegion); } player_modifer_formation_speak(team); }
void BallGoalFlyState::execute(SoccerBall &b){ b.set_motion_type(SoccerBall::GOAL_FLY); b.move(); }
void SoccerFormation::update_attack_formation(SoccerTeam *team) { // static double x_offset_factor[] = { 0, 0.5, 0.5, 0.5, 0, 0.8, 0.75, 0.75, 0.75, // 0.8, 1, 0.5, 0.6, 0.5, 1, 1, 1.2, 1.2, 1.2, 1, 1.75, 0.75, 0.75, // 0.75, 1.75, 1.5, 0.5, 0.5, 0.5, 1.5, 0, 0.5, 0.5, 0.5, 0 }; static double x_offset_factor[] = { 0, 0.25, 0.25, 0.25, 0, 0.4, 0.3, 0.3, 0.3, 0.4, 0.5, 0.25, 0.3, 0.25, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 1, 0.75, 0.75,0.75, 1, 1.5, 0.5, 0.5, 0.5, 1.5, 0, 0.5, 0.5, 0.5, 0 }; SoccerBall *ball = team->get_match()->get_ball(); int ball_x = (int) ball->get_pos().x; int ball_y = (int) ball->get_pos().y; double tmp = PITCH_WIDTH / 2; //拿到最后一个后卫线 for (int i = 0; i < team->get_players_on_pitch_count(); ++i) { SoccerPlayer *pPlayer = team->get_player_on_pitch(i); if (_position[i] >= 27 && _position[i] <= 29) { if (tmp > pPlayer->get_pos().x) { tmp = pPlayer->get_pos().x; } } else if ((_position[i] >= 32 && _position[i] <= 34)) { if (tmp > pPlayer->get_pos().x) { tmp = pPlayer->get_pos().x; } } } double dx = ball_x - tmp;//ball to last defense line double dy = ball_y - PITCH_HEIGHT / 2; for (int i = 0; i < team->get_players_on_pitch_count(); ++i) { SoccerPlayer *pPlayer = team->get_player_on_pitch(i); int region_id = _position[i] - 1; SoccerRegion region = _region[region_id]; int region_width = (int) (region.x2 - region.x1); int region_height = (int) (region.y2 - region.y1); region.x1 += (dx * x_offset_factor[region_id]); region.x2 += (dx * x_offset_factor[region_id]); if (_position[i] == 21) { region.x1 = tmp + 15 * METER_TO_POINT; region.x2 = tmp + 25 * METER_TO_POINT; } else if (_position[i] == 25) { region.x1 = tmp + 15 * METER_TO_POINT; region.x2 = tmp + 25 * METER_TO_POINT; } else if (_position[i] == 26) { region.x1 = tmp + 10 * METER_TO_POINT; region.x2 = tmp + 20 * METER_TO_POINT; } else if (_position[i] == 30) { region.x1 = tmp + 10 * METER_TO_POINT; region.x2 = tmp + 20 * METER_TO_POINT; } if (region.x2 > PITCH_WIDTH - OUTSIDE_WIDTH) { region.x2 = PITCH_WIDTH - OUTSIDE_WIDTH; region.x1 = region.x2 - region_width; } else if (region.x1 < OUTSIDE_WIDTH) { region.x1 = OUTSIDE_WIDTH; region.x2 = region.x1 + region_width; } //进攻球员根据move typ偏移 fix_formation_by_move_order(pPlayer->get_formation_pos(), region); //120是球员之间间距的合理值 region.y1 += ((dy / (PITCH_HEIGHT / 2)) * 100); region.y2 += ((dy / (PITCH_HEIGHT / 2)) * 100); if (region.y2 > PITCH_HEIGHT - OUTSIDE_HEIGHT) { region.y2 = PITCH_HEIGHT - OUTSIDE_HEIGHT; region.y1 = region.y2 - region_height; } else if (region.y1 < OUTSIDE_HEIGHT) { region.y1 = OUTSIDE_HEIGHT; region.y2 = region.y1 + region_height; } double y = pPlayer->get_middle_modifer(); region.y1 += y; region.y2 += y; pPlayer->set_home(region); } player_modifer_formation_speak(team); }
////////////////////////////// // BallCrossState void BallCrossState::execute(SoccerBall &b) { b.move(); }
void BallDribbledState::execute(SoccerBall &b) { b.move(); }
////////////////////////////// //FreeState void FreeState::execute(SoccerBall &b) { b.move_free(); }
////////////////////////////// //CornerState void CornerState::execute(SoccerBall &b) { b.move_corner(); }
////////////////////////////// // PenaltyState void PenaltyState::execute(SoccerBall &b) { b.move_penalty(); }
////////////////////////////// // BallRollState void BallRollState::execute(SoccerBall &b) { b.move(); }
void GlobalBallState::on_message(SoccerBall &b, Telegram *message) { BallTelegram *ball_msg = (BallTelegram *)message; switch (ball_msg->message) { case TELE_BALL_KICK: { b.kick(ball_msg->speed, ball_msg->heading); b.set_state(BallRollState::alloc()); } break; case TELE_BALL_CROSS: { b.cross(ball_msg->speed, ball_msg->speed_z, ball_msg->heading); b.set_state(BallCrossState::alloc()); } break; case TELE_BALL_STOP: { b.set_speed(0); b.set_state(BallStopState::alloc()); } break; case TELE_PLAYER_PENALTY: { b.set_speed(0); b.set_state(PenaltyState::alloc()); } break; case TELE_PLAYER_FREE: { b.set_speed(0); b.set_state(FreeState::alloc()); } break; case TELE_PLAYER_CORNER: { b.set_speed(0); b.set_state(CornerState::alloc()); } break; case TELE_BALL_GOAL_FLY: { b.set_speed(ball_msg->speed); b.set_state(BallGoalFlyState::alloc()); } break; default: { } break; } }
///////////////////////// // GlobalBallState void GlobalBallState::execute(SoccerBall &b) { SoccerPlayer *owner = b.get_owner(); if (owner != NULL) { if (b.get_motion_type() == SoccerBall::STOP) { b.set_motion_type(SoccerBall::MOVE); } else if (b.get_motion_type() == SoccerBall::MOVE) { b.set_motion_type(SoccerBall::START_DRIBBLE); } else if (b.get_motion_type() == SoccerBall::OUTSIZE) { b.set_motion_type(SoccerBall::OUTSIZE); } else if (b.get_motion_type() == SoccerBall::PENALTY) { b.set_pos(B_PENALTY_LOCATION_X, B_PENALTY_LOCATION_Y); b.set_speed(0); b.set_motion_type(SoccerBall::PENALTY); b.set_state(PenaltyState::alloc()); return; } else if (b.get_motion_type() == SoccerBall::FREE) { b.set_pos(b.get_boll_start_pos().x, b.get_boll_start_pos().y); b.set_speed(0); b.set_motion_type(SoccerBall::FREE); b.set_state(FreeState::alloc()); return; } else if (b.get_motion_type() == SoccerBall::CORNER) { b.set_pos(b.get_boll_start_pos().x, b.get_boll_start_pos().y); b.set_speed(0); b.set_motion_type(SoccerBall::CORNER); b.set_state(CornerState::alloc()); return; }/*else if(b.get_motion_type() == SoccerBall::GOAL_FLY){ b.set_motion_type(SoccerBall::GOAL_FLY); b.set_state(); }*/ else { b.set_motion_type(SoccerBall::DRIBBLE); if ((abs((int)(b.get_pos().x - owner->get_pos().x))<2)&&(abs((int)(b.get_pos().x - owner->get_pos().x))<2)) { b.set_speed_add(1); } if ((abs((int)(b.get_pos().x - owner->get_pos().x))>10)||(abs((int)(b.get_pos().x - owner->get_pos().x))>10)) { b.set_speed_add(-1); } b.set_speed(owner->get_speed()); b.set_heading(owner->get_heading()); if (b.get_speed_add() == 1) { b.set_pos(b.get_pos() + b.get_heading() * owner->get_speed()); } else { b.set_pos(b.get_pos() - b.get_heading() * owner->get_speed()); } return; } b.set_heading(owner->get_heading()); b.set_speed(owner->get_speed()); b.set_pos(owner->get_pos()); } }
void SoccerGoal::OnTouchNotify( HOBJECT hObj ) { CollisionInfo colInfo; DVector vBallVel; DBOOL bGoal; SoccerBall *pSoccerBall; DVector vPos, vDir, vDims; HOBJECT hPlayer; LMessage *pMsg; if( g_pServerDE->IsKindOf( g_pServerDE->GetObjectClass(hObj), m_hSoccerBall )) { pSoccerBall = ( SoccerBall * )g_pServerDE->HandleToObject( hObj ); if( !pSoccerBall ) return; // Already recorded this goal. Ball should delete itself soon. if( pSoccerBall->IsMadeGoal( )) return; // Ball has to enter from correct side for directional goals if( m_bDirectional ) { // Assume no goal bGoal = DFALSE; g_pServerDE->GetVelocity( hObj, &vBallVel ); // Check if going in the right direction if( VEC_DOT( vBallVel, m_vGoalDirection ) > 0.0f ) { bGoal = DTRUE; } } else bGoal = DTRUE; if( bGoal ) { if(( hPlayer = pSoccerBall->GetLastPlayerTouched( )) == DNULL ) return; // Send message to player and ball if( g_pServerDE->Common( )->CreateMessage( pMsg ) != LT_OK ) return; pMsg->WriteByte( m_nTeamID ); g_pServerDE->SendToObject( *pMsg, MID_GOAL, m_hObject, hPlayer, 0 ); g_pServerDE->SendToObject( *pMsg, MID_GOAL, m_hObject, hObj, 0 ); pMsg->Release(); // Create special effects g_pServerDE->GetObjectPos( hObj, &vPos ); g_pServerDE->GetVelocity( hObj, &vDir ); VEC_MULSCALAR( vDir, vDir, -1.0f ); VEC_SET( vDims, 25.0f, 25.0f, 25.0f ); SetupClientGibFX( &vPos, &vDir, &vDims, ( SURFTYPE_FLESH/10 ) | SIZE_SMALL | TRAIL_BLOOD, 1.0f, 5 ); // Play the sound if( m_hstrScoreSound ) { g_pServerDE->GetObjectPos( m_hObject, &vPos ); PlaySoundFromPos( &vPos, g_pServerDE->GetStringData( m_hstrScoreSound ), m_fRadius, SOUNDPRIORITY_MISC_MEDIUM ); } SendTrigger( ); } } }