bool COrder_Still::AutoAttackStand(CUnit &unit) { if (unit.Type->CanAttack == false) { return false; } // Removed units can only attack in AttackRange, from bunker CUnit *autoAttackUnit = AttackUnitsInRange(unit); if (autoAttackUnit == NULL) { return false; } // If unit is removed, use containers x and y const CUnit *firstContainer = unit.Container ? unit.Container : &unit; if (firstContainer->MapDistanceTo(*autoAttackUnit) > unit.Stats->Variables[ATTACKRANGE_INDEX].Max) { return false; } if (GameSettings.Inside && CheckObstaclesBetweenTiles(unit.tilePos, autoAttackUnit->tilePos, MapFieldRocks | MapFieldForest) == false) { return false; } this->State = SUB_STILL_ATTACK; // Mark attacking. this->SetGoal(autoAttackUnit); UnitHeadingFromDeltaXY(unit, autoAttackUnit->tilePos + autoAttackUnit->Type->GetHalfTileSize() - unit.tilePos); return true; }
CUnit *AttackUnitsInRange(const CUnit &unit) { return AttackUnitsInRange(unit, NoFilter()); }
/** ** Auto attack nearby units if possible */ static void AutoAttack(CUnit *unit, bool stand_ground) { CUnit *temp; CUnit *goal; if (unit->Wait) { unit->Wait--; return; } // Cowards don't attack unless ordered. if (unit->Type->CanAttack && !unit->Type->Coward) { // Normal units react in reaction range. if (CanMove(unit) && !unit->Removed && !stand_ground) { if ((goal = AttackUnitsInReactRange(unit))) { // Weak goal, can choose other unit, come back after attack CommandAttack(unit, goal->X, goal->Y, NULL, FlushCommands); Assert(unit->SavedOrder.Action == UnitActionStill); Assert(!unit->SavedOrder.Goal); unit->SavedOrder.Action = UnitActionAttack; unit->SavedOrder.Range = 0; unit->SavedOrder.X = unit->X; unit->SavedOrder.Y = unit->Y; unit->SavedOrder.Goal = NoUnitP; } else { unit->Wait = 15; } // Removed units can only attack in AttackRange, from bunker } else if ((goal = AttackUnitsInRange(unit))) { temp = unit->Orders[0]->Goal; if (temp && temp->Orders[0]->Action == UnitActionDie) { temp->RefsDecrease(); unit->Orders[0]->Goal = temp = NoUnitP; } if (!unit->SubAction || temp != goal) { // New target. if (temp) { temp->RefsDecrease(); } unit->Orders[0]->Goal = goal; goal->RefsIncrease(); unit->State = 0; unit->SubAction = 1; // Mark attacking. UnitHeadingFromDeltaXY(unit, goal->X + (goal->Type->TileWidth - 1) / 2 - unit->X, goal->Y + (goal->Type->TileHeight - 1) / 2 - unit->Y); } return; } } else { unit->Wait = 15; } if (unit->SubAction) { // was attacking. if ((temp = unit->Orders[0]->Goal)) { temp->RefsDecrease(); unit->Orders[0]->Goal = NoUnitP; } unit->SubAction = unit->State = 0; // No attacking, restart } Assert(!unit->Orders[0]->Goal); }
bool COrder_Still::AutoAttackStand(CUnit &unit) { //Wyrmgus start // if (unit.Type->CanAttack == false) { if (unit.CanAttack() == false) { //Wyrmgus end return false; } // Removed units can only attack in AttackRange, from bunker //Wyrmgus start //if unit is in a container which is attacking, and the container has a goal, use that goal (if possible) instead // CUnit *autoAttackUnit = AttackUnitsInRange(unit); CUnit *autoAttackUnit = unit.Container && unit.Container->CurrentAction() == UnitActionAttack && unit.Container->CurrentOrder()->HasGoal() ? unit.Container->CurrentOrder()->GetGoal() : AttackUnitsInRange(unit); //Wyrmgus end if (autoAttackUnit == nullptr) { return false; } // If unit is removed, use container's x and y const CUnit *firstContainer = unit.GetFirstContainer(); if (firstContainer->MapDistanceTo(*autoAttackUnit) > unit.GetModifiedVariable(ATTACKRANGE_INDEX)) { return false; } //Wyrmgus start // if (GameSettings.Inside && CheckObstaclesBetweenTiles(unit.tilePos, autoAttackUnit->tilePos, MapFieldRocks | MapFieldForest) == false) { if (Map.IsLayerUnderground(autoAttackUnit->MapLayer->ID) && unit.GetModifiedVariable(ATTACKRANGE_INDEX) > 1 && CheckObstaclesBetweenTiles(unit.tilePos, autoAttackUnit->tilePos, MapFieldAirUnpassable, autoAttackUnit->MapLayer->ID) == false) { //Wyrmgus end return false; } this->State = SUB_STILL_ATTACK; // Mark attacking. this->SetGoal(autoAttackUnit); //Wyrmgus start // UnitHeadingFromDeltaXY(unit, autoAttackUnit->tilePos + autoAttackUnit->Type->GetHalfTileSize() - unit.tilePos); UnitHeadingFromDeltaXY(unit, PixelSize(PixelSize(autoAttackUnit->tilePos) * Map.GetMapLayerPixelTileSize(autoAttackUnit->MapLayer->ID)) + autoAttackUnit->GetHalfTilePixelSize() - PixelSize(PixelSize(unit.tilePos) * Map.GetMapLayerPixelTileSize(autoAttackUnit->MapLayer->ID)) - unit.GetHalfTilePixelSize()); //Wyrmgus end return true; }