bool CFBTeam::canShootDirectly(CFBPlayer* player) { auto side = getSide(); auto pitch = FBMATCH->getPitch(); auto otherSide = pitch->getOtherSide(side); auto gp = pitch->getGoalPos(otherSide); auto otherTeam = FBMATCH->getTeam(otherSide); auto teamMember = otherTeam->getTeamMembers(); for (auto t : teamMember) { if (FBDefs::isPointOnTheWay(player->getPosition(), gp, t->getPosition())) { return false; } } teamMember = getTeamMembers(); for (auto t : teamMember) { if (t != player && FBDefs::isPointOnTheWay(player->getPosition(), gp, t->getPosition())) { return false; } } return true; }
int CFBTeam::getNumberOfDefenderBetweenPlayerAndBall(CFBPlayer* player) { int num = 0; auto side = getSide(); auto pitch = FBMATCH->getPitch(); auto otherSide = pitch->getOtherSide(side); auto& ballPos = FBMATCH->getBallPosition(); auto otherTeam = FBMATCH->getTeam(otherSide); auto teamMember = otherTeam->getTeamMembers(); for (auto t : teamMember) { if (FBDefs::isPointOnTheWay(player->getPosition(), ballPos, t->getPosition())) { num++; } } return num; }
int CFBTeam::getNumberOfDefenderAroundPlayer(CFBPlayer* player) { int num = 0; auto side = getSide(); auto pitch = FBMATCH->getPitch(); auto otherSide = pitch->getOtherSide(side); auto otherTeam = FBMATCH->getTeam(otherSide); auto teamMember = otherTeam->getTeamMembers(); float sizeSq = FBDefs::DEFENDER_PLAYER_RADIUS * FBDefs::DEFENDER_PLAYER_RADIUS; for (auto t : teamMember) { float dist = t->getPosition().getDistanceSq(player->getPosition()); if (dist < sizeSq) { num++; } } return num; }
void BattleController::entityAttack(GameEntity* entity,int col,int row,int side) { CCLOG("entityAttack id:%d,col:%d,row:%d,side:%d",entity->m_uID,col,row,side); //取得普通攻击目标 //取得对立的一方 int oppSide=getOtherSide(side); GameEntity* target=getAttackTarget(col, row, oppSide); if (target) { MessageManager* messageManager=Game::getInstance()->getMessageManager(); messageManager->registerReceiver(entity, kMSGEntityAttackComplete, NULL, message_selector(BattleController::onEntityAttackComplete),this); messageManager->dispatchMessage(MSG_ATTACK, NULL, entity,target); }else{ //如果没有目标,说明对方已经打光。 doBattleEnd(side==kSelfSide); } }
void CFBMatch::tryShootBall(CFBPlayer* shooter, bool isAir) { auto team = shooter->getOwnerTeam(); auto size = team->getSide(); auto pitch = FBMATCH->getPitch(); auto otherSide = pitch->getOtherSide(size); auto otherTeam = FBMATCH->getTeam(otherSide); auto& otherTeamMembers = otherTeam->getTeamMembers(); Point goalPos = pitch->getGoalPos(otherSide); if (isAir) { m_currentInstruction = INS_FAC->getShootBallAirIns(); } else { m_currentInstruction = INS_FAC->getShootBallGroundIns(); } m_currentInstruction->addPlayer(shooter); for (auto x : m_defendPlayerIds) { auto pO = otherTeam->getPlayer(x); int roll = RANDOM_MGR->getRand() % 300; if (roll > 200) { pO->setInstruction(FBDefs::PLAYER_INS::TAKCLE); } else if (roll > 100) { pO->setInstruction(FBDefs::PLAYER_INS::INTERCEPT); } else { pO->setInstruction(FBDefs::PLAYER_INS::BLOCK); } m_currentInstruction->addPlayer(pO); } auto& fpos = shooter->getPosition(); vector<pair<float, CFBPlayer*>> involvePlayers; CFBPlayer* goalKeeper = nullptr; for (auto player : otherTeamMembers) { if (player->m_isGoalKeeper) { goalKeeper = player; } else { auto it = std::find(m_defendPlayerIds.begin(), m_defendPlayerIds.end(), player->m_positionInFormation); if (it == m_defendPlayerIds.end()) { auto& ppos = player->getPosition(); if (FBDefs::isPointOnTheWay(fpos, goalPos, ppos)) { float dist = fpos.getDistanceSq(ppos); involvePlayers.push_back(pair<float, CFBPlayer*>(dist, player)); } } } } std::sort(involvePlayers.begin(), involvePlayers.end(), [&](const pair<float, CFBPlayer*>& o1, const pair<float, CFBPlayer*> o2)-> bool { return o1.first < o2.first; }); for (auto a : involvePlayers) { auto pO = a.second; int roll = RANDOM_MGR->getRand() % 300; if (roll > 200) { pO->setInstruction(FBDefs::PLAYER_INS::TAKCLE); } else if (roll > 100) { pO->setInstruction(FBDefs::PLAYER_INS::INTERCEPT); } else { pO->setInstruction(FBDefs::PLAYER_INS::BLOCK); } m_currentInstruction->addPlayer(pO); } CC_ASSERT(goalKeeper); int roll = RANDOM_MGR->getRand() % 1000; if (roll > 500) { goalKeeper->setInstruction(FBDefs::PLAYER_INS::HIT); } else { goalKeeper->setInstruction(FBDefs::PLAYER_INS::TAKE); } m_currentInstruction->addPlayer(goalKeeper); m_currentInstruction->start(bind(&CFBMatch::onInstructionEnd, this)); pauseGame(true); }
void CFBTeam::updateFieldStatusOnAttack() { auto pitch = FBMATCH->getPitch(); auto pp = getHilightPlayer(); CC_ASSERT(pp && pp->m_isBallController); float sizeSq = FBDefs::PASS_BALL_REDUCTION * FBDefs::PASS_BALL_REDUCTION; vector<int> gridsAroundPlayer; for (auto player : m_teamMembers) { auto ai = player->getBrain(); ai->setPassBallScore(INT_MIN); auto& pos = player->getPosition(); if (!player->m_isGoalKeeper && pp != player) { ai->setPassBallScore(0); // can shoot directly? if (canShootDirectly(player)) { ai->increasePassBallScore(50); } int num = getNumberOfDefenderBetweenPlayerAndBall(player); ai->increasePassBallScore(-20 * num); num = getNumberOfDefenderAroundPlayer(player); ai->increasePassBallScore(-10 * num); float dist = pp->getPosition().getDistanceSq(pos); if (dist > sizeSq) { ai->increasePassBallScore((dist - sizeSq) * (-1)); } } if (pitch->getGridsAroundPosition(pos, gridsAroundPlayer)) { for (auto gid : gridsAroundPlayer) { pitch->increaseGridDefenceScore(gid, -10); } } } auto side = getSide(); auto otherSide = pitch->getOtherSide(side); auto otherTeam = FBMATCH->getTeam(otherSide); auto teamMembers = otherTeam->getTeamMembers(); for (auto player : teamMembers) { if (pitch->getGridsAroundPosition(player->getPosition(), gridsAroundPlayer)) { for (auto gid : gridsAroundPlayer) { pitch->increaseGridDefenceScore(gid, -20); } } } }