mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-26 03:52:01 +02:00
HD mod highlighting of movement for hovered stack.
Does not work as intended in tactics mode.
This commit is contained in:
parent
e35a1ba471
commit
e1c388465a
BIN
Mods/vcmi/Data/CCNSSh2.png
Normal file
BIN
Mods/vcmi/Data/CCNSSh2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
BIN
Mods/vcmi/Data/CCNSShd.png
Normal file
BIN
Mods/vcmi/Data/CCNSShd.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 858 B |
@ -43,6 +43,7 @@ BattleFieldController::BattleFieldController(BattleInterface & owner):
|
|||||||
|
|
||||||
//preparing cells and hexes
|
//preparing cells and hexes
|
||||||
cellBorder = IImage::createFromFile("CCELLGRD.BMP", EImageBlitMode::COLORKEY);
|
cellBorder = IImage::createFromFile("CCELLGRD.BMP", EImageBlitMode::COLORKEY);
|
||||||
|
cellUnitMovementHighlight = IImage::createFromFile("CCNSSHD.BMP", EImageBlitMode::COLORKEY);
|
||||||
cellShade = IImage::createFromFile("CCELLSHD.BMP");
|
cellShade = IImage::createFromFile("CCELLSHD.BMP");
|
||||||
|
|
||||||
if(!owner.siegeController)
|
if(!owner.siegeController)
|
||||||
@ -138,7 +139,6 @@ void BattleFieldController::showBackground(Canvas & canvas)
|
|||||||
showBackgroundImage(canvas);
|
showBackgroundImage(canvas);
|
||||||
|
|
||||||
showHighlightedHexes(canvas);
|
showHighlightedHexes(canvas);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BattleFieldController::showBackgroundImage(Canvas & canvas)
|
void BattleFieldController::showBackgroundImage(Canvas & canvas)
|
||||||
@ -172,32 +172,39 @@ void BattleFieldController::redrawBackgroundWithHexes()
|
|||||||
{
|
{
|
||||||
const CStack *activeStack = owner.stacksController->getActiveStack();
|
const CStack *activeStack = owner.stacksController->getActiveStack();
|
||||||
std::vector<BattleHex> attackableHexes;
|
std::vector<BattleHex> attackableHexes;
|
||||||
if (activeStack)
|
if(activeStack)
|
||||||
occupyableHexes = owner.curInt->cb->battleGetAvailableHexes(activeStack, true, &attackableHexes);
|
occupyableHexes = owner.curInt->cb->battleGetAvailableHexes(activeStack, true, &attackableHexes);
|
||||||
|
|
||||||
//prepare background graphic with hexes and shaded hexes
|
auto accessibility = owner.curInt->cb->getAccesibility();
|
||||||
|
|
||||||
|
for(int i = 0; i < accessibility.size(); i++)
|
||||||
|
stackCountOutsideHexes[i] = (accessibility[i] == EAccessibility::ACCESSIBLE);
|
||||||
|
|
||||||
|
// prepare background graphic with hexes and shaded hexes
|
||||||
backgroundWithHexes->draw(background, Point(0,0));
|
backgroundWithHexes->draw(background, Point(0,0));
|
||||||
owner.obstacleController->showAbsoluteObstacles(*backgroundWithHexes);
|
owner.obstacleController->showAbsoluteObstacles(*backgroundWithHexes);
|
||||||
if ( owner.siegeController )
|
if(owner.siegeController)
|
||||||
owner.siegeController->showAbsoluteObstacles(*backgroundWithHexes);
|
owner.siegeController->showAbsoluteObstacles(*backgroundWithHexes);
|
||||||
|
|
||||||
if (settings["battle"]["stackRange"].Bool())
|
// show shaded hexes for active's stack valid movement and the hexes that it can attack
|
||||||
|
if(settings["battle"]["stackRange"].Bool())
|
||||||
{
|
{
|
||||||
std::vector<BattleHex> hexesToShade = occupyableHexes;
|
std::vector<BattleHex> hexesToShade = occupyableHexes;
|
||||||
hexesToShade.insert(hexesToShade.end(), attackableHexes.begin(), attackableHexes.end());
|
hexesToShade.insert(hexesToShade.end(), attackableHexes.begin(), attackableHexes.end());
|
||||||
for (BattleHex hex : hexesToShade)
|
for(BattleHex hex : hexesToShade)
|
||||||
{
|
{
|
||||||
backgroundWithHexes->draw(cellShade, hexPositionLocal(hex).topLeft());
|
backgroundWithHexes->draw(cellShade, hexPositionLocal(hex).topLeft());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// draw cell borders
|
||||||
if(settings["battle"]["cellBorders"].Bool())
|
if(settings["battle"]["cellBorders"].Bool())
|
||||||
{
|
{
|
||||||
for (int i=0; i<GameConstants::BFIELD_SIZE; ++i)
|
for(int i=0; i<GameConstants::BFIELD_SIZE; ++i)
|
||||||
{
|
{
|
||||||
if ( i % GameConstants::BFIELD_WIDTH == 0)
|
if(i % GameConstants::BFIELD_WIDTH == 0)
|
||||||
continue;
|
continue;
|
||||||
if ( i % GameConstants::BFIELD_WIDTH == GameConstants::BFIELD_WIDTH - 1)
|
if(i % GameConstants::BFIELD_WIDTH == GameConstants::BFIELD_WIDTH - 1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
backgroundWithHexes->draw(cellBorder, hexPositionLocal(i).topLeft());
|
backgroundWithHexes->draw(cellBorder, hexPositionLocal(i).topLeft());
|
||||||
@ -205,7 +212,7 @@ void BattleFieldController::redrawBackgroundWithHexes()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BattleFieldController::showHighlightedHex(Canvas & canvas, BattleHex hex, bool darkBorder)
|
void BattleFieldController::showShadedHex(Canvas & canvas, BattleHex hex, bool darkBorder)
|
||||||
{
|
{
|
||||||
Point hexPos = hexPositionLocal(hex).topLeft();
|
Point hexPos = hexPositionLocal(hex).topLeft();
|
||||||
|
|
||||||
@ -214,14 +221,23 @@ void BattleFieldController::showHighlightedHex(Canvas & canvas, BattleHex hex, b
|
|||||||
canvas.draw(cellBorder, hexPos);
|
canvas.draw(cellBorder, hexPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set<BattleHex> BattleFieldController::getHighlightedHexesStackRange()
|
void BattleFieldController::showHighlightedHexForMovement(Canvas & canvas, BattleHex hex, bool darkBorder)
|
||||||
|
{
|
||||||
|
Point hexPos = hexPositionLocal(hex).topLeft();
|
||||||
|
|
||||||
|
canvas.draw(cellUnitMovementHighlight, hexPos);
|
||||||
|
if(!darkBorder && settings["battle"]["cellBorders"].Bool())
|
||||||
|
canvas.draw(cellBorder, hexPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::set<BattleHex> BattleFieldController::getHighlightedHexesForActiveStack()
|
||||||
{
|
{
|
||||||
std::set<BattleHex> result;
|
std::set<BattleHex> result;
|
||||||
|
|
||||||
if ( !owner.stacksController->getActiveStack())
|
if(!owner.stacksController->getActiveStack())
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
if ( !settings["battle"]["stackRange"].Bool())
|
if(!settings["battle"]["stackRange"].Bool())
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
auto hoveredHex = getHoveredHex();
|
auto hoveredHex = getHoveredHex();
|
||||||
@ -230,7 +246,22 @@ std::set<BattleHex> BattleFieldController::getHighlightedHexesStackRange()
|
|||||||
for(BattleHex hex : set)
|
for(BattleHex hex : set)
|
||||||
result.insert(hex);
|
result.insert(hex);
|
||||||
|
|
||||||
// display the movement shadow of stack under mouse
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::set<BattleHex> BattleFieldController::getMovementRangeForHoveredStack()
|
||||||
|
{
|
||||||
|
std::set<BattleHex> result;
|
||||||
|
|
||||||
|
if (!owner.stacksController->getActiveStack())
|
||||||
|
return result;
|
||||||
|
|
||||||
|
if (!settings["battle"]["stackRange"].Bool())
|
||||||
|
return result;
|
||||||
|
|
||||||
|
auto hoveredHex = getHoveredHex();
|
||||||
|
|
||||||
|
// add possible movement hexes for stack under mouse
|
||||||
const CStack * const hoveredStack = owner.curInt->cb->battleGetStackByPos(hoveredHex, true);
|
const CStack * const hoveredStack = owner.curInt->cb->battleGetStackByPos(hoveredHex, true);
|
||||||
if(hoveredStack && hoveredStack != owner.stacksController->getActiveStack())
|
if(hoveredStack && hoveredStack != owner.stacksController->getActiveStack())
|
||||||
{
|
{
|
||||||
@ -241,7 +272,7 @@ std::set<BattleHex> BattleFieldController::getHighlightedHexesStackRange()
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set<BattleHex> BattleFieldController::getHighlightedHexesSpellRange()
|
std::set<BattleHex> BattleFieldController::getHighlightedHexesForSpellRange()
|
||||||
{
|
{
|
||||||
std::set<BattleHex> result;
|
std::set<BattleHex> result;
|
||||||
auto hoveredHex = getHoveredHex();
|
auto hoveredHex = getHoveredHex();
|
||||||
@ -260,9 +291,9 @@ std::set<BattleHex> BattleFieldController::getHighlightedHexesSpellRange()
|
|||||||
{
|
{
|
||||||
// printing shaded hex(es)
|
// printing shaded hex(es)
|
||||||
spells::BattleCast event(owner.curInt->cb.get(), caster, mode, spell);
|
spells::BattleCast event(owner.curInt->cb.get(), caster, mode, spell);
|
||||||
auto shaded = spell->battleMechanics(&event)->rangeInHexes(hoveredHex);
|
auto shadedHexes = spell->battleMechanics(&event)->rangeInHexes(hoveredHex);
|
||||||
|
|
||||||
for(BattleHex shadedHex : shaded)
|
for(BattleHex shadedHex : shadedHexes)
|
||||||
{
|
{
|
||||||
if((shadedHex.getX() != 0) && (shadedHex.getX() != GameConstants::BFIELD_WIDTH - 1))
|
if((shadedHex.getX() != 0) && (shadedHex.getX() != GameConstants::BFIELD_WIDTH - 1))
|
||||||
result.insert(shadedHex);
|
result.insert(shadedHex);
|
||||||
@ -276,72 +307,74 @@ std::set<BattleHex> BattleFieldController::getHighlightedHexesMovementTarget()
|
|||||||
const CStack * stack = owner.stacksController->getActiveStack();
|
const CStack * stack = owner.stacksController->getActiveStack();
|
||||||
auto hoveredHex = getHoveredHex();
|
auto hoveredHex = getHoveredHex();
|
||||||
|
|
||||||
if (stack)
|
if(!stack)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
std::vector<BattleHex> availableHexes = owner.curInt->cb->battleGetAvailableHexes(stack, false, nullptr);
|
||||||
|
|
||||||
|
auto hoveredStack = owner.curInt->cb->battleGetStackByPos(hoveredHex, true);
|
||||||
|
if(owner.curInt->cb->battleCanAttack(stack, hoveredStack, hoveredHex))
|
||||||
{
|
{
|
||||||
std::vector<BattleHex> v = owner.curInt->cb->battleGetAvailableHexes(stack, false, nullptr);
|
if(isTileAttackable(hoveredHex))
|
||||||
|
|
||||||
auto hoveredStack = owner.curInt->cb->battleGetStackByPos(hoveredHex, true);
|
|
||||||
if(owner.curInt->cb->battleCanAttack(stack, hoveredStack, hoveredHex))
|
|
||||||
{
|
{
|
||||||
if (isTileAttackable(hoveredHex))
|
BattleHex attackFromHex = fromWhichHexAttack(hoveredHex);
|
||||||
{
|
|
||||||
BattleHex attackFromHex = fromWhichHexAttack(hoveredHex);
|
|
||||||
|
|
||||||
if (stack->doubleWide())
|
if(stack->doubleWide())
|
||||||
return {attackFromHex, stack->occupiedHex(attackFromHex)};
|
return {attackFromHex, stack->occupiedHex(attackFromHex)};
|
||||||
else
|
|
||||||
return {attackFromHex};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vstd::contains(v,hoveredHex))
|
|
||||||
{
|
|
||||||
if (stack->doubleWide())
|
|
||||||
return {hoveredHex, stack->occupiedHex(hoveredHex)};
|
|
||||||
else
|
else
|
||||||
return {hoveredHex};
|
return {attackFromHex};
|
||||||
}
|
|
||||||
if (stack->doubleWide())
|
|
||||||
{
|
|
||||||
for (auto const & hex : v)
|
|
||||||
{
|
|
||||||
if (stack->occupiedHex(hex) == hoveredHex)
|
|
||||||
return { hoveredHex, hex };
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(vstd::contains(availableHexes, hoveredHex))
|
||||||
|
{
|
||||||
|
if(stack->doubleWide())
|
||||||
|
return {hoveredHex, stack->occupiedHex(hoveredHex)};
|
||||||
|
else
|
||||||
|
return {hoveredHex};
|
||||||
|
}
|
||||||
|
|
||||||
|
if(stack->doubleWide())
|
||||||
|
{
|
||||||
|
for(auto const & hex : availableHexes)
|
||||||
|
{
|
||||||
|
if(stack->occupiedHex(hex) == hoveredHex)
|
||||||
|
return {hoveredHex, hex};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void BattleFieldController::showHighlightedHexes(Canvas & canvas)
|
void BattleFieldController::showHighlightedHexes(Canvas & canvas)
|
||||||
{
|
{
|
||||||
std::set<BattleHex> hoveredStack = getHighlightedHexesStackRange();
|
//std::set<BattleHex> hoveredStack = getHighlightedHexesForActiveStack();
|
||||||
std::set<BattleHex> hoveredSpell = getHighlightedHexesSpellRange();
|
std::set<BattleHex> hoveredStackHexes = getMovementRangeForHoveredStack();
|
||||||
std::set<BattleHex> hoveredMove = getHighlightedHexesMovementTarget();
|
std::set<BattleHex> hoveredSpellHexes = getHighlightedHexesForSpellRange();
|
||||||
|
std::set<BattleHex> hoveredMoveHexes = getHighlightedHexesMovementTarget();
|
||||||
|
|
||||||
if (getHoveredHex() == BattleHex::INVALID)
|
if(getHoveredHex() == BattleHex::INVALID)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto const & hoveredMouse = owner.actionsController->currentActionSpellcasting(getHoveredHex()) ? hoveredSpell : hoveredMove;
|
auto const & hoveredMouseHexes = owner.actionsController->currentActionSpellcasting(getHoveredHex()) ? hoveredSpellHexes : hoveredMoveHexes;
|
||||||
|
|
||||||
for(int b=0; b<GameConstants::BFIELD_SIZE; ++b)
|
for(int b=0; b<GameConstants::BFIELD_SIZE; ++b)
|
||||||
{
|
{
|
||||||
bool stack = hoveredStack.count(b);
|
bool stack = hoveredStackHexes.count(b);
|
||||||
bool mouse = hoveredMouse.count(b);
|
bool mouse = hoveredMouseHexes.count(b);
|
||||||
|
|
||||||
if ( stack && mouse )
|
if(stack && mouse) // area where hovered stack can move shown with highlight. Because also affected by mouse cursor, shade as well
|
||||||
{
|
{
|
||||||
// area where enemy stack can move AND affected by mouse cursor - create darker highlight by blitting twice
|
showHighlightedHexForMovement(canvas, b, false);
|
||||||
showHighlightedHex(canvas, b, true);
|
showShadedHex(canvas, b, true);
|
||||||
showHighlightedHex(canvas, b, true);
|
|
||||||
}
|
}
|
||||||
if ( !stack && mouse )
|
if(!stack && mouse) // hexes affected only at mouse cursor shown as shaded
|
||||||
{
|
{
|
||||||
showHighlightedHex(canvas, b, true);
|
showShadedHex(canvas, b, true);
|
||||||
}
|
}
|
||||||
if ( stack && !mouse )
|
if(stack && !mouse) // hexes where hovered stack can move shown with highlight
|
||||||
{
|
{
|
||||||
showHighlightedHex(canvas, b, false);
|
showHighlightedHexForMovement(canvas, b, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@ class BattleFieldController : public CIntObject
|
|||||||
|
|
||||||
std::shared_ptr<IImage> background;
|
std::shared_ptr<IImage> background;
|
||||||
std::shared_ptr<IImage> cellBorder;
|
std::shared_ptr<IImage> cellBorder;
|
||||||
|
std::shared_ptr<IImage> cellUnitMovementHighlight;
|
||||||
std::shared_ptr<IImage> cellShade;
|
std::shared_ptr<IImage> cellShade;
|
||||||
|
|
||||||
/// Canvas that contains background, hex grid (if enabled), absolute obstacles and movement range of active stack
|
/// Canvas that contains background, hex grid (if enabled), absolute obstacles and movement range of active stack
|
||||||
@ -46,10 +47,12 @@ class BattleFieldController : public CIntObject
|
|||||||
/// hexes that when in front of a unit cause it's amount box to move back
|
/// hexes that when in front of a unit cause it's amount box to move back
|
||||||
std::array<bool, GameConstants::BFIELD_SIZE> stackCountOutsideHexes;
|
std::array<bool, GameConstants::BFIELD_SIZE> stackCountOutsideHexes;
|
||||||
|
|
||||||
void showHighlightedHex(Canvas & to, BattleHex hex, bool darkBorder);
|
void showHighlightedHexForMovement(Canvas& canvas, BattleHex hex, bool darkBorder);
|
||||||
|
void showShadedHex(Canvas & to, BattleHex hex, bool darkBorder);
|
||||||
|
|
||||||
std::set<BattleHex> getHighlightedHexesStackRange();
|
std::set<BattleHex> getHighlightedHexesForActiveStack();
|
||||||
std::set<BattleHex> getHighlightedHexesSpellRange();
|
std::set<BattleHex> getMovementRangeForHoveredStack();
|
||||||
|
std::set<BattleHex> getHighlightedHexesForSpellRange();
|
||||||
std::set<BattleHex> getHighlightedHexesMovementTarget();
|
std::set<BattleHex> getHighlightedHexesMovementTarget();
|
||||||
|
|
||||||
void showBackground(Canvas & canvas);
|
void showBackground(Canvas & canvas);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user