[*] Generic AI collision detection for blocked units

[-] Fixed AI transporter attack
This commit is contained in:
cybermind 2014-10-28 18:05:43 +05:00
parent c560b02922
commit 18a82e0e3e
2 changed files with 38 additions and 19 deletions

View file

@ -833,8 +833,8 @@ static void AiMoveUnitInTheWay(CUnit &unit)
AiPlayer = unit.Player->Ai;
// No more than 1 move per cycle ( avoid stressing the pathfinder )
if (GameCycle == AiPlayer->LastCanNotMoveGameCycle) {
// No more than 1 move per 3 cycle ( avoid stressing the pathfinder )
if (GameCycle <= AiPlayer->LastCanNotMoveGameCycle + 3) {
return;
}
@ -869,15 +869,11 @@ static void AiMoveUnitInTheWay(CUnit &unit)
const Vec2i b0 = blocker.tilePos;
const Vec2i b1(b0.x + blockertype.TileWidth - 1, b0.y + blockertype.TileHeight - 1);
// Check for collision
if (!((u0.x == b1.x + 1 || u1.x == b0.x - 1)
&& (std::max<int>(b0.y, u0.y) <= std::min<int>(b1.y, u1.y)))
&& !((u0.y == b1.y + 1 || u1.y == b0.y - 1)
&& (std::max<int>(b0.x, u0.x) <= std::min<int>(b1.x, u1.x)))) {
if (&unit == &blocker) {
continue;
}
if (&unit == &blocker) {
// Check for collision
if (unit.MapDistanceTo(blocker) >= 2) {
continue;
}
@ -933,8 +929,7 @@ void AiCanNotMove(CUnit &unit)
const int gh = unit.pathFinderData->input.GetGoalSize().y;
AiPlayer = unit.Player->Ai;
if (unit.Type->UnitType == UnitTypeFly
|| PlaceReachable(unit, goalPos, gw, gh, minrange, maxrange)) {
if (PlaceReachable(unit, goalPos, gw, gh, 0, 255)) {
// Path probably closed by unit here
AiMoveUnitInTheWay(unit);
}

View file

@ -853,7 +853,39 @@ void AiForce::Update()
AiGroupAttackerForTransport(*this);
return ;
}
if (State == AiForceAttackingState_AttackingWithTransporter) {
// Move transporters to goalpos
std::vector<CUnit *> transporters;
bool emptyTrans = true;
for (unsigned int i = 0; i != Size(); ++i) {
CUnit &aiunit = *Units[i];
if (aiunit.CanMove() && aiunit.Type->MaxOnBoard) {
transporters.push_back(&aiunit);
if (aiunit.BoardCount > 0) {
emptyTrans = false;
}
}
}
if (transporters.empty()) {
// Our transporters have been destroyed
DebugPrint("%d: Attack force #%lu has lost all agresive units, giving up\n"
_C_ AiPlayer->Player->Index _C_(long unsigned int)(this - & (AiPlayer->Force[0])));
Reset(true);
} else if (emptyTrans) {
// We have emptied our transporters, go go go
State = AiForceAttackingState_GoingToRallyPoint;
} else {
for (size_t i = 0; i != transporters.size(); ++i) {
CUnit &trans = *transporters[i];
const int delay = i / 5; // To avoid lot of CPU consuption, send them with a small time difference.
trans.Wait = delay;
CommandUnload(trans, this->GoalPos, NULL, FlushCommands);
}
}
return;
}
CUnit *leader = NULL;
for (unsigned int i = 0; i != Size(); ++i) {
CUnit &aiunit = *Units[i];
@ -905,14 +937,6 @@ void AiForce::Update()
aiunit.Wait = delay;
if (aiunit.IsAgressive()) {
CommandAttack(aiunit, this->GoalPos, NULL, FlushCommands);
} else if (aiunit.Type->CanTransport()) {
if (aiunit.BoardCount != 0) {
CommandUnload(aiunit, this->GoalPos, NULL, FlushCommands);
} else {
// FIXME : Retrieve unit blocked (transport previously full)
CommandMove(aiunit, aiunit.Player->StartPos, FlushCommands);
this->Remove(aiunit);
}
} else {
if (leader) {
CommandDefend(aiunit, *leader, FlushCommands);