* Attempts to find cover, and move toward it. * The idea is to check within a 11x11 tile square for a tile which is not seen by our aggroTarget. * If there is no such tile, we run away from the target. * Fills out the _escapeAction with useful data. */
| 755 | * Fills out the _escapeAction with useful data. |
| 756 | */ |
| 757 | void AlienBAIState::setupEscape() |
| 758 | { |
| 759 | int unitsSpottingMe = getSpottingUnits(_unit->getPosition()); |
| 760 | int currentTilePreference = 15; |
| 761 | int tries = -1; |
| 762 | bool coverFound = false; |
| 763 | selectNearestTarget(); |
| 764 | _escapeTUs = 0; |
| 765 | |
| 766 | int dist = _aggroTarget ? _save->getTileEngine()->distance(_unit->getPosition(), _aggroTarget->getPosition()) : 0; |
| 767 | |
| 768 | int bestTileScore = -100000; |
| 769 | int score = -100000; |
| 770 | Position bestTile(0, 0, 0); |
| 771 | |
| 772 | Tile *tile = 0; |
| 773 | |
| 774 | // weights of various factors in choosing a tile to which to withdraw |
| 775 | const int EXPOSURE_PENALTY = 10; |
| 776 | const int FIRE_PENALTY = 40; |
| 777 | const int BASE_SYSTEMATIC_SUCCESS = 100; |
| 778 | const int BASE_DESPERATE_SUCCESS = 110; |
| 779 | const int FAST_PASS_THRESHOLD = 100; // a score that's good engouh to quit the while loop early; it's subjective, hand-tuned and may need tweaking |
| 780 | |
| 781 | std::vector<Position> randomTileSearch = _save->getTileSearch(); |
| 782 | RNG::shuffle(randomTileSearch); |
| 783 | |
| 784 | while (tries < 150 && !coverFound) |
| 785 | { |
| 786 | _escapeAction->target = _unit->getPosition(); // start looking in a direction away from the enemy |
| 787 | |
| 788 | if (!_save->getTile(_escapeAction->target)) |
| 789 | { |
| 790 | _escapeAction->target = _unit->getPosition(); // cornered at the edge of the map perhaps? |
| 791 | } |
| 792 | |
| 793 | score = 0; |
| 794 | |
| 795 | if (tries == -1) |
| 796 | { |
| 797 | // you know, maybe we should just stay where we are and not risk reaction fire... |
| 798 | // or maybe continue to wherever we were running to and not risk looking stupid |
| 799 | if (_save->getTile(_unit->lastCover) != 0) |
| 800 | { |
| 801 | _escapeAction->target = _unit->lastCover; |
| 802 | } |
| 803 | } |
| 804 | else if (tries < 121) |
| 805 | { |
| 806 | // looking for cover |
| 807 | _escapeAction->target.x += randomTileSearch[tries].x; |
| 808 | _escapeAction->target.y += randomTileSearch[tries].y; |
| 809 | score = BASE_SYSTEMATIC_SUCCESS; |
| 810 | if (_escapeAction->target == _unit->getPosition()) |
| 811 | { |
| 812 | if (unitsSpottingMe > 0) |
| 813 | { |
| 814 | // maybe don't stay in the same spot? move or something if there's any point to it? |
nothing calls this directly
no test coverage detected