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

Merge pull request #1874 from krs0/feature/separate_movement_highlight_for_hoverd_units_in_battle

Separate movement highlight for hovered units in battle
This commit is contained in:
Ivan Savenko 2023-04-08 21:47:49 +03:00 committed by GitHub
commit a97ebc2bf1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 183 additions and 108 deletions

View File

@ -271,7 +271,7 @@ BattleAction CBattleAI::activeStack( const CStack * stack )
BattleAction CBattleAI::goTowardsNearest(const CStack * stack, std::vector<BattleHex> hexes) const
{
auto reachability = cb->getReachability(stack);
auto avHexes = cb->battleGetAvailableHexes(reachability, stack);
auto avHexes = cb->battleGetAvailableHexes(reachability, stack, true);
if(!avHexes.size() || !hexes.size()) //we are blocked or dest is blocked
{

View File

@ -15,7 +15,7 @@ PotentialTargets::PotentialTargets(const battle::Unit * attacker, const Hypothet
{
auto attackerInfo = state.battleGetUnitByID(attacker->unitId());
auto reachability = state.getReachability(attackerInfo);
auto avHexes = state.battleGetAvailableHexes(reachability, attackerInfo);
auto avHexes = state.battleGetAvailableHexes(reachability, attackerInfo, true);
//FIXME: this should part of battleGetAvailableHexes
bool forceTarget = false;

View File

@ -120,7 +120,7 @@ BattleAction CStupidAI::activeStack( const CStack * stack )
}
else
{
std::vector<BattleHex> avHexes = cb->battleGetAvailableHexes(stack);
std::vector<BattleHex> avHexes = cb->battleGetAvailableHexes(stack, true);
for (BattleHex hex : avHexes)
{
@ -238,7 +238,7 @@ void CStupidAI::print(const std::string &text) const
BattleAction CStupidAI::goTowards(const CStack * stack, std::vector<BattleHex> hexes) const
{
auto reachability = cb->getReachability(stack);
auto avHexes = cb->battleGetAvailableHexes(reachability, stack);
auto avHexes = cb->battleGetAvailableHexes(reachability, stack, false);
if(!avHexes.size() || !hexes.size()) //we are blocked or dest is blocked
{

Binary file not shown.

After

Width:  |  Height:  |  Size: 422 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 272 B

View File

@ -81,6 +81,8 @@
"vcmi.battleOptions.animationsSpeed6.help": "Set animation speed to instantaneous",
"vcmi.battleOptions.touchscreenMode.hover": "Touchscreen mode",
"vcmi.battleOptions.touchscreenMode.help": "{Touchscreen mode}\n\nIf enabled, second click is required to confirm and execute action. This is more suitable for touchscreen devices.",
"vcmi.battleOptions.movementHighlightOnHover.hover": "Movement Highlight on Hover",
"vcmi.battleOptions.movementHighlightOnHover.help": "{Movement Highlight on Hover}\n\nHighlight unit's movement range when you hover over it.",
"vcmi.battleOptions.skipBattleIntroMusic.hover": "Skip Intro Music",
"vcmi.battleOptions.skipBattleIntroMusic.help": "{Skip Intro Music}\n\nAllow actions during the intro music that plays at the beginning of each battle",
"vcmi.battleWindow.pressKeyToSkipIntro" : "Press any key to start battle immediately",

View File

@ -50,6 +50,7 @@
"description" : "Ключові файли необхідні для повноцінної роботи VCMI",
"author" : "Команда VCMI",
"skipValidation" : true,
"translations" : [
"config/vcmi/ukrainian.json"
]

View File

@ -623,7 +623,7 @@ void BattleActionsController::actionRealize(PossiblePlayerBattleAction action, B
{
if(owner.stacksController->getActiveStack()->doubleWide())
{
std::vector<BattleHex> acc = owner.curInt->cb->battleGetAvailableHexes(owner.stacksController->getActiveStack());
std::vector<BattleHex> acc = owner.curInt->cb->battleGetAvailableHexes(owner.stacksController->getActiveStack(), true);
BattleHex shiftedDest = targetHex.cloneInDirection(owner.stacksController->getActiveStack()->destShiftDir(), false);
if(vstd::contains(acc, targetHex))
owner.giveCommand(EActionType::WALK, targetHex);
@ -926,7 +926,7 @@ bool BattleActionsController::isCastingPossibleHere(const CSpell * currentSpell,
bool BattleActionsController::canStackMoveHere(const CStack * stackToMove, BattleHex myNumber) const
{
std::vector<BattleHex> acc = owner.curInt->cb->battleGetAvailableHexes(stackToMove);
std::vector<BattleHex> acc = owner.curInt->cb->battleGetAvailableHexes(stackToMove, false);
BattleHex shiftedDest = myNumber.cloneInDirection(stackToMove->destShiftDir(), false);
if (vstd::contains(acc, myNumber))

View File

@ -44,6 +44,8 @@ BattleFieldController::BattleFieldController(BattleInterface & owner):
//preparing cells and hexes
cellBorder = IImage::createFromFile("CCELLGRD.BMP", EImageBlitMode::COLORKEY);
cellShade = IImage::createFromFile("CCELLSHD.BMP");
cellUnitMovementHighlight = IImage::createFromFile("UnitMovementHighlight.PNG", EImageBlitMode::COLORKEY);
cellUnitMaxMovementHighlight = IImage::createFromFile("UnitMaxMovementHighlight.PNG", EImageBlitMode::COLORKEY);
if(!owner.siegeController)
{
@ -138,7 +140,6 @@ void BattleFieldController::showBackground(Canvas & canvas)
showBackgroundImage(canvas);
showHighlightedHexes(canvas);
}
void BattleFieldController::showBackgroundImage(Canvas & canvas)
@ -172,32 +173,34 @@ void BattleFieldController::redrawBackgroundWithHexes()
{
const CStack *activeStack = owner.stacksController->getActiveStack();
std::vector<BattleHex> attackableHexes;
if (activeStack)
occupyableHexes = owner.curInt->cb->battleGetAvailableHexes(activeStack, true, &attackableHexes);
if(activeStack)
occupiableHexes = owner.curInt->cb->battleGetAvailableHexes(activeStack, true, true, &attackableHexes);
//prepare background graphic with hexes and shaded hexes
// prepare background graphic with hexes and shaded hexes
backgroundWithHexes->draw(background, Point(0,0));
owner.obstacleController->showAbsoluteObstacles(*backgroundWithHexes);
if ( owner.siegeController )
if(owner.siegeController)
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 = occupiableHexes;
hexesToShade.insert(hexesToShade.end(), attackableHexes.begin(), attackableHexes.end());
for (BattleHex hex : hexesToShade)
for(BattleHex hex : hexesToShade)
{
backgroundWithHexes->draw(cellShade, hexPositionLocal(hex).topLeft());
showHighlightedHex(*backgroundWithHexes, cellShade, hex, false);
}
}
// draw cell borders
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;
if ( i % GameConstants::BFIELD_WIDTH == GameConstants::BFIELD_WIDTH - 1)
if(i % GameConstants::BFIELD_WIDTH == GameConstants::BFIELD_WIDTH - 1)
continue;
backgroundWithHexes->draw(cellBorder, hexPositionLocal(i).topLeft());
@ -205,23 +208,23 @@ void BattleFieldController::redrawBackgroundWithHexes()
}
}
void BattleFieldController::showHighlightedHex(Canvas & canvas, BattleHex hex, bool darkBorder)
void BattleFieldController::showHighlightedHex(Canvas & canvas, std::shared_ptr<IImage> highlight, BattleHex hex, bool darkBorder)
{
Point hexPos = hexPositionLocal(hex).topLeft();
canvas.draw(cellShade, hexPos);
canvas.draw(highlight, hexPos);
if(!darkBorder && settings["battle"]["cellBorders"].Bool())
canvas.draw(cellBorder, hexPos);
}
std::set<BattleHex> BattleFieldController::getHighlightedHexesStackRange()
std::set<BattleHex> BattleFieldController::getHighlightedHexesForActiveStack()
{
std::set<BattleHex> result;
if ( !owner.stacksController->getActiveStack())
if(!owner.stacksController->getActiveStack())
return result;
if ( !settings["battle"]["stackRange"].Bool())
if(!settings["battle"]["stackRange"].Bool())
return result;
auto hoveredHex = getHoveredHex();
@ -230,18 +233,33 @@ std::set<BattleHex> BattleFieldController::getHighlightedHexesStackRange()
for(BattleHex hex : set)
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"]["movementHighlightOnHover"].Bool())
return result;
auto hoveredHex = getHoveredHex();
// add possible movement hexes for stack under mouse
const CStack * const hoveredStack = owner.curInt->cb->battleGetStackByPos(hoveredHex, true);
if(hoveredStack && hoveredStack != owner.stacksController->getActiveStack())
if(hoveredStack)
{
std::vector<BattleHex> v = owner.curInt->cb->battleGetAvailableHexes(hoveredStack, true, nullptr);
std::vector<BattleHex> v = owner.curInt->cb->battleGetAvailableHexes(hoveredStack, false, true, nullptr);
for(BattleHex hex : v)
result.insert(hex);
}
return result;
}
std::set<BattleHex> BattleFieldController::getHighlightedHexesSpellRange()
std::set<BattleHex> BattleFieldController::getHighlightedHexesForSpellRange()
{
std::set<BattleHex> result;
auto hoveredHex = getHoveredHex();
@ -260,9 +278,9 @@ std::set<BattleHex> BattleFieldController::getHighlightedHexesSpellRange()
{
// printing shaded hex(es)
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))
result.insert(shadedHex);
@ -276,72 +294,73 @@ std::set<BattleHex> BattleFieldController::getHighlightedHexesMovementTarget()
const CStack * stack = owner.stacksController->getActiveStack();
auto hoveredHex = getHoveredHex();
if (stack)
if(!stack)
return {};
std::vector<BattleHex> availableHexes = owner.curInt->cb->battleGetAvailableHexes(stack, true, 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);
auto hoveredStack = owner.curInt->cb->battleGetStackByPos(hoveredHex, true);
if(owner.curInt->cb->battleCanAttack(stack, hoveredStack, hoveredHex))
if(isTileAttackable(hoveredHex))
{
if (isTileAttackable(hoveredHex))
{
BattleHex attackFromHex = fromWhichHexAttack(hoveredHex);
BattleHex attackFromHex = fromWhichHexAttack(hoveredHex);
if (stack->doubleWide())
return {attackFromHex, stack->occupiedHex(attackFromHex)};
else
return {attackFromHex};
}
}
if (vstd::contains(v,hoveredHex))
{
if (stack->doubleWide())
return {hoveredHex, stack->occupiedHex(hoveredHex)};
if(stack->doubleWide())
return {attackFromHex, stack->occupiedHex(attackFromHex)};
else
return {hoveredHex};
}
if (stack->doubleWide())
{
for (auto const & hex : v)
{
if (stack->occupiedHex(hex) == hoveredHex)
return { hoveredHex, hex };
}
return {attackFromHex};
}
}
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 {};
}
void BattleFieldController::showHighlightedHexes(Canvas & canvas)
{
std::set<BattleHex> hoveredStack = getHighlightedHexesStackRange();
std::set<BattleHex> hoveredSpell = getHighlightedHexesSpellRange();
std::set<BattleHex> hoveredMove = getHighlightedHexesMovementTarget();
std::set<BattleHex> hoveredStackMovementRangeHexes = getMovementRangeForHoveredStack();
std::set<BattleHex> hoveredSpellHexes = getHighlightedHexesForSpellRange();
std::set<BattleHex> hoveredMoveHexes = getHighlightedHexesMovementTarget();
if (getHoveredHex() == BattleHex::INVALID)
if(getHoveredHex() == BattleHex::INVALID)
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 hex = 0; hex < GameConstants::BFIELD_SIZE; ++hex)
{
bool stack = hoveredStack.count(b);
bool mouse = hoveredMouse.count(b);
bool stackMovement = hoveredStackMovementRangeHexes.count(hex);
bool mouse = hoveredMouseHexes.count(hex);
if ( stack && mouse )
if(stackMovement && mouse) // area where hovered stackMovement 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
showHighlightedHex(canvas, b, true);
showHighlightedHex(canvas, b, true);
showHighlightedHex(canvas, cellUnitMovementHighlight, hex, false);
showHighlightedHex(canvas, cellShade, hex, true);
}
if ( !stack && mouse )
if(!stackMovement && mouse) // hexes affected only at mouse cursor shown as shaded
{
showHighlightedHex(canvas, b, true);
showHighlightedHex(canvas, cellShade, hex, true);
}
if ( stack && !mouse )
if(stackMovement && !mouse) // hexes where hovered stackMovement can move shown with highlight
{
showHighlightedHex(canvas, b, false);
showHighlightedHex(canvas, cellUnitMovementHighlight, hex, false);
}
}
}
@ -438,18 +457,18 @@ BattleHex::EDir BattleFieldController::selectAttackDirection(BattleHex myNumber,
// | - - | - - | - - | - o o | o o - | - - | - - | o o
for (size_t i : { 1, 2, 3})
attackAvailability[i] = vstd::contains(occupyableHexes, neighbours[i]) && vstd::contains(occupyableHexes, neighbours[i].cloneInDirection(BattleHex::RIGHT, false));
attackAvailability[i] = vstd::contains(occupiableHexes, neighbours[i]) && vstd::contains(occupiableHexes, neighbours[i].cloneInDirection(BattleHex::RIGHT, false));
for (size_t i : { 4, 5, 0})
attackAvailability[i] = vstd::contains(occupyableHexes, neighbours[i]) && vstd::contains(occupyableHexes, neighbours[i].cloneInDirection(BattleHex::LEFT, false));
attackAvailability[i] = vstd::contains(occupiableHexes, neighbours[i]) && vstd::contains(occupiableHexes, neighbours[i].cloneInDirection(BattleHex::LEFT, false));
attackAvailability[6] = vstd::contains(occupyableHexes, neighbours[0]) && vstd::contains(occupyableHexes, neighbours[1]);
attackAvailability[7] = vstd::contains(occupyableHexes, neighbours[3]) && vstd::contains(occupyableHexes, neighbours[4]);
attackAvailability[6] = vstd::contains(occupiableHexes, neighbours[0]) && vstd::contains(occupiableHexes, neighbours[1]);
attackAvailability[7] = vstd::contains(occupiableHexes, neighbours[3]) && vstd::contains(occupiableHexes, neighbours[4]);
}
else
{
for (size_t i = 0; i < 6; ++i)
attackAvailability[i] = vstd::contains(occupyableHexes, neighbours[i]);
attackAvailability[i] = vstd::contains(occupiableHexes, neighbours[i]);
attackAvailability[6] = false;
attackAvailability[7] = false;
@ -561,7 +580,7 @@ BattleHex BattleFieldController::fromWhichHexAttack(BattleHex attackTarget)
bool BattleFieldController::isTileAttackable(const BattleHex & number) const
{
for (auto & elem : occupyableHexes)
for (auto & elem : occupiableHexes)
{
if (BattleHex::mutualPosition(elem, number) != -1 || elem == number)
return true;

View File

@ -32,6 +32,8 @@ class BattleFieldController : public CIntObject
std::shared_ptr<IImage> background;
std::shared_ptr<IImage> cellBorder;
std::shared_ptr<IImage> cellUnitMovementHighlight;
std::shared_ptr<IImage> cellUnitMaxMovementHighlight;
std::shared_ptr<IImage> cellShade;
/// Canvas that contains background, hex grid (if enabled), absolute obstacles and movement range of active stack
@ -41,15 +43,16 @@ class BattleFieldController : public CIntObject
BattleHex attackingHex;
/// hexes to which currently active stack can move
std::vector<BattleHex> occupyableHexes;
std::vector<BattleHex> occupiableHexes;
/// hexes that when in front of a unit cause it's amount box to move back
std::array<bool, GameConstants::BFIELD_SIZE> stackCountOutsideHexes;
void showHighlightedHex(Canvas & to, BattleHex hex, bool darkBorder);
void showHighlightedHex(Canvas & to, std::shared_ptr<IImage> highlight, BattleHex hex, bool darkBorder);
std::set<BattleHex> getHighlightedHexesStackRange();
std::set<BattleHex> getHighlightedHexesSpellRange();
std::set<BattleHex> getHighlightedHexesForActiveStack();
std::set<BattleHex> getMovementRangeForHoveredStack();
std::set<BattleHex> getHighlightedHexesForSpellRange();
std::set<BattleHex> getHighlightedHexesMovementTarget();
void showBackground(Canvas & canvas);

View File

@ -198,6 +198,23 @@ void BattleWindow::keyPressed(const SDL_Keycode & key)
{
owner.actionsController->endCastingSpell();
}
else if(GH.isKeyboardShiftDown())
{
// save and activate setting
Settings movementHighlightOnHover = settings.write["battle"]["movementHighlightOnHover"];
movementHighlightOnHoverCache = movementHighlightOnHover->Bool();
movementHighlightOnHover->Bool() = true;
}
}
void BattleWindow::keyReleased(const SDL_Keycode & key)
{
if(!GH.isKeyboardShiftDown())
{
// set back to initial state
Settings movementHighlightOnHover = settings.write["battle"]["movementHighlightOnHover"];
movementHighlightOnHover->Bool() = movementHighlightOnHoverCache;
}
}
void BattleWindow::clickRight(tribool down, bool previousState)

View File

@ -85,6 +85,7 @@ public:
void activate() override;
void deactivate() override;
void keyPressed(const SDL_Keycode & key) override;
void keyReleased(const SDL_Keycode& key) override;
void clickRight(tribool down, bool previousState) override;
void show(SDL_Surface *to) override;
void showAll(SDL_Surface *to) override;
@ -98,5 +99,8 @@ public:
/// Set possible alternative options. If more than 1 - the last will be considered as default option
void setAlternativeActions(const std::list<PossiblePlayerBattleAction> &);
private:
/// used to save the state of this setting on toggle.
bool movementHighlightOnHoverCache;
};

View File

@ -418,7 +418,7 @@ void CGuiHandler::handleCurrentEvent( SDL_Event & current )
for(auto i = miCopy.begin(); i != miCopy.end() && continueEventHandling; i++)
if(vstd::contains(keyinterested,*i) && (!keysCaptured || (*i)->captureThisKey(key.keysym.sym)))
{
if (key.state == SDL_PRESSED)
if (key.state == SDL_PRESSED && key.repeat == 0) // function like key_DOWN, and not like a periodic key_Pressed check
(**i).keyPressed(key.keysym.sym);
if (key.state == SDL_RELEASED)
(**i).keyReleased(key.keysym.sym);

View File

@ -34,6 +34,10 @@ BattleOptionsTab::BattleOptionsTab(BattleInterface * owner)
{
movementShadowChangedCallback(value, owner);
});
addCallback("movementHighlightOnHoverChanged", [this, owner](bool value)
{
movementHighlightOnHoverChangedCallback(value, owner);
});
addCallback("mouseShadowChanged", [this](bool value)
{
mouseShadowChangedCallback(value);
@ -72,6 +76,9 @@ BattleOptionsTab::BattleOptionsTab(BattleInterface * owner)
std::shared_ptr<CToggleButton> movementShadowCheckbox = widget<CToggleButton>("movementShadowCheckbox");
movementShadowCheckbox->setSelected(settings["battle"]["stackRange"].Bool());
std::shared_ptr<CToggleButton> movementHighlightOnHoverCheckbox = widget<CToggleButton>("movementHighlightOnHoverCheckbox");
movementHighlightOnHoverCheckbox->setSelected(settings["battle"]["movementHighlightOnHover"].Bool());
std::shared_ptr<CToggleButton> mouseShadowCheckbox = widget<CToggleButton>("mouseShadowCheckbox");
mouseShadowCheckbox->setSelected(settings["battle"]["mouseShadow"].Bool());
@ -138,6 +145,14 @@ void BattleOptionsTab::movementShadowChangedCallback(bool value, BattleInterface
parentBattleInterface->redrawBattlefield();
}
void BattleOptionsTab::movementHighlightOnHoverChangedCallback(bool value, BattleInterface * parentBattleInterface)
{
Settings stackRange = settings.write["battle"]["movementHighlightOnHover"];
stackRange->Bool() = value;
if(parentBattleInterface)
parentBattleInterface->redrawBattlefield();
}
void BattleOptionsTab::mouseShadowChangedCallback(bool value)
{
Settings shadow = settings.write["battle"]["mouseShadow"];

View File

@ -24,6 +24,7 @@ private:
std::string getQueueSizeStringFromId(int value) const;
void viewGridChangedCallback(bool value, BattleInterface * parentBattleInterface);
void movementShadowChangedCallback(bool value, BattleInterface * parentBattleInterface);
void movementHighlightOnHoverChangedCallback(bool value, BattleInterface * parentBattleInterface);
void mouseShadowChangedCallback(bool value);
void animationSpeedChangedCallback(int value);
void showQueueChangedCallback(bool value, BattleInterface * parentBattleInterface);

View File

@ -286,7 +286,7 @@
"type" : "object",
"additionalProperties" : false,
"default": {},
"required" : [ "speedFactor", "mouseShadow", "cellBorders", "stackRange", "showQueue", "queueSize", "touchscreenMode" ],
"required" : [ "speedFactor", "mouseShadow", "cellBorders", "stackRange", "movementHighlightOnHover", "showQueue", "queueSize", "touchscreenMode" ],
"properties" : {
"speedFactor" : {
"type" : "number",
@ -308,6 +308,10 @@
"type" : "boolean",
"default" : true
},
"movementHighlightOnHover" : {
"type" : "boolean",
"default" : true
},
"showQueue" : {
"type" : "boolean",
"default" : true

View File

@ -142,13 +142,17 @@
"position": {"x": 45, "y": 85}
},
{
"text": "core.genrltxt.406",
"text": "vcmi.battleOptions.movementHighlightOnHover.hover",
"position": {"x": 45, "y": 115}
},
{
"text": "core.genrltxt.407",
"text": "core.genrltxt.406",
"position": {"x": 45, "y": 145}
},
{
"text": "core.genrltxt.407",
"position": {"x": 45, "y": 175}
},
{
"text": "vcmi.battleOptions.skipBattleIntroMusic.hover",
"position": {"x": 45, "y": 175}
@ -176,26 +180,34 @@
"position": {"x": 10, "y": 83},
"callback": "movementShadowChanged"
},
{
"name": "movementHighlightOnHoverCheckbox",
"type": "toggleButton",
"image": "sysopchk.def",
"help": "vcmi.battleOptions.movementHighlightOnHover",
"position": {"x": 10, "y": 113},
"callback": "movementHighlightOnHoverChanged"
},
{
"name": "mouseShadowCheckbox",
"type": "toggleButton",
"image": "sysopchk.def",
"help": "core.help.429",
"position": {"x": 10, "y": 113},
"position": {"x": 10, "y": 143},
"callback": "mouseShadowChanged"
},
{
"name": "battleFieldCasualtiesPlaceholder",
"type": "picture",
"image": "settingsWindow/checkBoxEmpty",
"position": {"x": 10, "y": 143},
"position": {"x": 10, "y": 173},
},
{
"name": "skipBattleIntroMusicCheckbox",
"type": "toggleButton",
"image": "sysopchk.def",
"help": "vcmi.battleOptions.skipBattleIntroMusic",
"position": {"x": 10, "y": 173},
"position": {"x": 10, "y": 203},
"callback": "skipBattleIntroMusicChanged"
},
{

View File

@ -538,7 +538,7 @@ void CBattleInfoCallback::battleGetTurnOrder(std::vector<battle::Units> & turns,
battleGetTurnOrder(turns, maxUnits, maxTurns, actualTurn + 1, sideThatLastMoved);
}
std::vector<BattleHex> CBattleInfoCallback::battleGetAvailableHexes(const battle::Unit * unit) const
std::vector<BattleHex> CBattleInfoCallback::battleGetAvailableHexes(const battle::Unit * unit, bool isActiveStack) const
{
RETURN_IF_NOT_BATTLE(std::vector<BattleHex>());
@ -547,10 +547,10 @@ std::vector<BattleHex> CBattleInfoCallback::battleGetAvailableHexes(const battle
auto reachability = getReachability(unit);
return battleGetAvailableHexes(reachability, unit);
return battleGetAvailableHexes(reachability, unit, isActiveStack);
}
std::vector<BattleHex> CBattleInfoCallback::battleGetAvailableHexes(const ReachabilityInfo & cache, const battle::Unit * unit) const
std::vector<BattleHex> CBattleInfoCallback::battleGetAvailableHexes(const ReachabilityInfo & cache, const battle::Unit * unit, bool isActiveStack) const
{
std::vector<BattleHex> ret;
@ -560,7 +560,7 @@ std::vector<BattleHex> CBattleInfoCallback::battleGetAvailableHexes(const Reacha
auto unitSpeed = unit->Speed(0, true);
const bool tacticPhase = battleTacticDist() && battleGetTacticsSide() == unit->unitSide();
const bool showTacticsRange = battleTacticDist() && battleGetTacticsSide() == unit->unitSide() && isActiveStack;
for(int i = 0; i < GameConstants::BFIELD_SIZE; ++i)
{
@ -568,15 +568,15 @@ std::vector<BattleHex> CBattleInfoCallback::battleGetAvailableHexes(const Reacha
if(!cache.isReachable(i))
continue;
if(tacticPhase)
if(showTacticsRange)
{
//Stack has to perform tactic-phase movement -> can enter any reachable tile within given range
// Stack has to perform tactic-phase movement -> can enter any reachable tile within given range
if(!isInTacticRange(i))
continue;
}
else
{
//Not tactics phase -> destination must be reachable and within unit range.
// Not tactics phase -> destination must be reachable and within unit range.
if(cache.distances[i] > static_cast<int>(unitSpeed))
continue;
}
@ -587,10 +587,9 @@ std::vector<BattleHex> CBattleInfoCallback::battleGetAvailableHexes(const Reacha
return ret;
}
std::vector<BattleHex> CBattleInfoCallback::battleGetAvailableHexes(const battle::Unit * unit, bool addOccupiable, std::vector<BattleHex> * attackable) const
std::vector<BattleHex> CBattleInfoCallback::battleGetAvailableHexes(const battle::Unit * unit, bool isActiveStack, bool addOccupiable, std::vector<BattleHex> * attackable) const
{
std::vector<BattleHex> ret = battleGetAvailableHexes(unit);
std::vector<BattleHex> ret = battleGetAvailableHexes(unit, isActiveStack);
if(ret.empty())
return ret;
@ -976,7 +975,6 @@ ReachabilityInfo CBattleInfoCallback::makeBFS(const AccessibilityInfo &accessibi
return ret;
}
bool CBattleInfoCallback::isInObstacle(
BattleHex hex,
const std::set<BattleHex> & obstacles,
@ -1030,7 +1028,7 @@ std::set<BattleHex> CBattleInfoCallback::getStoppers(BattlePerspective::BattlePe
std::pair<const battle::Unit *, BattleHex> CBattleInfoCallback::getNearestStack(const battle::Unit * closest) const
{
auto reachability = getReachability(closest);
auto avHexes = battleGetAvailableHexes(reachability, closest);
auto avHexes = battleGetAvailableHexes(reachability, closest, false);
// I hate std::pairs with their undescriptive member names first / second
struct DistStack
@ -1097,7 +1095,6 @@ BattleHex CBattleInfoCallback::getAvaliableHex(const CreatureID & creID, ui8 sid
return BattleHex::getClosestTile(side, pos, occupyable);
}
si8 CBattleInfoCallback::battleGetTacticDist() const
{
RETURN_IF_NOT_BATTLE(0);
@ -1158,7 +1155,7 @@ ReachabilityInfo CBattleInfoCallback::getFlyingReachability(const ReachabilityIn
return ret;
}
AttackableTiles CBattleInfoCallback::getPotentiallyAttackableHexes (const battle::Unit* attacker, BattleHex destinationTile, BattleHex attackerPos) const
AttackableTiles CBattleInfoCallback::getPotentiallyAttackableHexes(const battle::Unit* attacker, BattleHex destinationTile, BattleHex attackerPos) const
{
//does not return hex attacked directly
AttackableTiles at;
@ -1242,7 +1239,7 @@ AttackableTiles CBattleInfoCallback::getPotentiallyAttackableHexes (const battl
return at;
}
AttackableTiles CBattleInfoCallback::getPotentiallyShootableHexes(const battle::Unit * attacker, BattleHex destinationTile, BattleHex attackerPos) const
AttackableTiles CBattleInfoCallback::getPotentiallyShootableHexes(const battle::Unit * attacker, BattleHex destinationTile, BattleHex attackerPos) const
{
//does not return hex attacked directly
AttackableTiles at;

View File

@ -74,12 +74,12 @@ public:
void battleGetTurnOrder(std::vector<battle::Units> & out, const size_t maxUnits, const int maxTurns, const int turn = 0, int8_t lastMoved = -1) const;
///returns reachable hexes (valid movement destinations), DOES contain stack current position
std::vector<BattleHex> battleGetAvailableHexes(const battle::Unit * unit, bool addOccupiable, std::vector<BattleHex> * attackable) const;
std::vector<BattleHex> battleGetAvailableHexes(const battle::Unit * unit, bool isActiveStack, bool addOccupiable, std::vector<BattleHex> * attackable) const;
///returns reachable hexes (valid movement destinations), DOES contain stack current position (lite version)
std::vector<BattleHex> battleGetAvailableHexes(const battle::Unit * unit) const;
std::vector<BattleHex> battleGetAvailableHexes(const battle::Unit * unit, bool isActiveStack) const;
std::vector<BattleHex> battleGetAvailableHexes(const ReachabilityInfo & cache, const battle::Unit * unit) const;
std::vector<BattleHex> battleGetAvailableHexes(const ReachabilityInfo & cache, const battle::Unit * unit, bool isActiveStack) const;
int battleGetSurrenderCost(const PlayerColor & Player) const; //returns cost of surrendering battle, -1 if surrendering is not possible
ReachabilityInfo::TDistances battleGetDistances(const battle::Unit * unit, BattleHex assumedPosition) const;