* Finds a fitting node where a unit can patrol to. * @param scout Is the unit scouting? * @param unit Pointer to the unit (to get its position). * @param fromNode Pointer to the node the unit is at. * @return Pointer to the choosen node. */
| 1136 | * @return Pointer to the choosen node. |
| 1137 | */ |
| 1138 | Node *SavedBattleGame::getPatrolNode(bool scout, BattleUnit *unit, Node *fromNode) |
| 1139 | { |
| 1140 | std::vector<Node *> compliantNodes; |
| 1141 | Node *preferred = 0; |
| 1142 | |
| 1143 | if (fromNode == 0) |
| 1144 | { |
| 1145 | if (Options::traceAI) { Log(LOG_INFO) << "This alien got lost. :("; } |
| 1146 | fromNode = getNodes()->at(RNG::generate(0, getNodes()->size() - 1)); |
| 1147 | } |
| 1148 | |
| 1149 | // scouts roam all over while all others shuffle around to adjacent nodes at most: |
| 1150 | const int end = scout ? getNodes()->size() : fromNode->getNodeLinks()->size(); |
| 1151 | |
| 1152 | for (int i = 0; i < end; ++i) |
| 1153 | { |
| 1154 | if (!scout && fromNode->getNodeLinks()->at(i) < 1) continue; |
| 1155 | |
| 1156 | Node *n = getNodes()->at(scout ? i : fromNode->getNodeLinks()->at(i)); |
| 1157 | if ((n->getFlags() > 0 || n->getRank() > 0 || scout) // for non-scouts we find a node with a desirability above 0 |
| 1158 | && (!(n->getType() & Node::TYPE_SMALL) || unit->getArmor()->getSize() == 1) // the small unit bit is not set or the unit is small |
| 1159 | && (!(n->getType() & Node::TYPE_FLYING) || unit->getArmor()->getMovementType() == MT_FLY) // the flying unit bit is not set or the unit can fly |
| 1160 | && !n->isAllocated() // check if not allocated |
| 1161 | && !(n->getType() & Node::TYPE_DANGEROUS) // don't go there if an alien got shot there; stupid behavior like that |
| 1162 | && setUnitPosition(unit, n->getPosition(), true) // check if not already occupied |
| 1163 | && getTile(n->getPosition()) && !getTile(n->getPosition())->getFire() // you are not a firefighter; do not patrol into fire |
| 1164 | && (unit->getFaction() != FACTION_HOSTILE || !getTile(n->getPosition())->getDangerous()) // aliens don't run into a grenade blast |
| 1165 | && (!scout || n != fromNode) // scouts push forward |
| 1166 | && n->getPosition().x > 0 && n->getPosition().y > 0) |
| 1167 | { |
| 1168 | if (!preferred |
| 1169 | || (preferred->getRank() == Node::nodeRank[unit->getRankInt()][0] && preferred->getFlags() < n->getFlags()) |
| 1170 | || preferred->getFlags() < n->getFlags()) |
| 1171 | { |
| 1172 | preferred = n; |
| 1173 | } |
| 1174 | compliantNodes.push_back(n); |
| 1175 | } |
| 1176 | } |
| 1177 | |
| 1178 | if (compliantNodes.empty()) |
| 1179 | { |
| 1180 | if (Options::traceAI) { Log(LOG_INFO) << (scout ? "Scout " : "Guard") << " found on patrol node! XXX XXX XXX"; } |
| 1181 | if (unit->getArmor()->getSize() > 1 && !scout) |
| 1182 | { |
| 1183 | return getPatrolNode(true, unit, fromNode); // move dammit |
| 1184 | } |
| 1185 | else |
| 1186 | return 0; |
| 1187 | } |
| 1188 | |
| 1189 | if (scout) |
| 1190 | { |
| 1191 | // scout picks a random destination: |
| 1192 | return compliantNodes[RNG::generate(0, compliantNodes.size() - 1)]; |
| 1193 | } |
| 1194 | else |
| 1195 | { |
no test coverage detected