[*] Generic AI collision detection for blocked units
[-] Fixed AI transporter attack
This commit is contained in:
parent
c560b02922
commit
18a82e0e3e
2 changed files with 38 additions and 19 deletions
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue