1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-02-03 13:01:33 +02:00

IsHexInRangeLimit() is now a common function

Plus some minor rearranging of code.
This commit is contained in:
krs 2023-06-18 12:45:36 +03:00
parent 1ba9a2a42a
commit 1cba41a3c3
2 changed files with 42 additions and 29 deletions

View File

@ -136,8 +136,8 @@ BattleFieldController::BattleFieldController(BattleInterface & owner):
shootingRangeLimitImages = std::make_shared<CAnimation>("battle/rangeHighlights/rangeHighlightsRed.json");
shootingRangeLimitImages->preload();
flipRangedFullDamageLimitImagesIntoPositions(rangedFullDamageLimitImages);
flipRangedFullDamageLimitImagesIntoPositions(shootingRangeLimitImages);
flipRangeLimitImagesIntoPositions(rangedFullDamageLimitImages);
flipRangeLimitImagesIntoPositions(shootingRangeLimitImages);
if(!owner.siegeController)
{
@ -446,6 +446,8 @@ std::set<BattleHex> BattleFieldController::getHighlightedHexesForMovementTarget(
return {};
}
#pragma region Range limit highlight helpers
std::vector<BattleHex> BattleFieldController::getRangeHexes(BattleHex sourceHex, uint8_t distance)
{
std::vector<BattleHex> rangeHexes; // used for return
@ -478,6 +480,20 @@ std::vector<BattleHex> BattleFieldController::getRangeLimitHexes(BattleHex hover
return limitHexes;
}
bool BattleFieldController::IsHexInRangeLimit(BattleHex hex, std::vector<BattleHex> & rangeLimitHexes, int * hexIndexInRangeLimit)
{
bool hexInRangeLimit = false;
if(!rangeLimitHexes.empty())
{
auto pos = std::find(rangeLimitHexes.begin(), rangeLimitHexes.end(), hex);
*hexIndexInRangeLimit = std::distance(rangeLimitHexes.begin(), pos);
hexInRangeLimit = pos != rangeLimitHexes.end();
}
return hexInRangeLimit;
}
std::vector<std::vector<BattleHex::EDir>> BattleFieldController::getOutsideNeighbourDirectionsForLimitHexes(std::vector<BattleHex> wholeRangeHexes, std::vector<BattleHex> rangeLimitHexes)
{
std::vector<std::vector<BattleHex::EDir>> output;
@ -511,7 +527,7 @@ std::vector<std::vector<BattleHex::EDir>> BattleFieldController::getOutsideNeigh
return output;
}
std::vector<std::shared_ptr<IImage>> BattleFieldController::calculateRangeHighlightImages(std::vector<std::vector<BattleHex::EDir>> hexesNeighbourDirections, std::shared_ptr<CAnimation> limitImages)
std::vector<std::shared_ptr<IImage>> BattleFieldController::calculateRangeLimitHighlightImages(std::vector<std::vector<BattleHex::EDir>> hexesNeighbourDirections, std::shared_ptr<CAnimation> limitImages)
{
std::vector<std::shared_ptr<IImage>> output; // if no image is to be shown an empty image is still added to help with traverssing the range
@ -538,10 +554,10 @@ void BattleFieldController::calculateRangeLimitAndHighlightImages(uint8_t distan
std::vector<BattleHex> rangeHexes = getRangeHexes(hoveredHex, distance);
rangeLimitHexes = getRangeLimitHexes(hoveredHex, rangeHexes, distance);
std::vector<std::vector<BattleHex::EDir>> rangeLimitNeighbourDirections = getOutsideNeighbourDirectionsForLimitHexes(rangeHexes, rangeLimitHexes);
rangeLimitHexesHighligts = calculateRangeHighlightImages(rangeLimitNeighbourDirections, rangeLimitImages);
rangeLimitHexesHighligts = calculateRangeLimitHighlightImages(rangeLimitNeighbourDirections, rangeLimitImages);
}
void BattleFieldController::flipRangedFullDamageLimitImagesIntoPositions(std::shared_ptr<CAnimation> images)
void BattleFieldController::flipRangeLimitImagesIntoPositions(std::shared_ptr<CAnimation> images)
{
images->getImage(hexEdgeMaskToFrameIndex[HexMasks::topRight])->verticalFlip();
images->getImage(hexEdgeMaskToFrameIndex[HexMasks::right])->verticalFlip();
@ -561,8 +577,16 @@ void BattleFieldController::flipRangedFullDamageLimitImagesIntoPositions(std::sh
images->getImage(hexEdgeMaskToFrameIndex[HexMasks::bottomLeftCorner])->horizontalFlip();
}
#pragma endregion
void BattleFieldController::showHighlightedHexes(Canvas & canvas)
{
std::vector<BattleHex> rangedFullDamageLimitHexes;
std::vector<BattleHex> shootingRangeLimitHexes;
std::vector<std::shared_ptr<IImage>> rangedFullDamageLimitHexesHighligts;
std::vector<std::shared_ptr<IImage>> shootingRangeLimitHexesHighligts;
std::set<BattleHex> hoveredStackMovementRangeHexes = getMovementRangeForHoveredStack();
std::set<BattleHex> hoveredSpellHexes = getHighlightedHexesForSpellRange();
std::set<BattleHex> hoveredMoveHexes = getHighlightedHexesForMovementTarget();
@ -573,12 +597,6 @@ void BattleFieldController::showHighlightedHexes(Canvas & canvas)
const CStack * hoveredStack = getHoveredStack();
std::vector<BattleHex> rangedFullDamageLimitHexes;
std::vector<BattleHex> shootingRangeLimitHexes;
std::vector<std::shared_ptr<IImage>> rangedFullDamageLimitHexesHighligts;
std::vector<std::shared_ptr<IImage>> shootingRangeLimitHexesHighligts;
// skip range limit calculations if unit hovered is not a shooter
if(hoveredStack && hoveredStack->isShooter())
{
@ -599,24 +617,12 @@ void BattleFieldController::showHighlightedHexes(Canvas & canvas)
bool mouse = hoveredMouseHexes.count(hex);
// calculate if hex is Ranged Full Damage Limit and its position in highlight array
bool isRangedFullDamageLimit = false;
int hexIndexInRangedFullDamageLimit = 0;
if(!rangedFullDamageLimitHexes.empty())
{
auto pos = std::find(rangedFullDamageLimitHexes.begin(), rangedFullDamageLimitHexes.end(), hex);
hexIndexInRangedFullDamageLimit = std::distance(rangedFullDamageLimitHexes.begin(), pos);
isRangedFullDamageLimit = pos != rangedFullDamageLimitHexes.end();
}
bool hexInRangedFullDamageLimit = IsHexInRangeLimit(hex, rangedFullDamageLimitHexes, &hexIndexInRangedFullDamageLimit);
// calculate if hex is Shooting Range Limit and its position in highlight array
bool isShootingRangeLimit = false;
int hexIndexInShootingRangeLimit = 0;
if(!shootingRangeLimitHexes.empty())
{
auto pos = std::find(shootingRangeLimitHexes.begin(), shootingRangeLimitHexes.end(), hex);
hexIndexInShootingRangeLimit = std::distance(shootingRangeLimitHexes.begin(), pos);
isShootingRangeLimit = pos != shootingRangeLimitHexes.end();
}
bool hexInShootingRangeLimit = IsHexInRangeLimit(hex, shootingRangeLimitHexes, &hexIndexInShootingRangeLimit);
if(stackMovement && mouse) // area where hovered stackMovement can move shown with highlight. Because also affected by mouse cursor, shade as well
{
@ -631,11 +637,11 @@ void BattleFieldController::showHighlightedHexes(Canvas & canvas)
{
showHighlightedHex(canvas, cellUnitMovementHighlight, hex, false);
}
if(isRangedFullDamageLimit)
if(hexInRangedFullDamageLimit)
{
showHighlightedHex(canvas, rangedFullDamageLimitHexesHighligts[hexIndexInRangedFullDamageLimit], hex, false);
}
if(isShootingRangeLimit)
if(hexInShootingRangeLimit)
{
showHighlightedHex(canvas, shootingRangeLimitHexesHighligts[hexIndexInShootingRangeLimit], hex, false);
}

View File

@ -60,25 +60,32 @@ class BattleFieldController : public CIntObject
std::set<BattleHex> getHighlightedHexesForSpellRange();
std::set<BattleHex> getHighlightedHexesForMovementTarget();
#pragma region Range limit highlight helpers
/// get all hexes within a certain distance of given hex
std::vector<BattleHex> getRangeHexes(BattleHex sourceHex, uint8_t distance);
/// get only hexes at the limit of a range
std::vector<BattleHex> getRangeLimitHexes(BattleHex hoveredHex, std::vector<BattleHex> hexRange, uint8_t distanceToLimit);
/// calculate if a hex is in range limit and return its index in range
bool IsHexInRangeLimit(BattleHex hex, std::vector<BattleHex> & rangedFullDamageLimitHexes, int * hexIndexInRangeLimit);
/// get an array that has for each hex in range, an aray with all directions where an ouside neighbour hex exists
std::vector<std::vector<BattleHex::EDir>> getOutsideNeighbourDirectionsForLimitHexes(std::vector<BattleHex> rangedFullDamageHexes, std::vector<BattleHex> rangedFullDamageLimitHexes);
/// calculates what image to use as range limit, depending on the direction of neighbors
/// a mask is used internally to mark the directions of all neighbours
/// based on this mask the corresponding image is selected
std::vector<std::shared_ptr<IImage>> calculateRangeHighlightImages(std::vector<std::vector<BattleHex::EDir>> hexesNeighbourDirections, std::shared_ptr<CAnimation> limitImages);
std::vector<std::shared_ptr<IImage>> calculateRangeLimitHighlightImages(std::vector<std::vector<BattleHex::EDir>> hexesNeighbourDirections, std::shared_ptr<CAnimation> limitImages);
/// calculates all hexes for a range limit and what images to be shown as highlight for each of the hexes
void calculateRangeLimitAndHighlightImages(uint8_t distance, std::shared_ptr<CAnimation> rangedFullDamageLimitImages, std::vector<BattleHex> & rangedFullDamageLimitHexes, std::vector<std::shared_ptr<IImage>> & rangedFullDamageLimitHexesHighligts);
/// to reduce the number of source images used, some images will be used as flipped versions of preloaded ones
void flipRangedFullDamageLimitImagesIntoPositions(std::shared_ptr<CAnimation> images);
void flipRangeLimitImagesIntoPositions(std::shared_ptr<CAnimation> images);
#pragma endregion
void showBackground(Canvas & canvas);
void showBackgroundImage(Canvas & canvas);