* Checks for another unit available for targeting and what particular voxel. * @param originVoxel Voxel of trace origin (eye or gun's barrel). * @param tile The tile to check for. * @param scanVoxel is returned coordinate of hit. * @param excludeUnit is self (not to hit self). * @param potentialUnit is a hypothetical unit to draw a virtual line of fire for AI. if left blank, this function beh
| 530 | * @return True if the unit can be targetted. |
| 531 | */ |
| 532 | bool TileEngine::canTargetUnit(Position *originVoxel, Tile *tile, Position *scanVoxel, BattleUnit *excludeUnit, BattleUnit *potentialUnit) |
| 533 | { |
| 534 | Position targetVoxel = Position((tile->getPosition().x * 16) + 7, (tile->getPosition().y * 16) + 8, tile->getPosition().z * 24); |
| 535 | std::vector<Position> _trajectory; |
| 536 | bool hypothetical = potentialUnit != 0; |
| 537 | if (potentialUnit == 0) |
| 538 | { |
| 539 | potentialUnit = tile->getUnit(); |
| 540 | if (potentialUnit == 0) return false; //no unit in this tile, even if it elevated and appearing in it. |
| 541 | } |
| 542 | |
| 543 | if (potentialUnit == excludeUnit) return false; //skip self |
| 544 | |
| 545 | int targetMinHeight = targetVoxel.z - tile->getTerrainLevel(); |
| 546 | targetMinHeight += potentialUnit->getFloatHeight(); |
| 547 | |
| 548 | int targetMaxHeight = targetMinHeight; |
| 549 | int targetCenterHeight; |
| 550 | // if there is an other unit on target tile, we assume we want to check against this unit's height |
| 551 | int heightRange; |
| 552 | |
| 553 | int unitRadius = potentialUnit->getLoftemps(); //width == loft in default loftemps set |
| 554 | int targetSize = potentialUnit->getArmor()->getSize() - 1; |
| 555 | int xOffset = potentialUnit->getPosition().x - tile->getPosition().x; |
| 556 | int yOffset = potentialUnit->getPosition().y - tile->getPosition().y; |
| 557 | if (targetSize > 0) |
| 558 | { |
| 559 | unitRadius = 3; |
| 560 | } |
| 561 | // vector manipulation to make scan work in view-space |
| 562 | Position relPos = targetVoxel - *originVoxel; |
| 563 | float normal = unitRadius/sqrt((float)(relPos.x*relPos.x + relPos.y*relPos.y)); |
| 564 | int relX = floor(((float)relPos.y)*normal+0.5); |
| 565 | int relY = floor(((float)-relPos.x)*normal+0.5); |
| 566 | |
| 567 | int sliceTargets[10]={0,0, relX,relY, -relX,-relY, relY,-relX, -relY,relX}; |
| 568 | |
| 569 | if (!potentialUnit->isOut()) |
| 570 | { |
| 571 | heightRange = potentialUnit->getHeight(); |
| 572 | } |
| 573 | else |
| 574 | { |
| 575 | heightRange = 12; |
| 576 | } |
| 577 | |
| 578 | targetMaxHeight += heightRange; |
| 579 | targetCenterHeight=(targetMaxHeight+targetMinHeight)/2; |
| 580 | heightRange/=2; |
| 581 | if (heightRange>10) heightRange=10; |
| 582 | if (heightRange<=0) heightRange=0; |
| 583 | |
| 584 | // scan ray from top to bottom plus different parts of target cylinder |
| 585 | for (int i = 0; i <= heightRange; ++i) |
| 586 | { |
| 587 | scanVoxel->z=targetCenterHeight+heightFromCenter[i]; |
| 588 | for (int j = 0; j < 5; ++j) |
| 589 | { |
no test coverage detected