瀏覽代碼

Add hex highlight for SPELL_LIKE_ATTACK in casting mode & minor cleanup

Dydzio 1 年之前
父節點
當前提交
dc56047661

+ 20 - 9
client/battle/BattleActionsController.cpp

@@ -371,6 +371,12 @@ const CSpell * BattleActionsController::getStackSpellToCast(BattleHex hoveredHex
 
 	auto action = selectAction(hoveredHex);
 
+	if(owner.stacksController->getActiveStack()->hasBonusOfType(BonusType::SPELL_LIKE_ATTACK))
+	{
+		auto bonus = owner.stacksController->getActiveStack()->getBonus(Selector::type()(BonusType::SPELL_LIKE_ATTACK));
+		return bonus->subtype.as<SpellID>().toSpell();
+	}
+
 	if (action.spell() == SpellID::NONE)
 		return nullptr;
 
@@ -793,7 +799,7 @@ void BattleActionsController::actionRealize(PossiblePlayerBattleAction action, B
 				}
 			}
 
-			if (!spellcastingModeActive())
+			if (!heroSpellcastingModeActive())
 			{
 				if (action.spell().hasValue())
 				{
@@ -1040,14 +1046,9 @@ void BattleActionsController::activateStack()
 
 void BattleActionsController::onHexRightClicked(BattleHex clickedHex)
 {
-	auto spellcastActionPredicate = [](PossiblePlayerBattleAction & action)
-	{
-		return action.spellcast() || action.get() == PossiblePlayerBattleAction::SHOOT;
-	};
-
-	bool isCurrentStackInSpellcastMode = !possibleActions.empty() && std::all_of(possibleActions.begin(), possibleActions.end(), spellcastActionPredicate);
+	bool isCurrentStackInSpellcastMode = creatureSpellcastingModeActive();
 
-	if (spellcastingModeActive() || isCurrentStackInSpellcastMode)
+	if (heroSpellcastingModeActive() || isCurrentStackInSpellcastMode)
 	{
 		endCastingSpell();
 		CRClickPopup::createAndPush(CGI->generaltexth->translate("core.genrltxt.731")); // spell cancelled
@@ -1066,11 +1067,21 @@ void BattleActionsController::onHexRightClicked(BattleHex clickedHex)
 		owner.defendingHero->heroRightClicked();
 }
 
-bool BattleActionsController::spellcastingModeActive() const
+bool BattleActionsController::heroSpellcastingModeActive() const
 {
 	return heroSpellToCast != nullptr;
 }
 
+bool BattleActionsController::creatureSpellcastingModeActive() const
+{
+	auto spellcastModePredicate = [](const PossiblePlayerBattleAction & action)
+	{
+		return action.spellcast() || action.get() == PossiblePlayerBattleAction::SHOOT; //for hotkey-eligible SPELL_LIKE_ATTACK creature should have only SHOOT action
+	};
+
+	return !possibleActions.empty() && std::all_of(possibleActions.begin(), possibleActions.end(), spellcastModePredicate);
+}
+
 bool BattleActionsController::currentActionSpellcasting(BattleHex hoveredHex)
 {
 	if (heroSpellToCast)

+ 4 - 2
client/battle/BattleActionsController.h

@@ -82,8 +82,10 @@ public:
 	/// initialize list of potential actions for new active stack
 	void activateStack();
 
-	/// returns true if UI is currently in target selection mode
-	bool spellcastingModeActive() const;
+	/// returns true if UI is currently in hero spell target selection mode
+	bool heroSpellcastingModeActive() const;
+	/// returns true if UI is currently in "F" hotkey creature spell target selection mode
+	bool creatureSpellcastingModeActive() const;
 
 	/// returns true if one of the following is true:
 	/// - we are casting spell by hero

+ 3 - 1
client/battle/BattleFieldController.cpp

@@ -566,7 +566,9 @@ void BattleFieldController::showHighlightedHexes(Canvas & canvas)
 		calculateRangeLimitAndHighlightImages(shootingRangeDistance, shootingRangeLimitImages, shootingRangeLimitHexes, shootingRangeLimitHexesHighlights);
 	}
 
-	bool useSpellRangeForMouse = hoveredHex != BattleHex::INVALID && owner.actionsController->currentActionSpellcasting(getHoveredHex());
+	bool useSpellRangeForMouse = hoveredHex != BattleHex::INVALID
+		&& (owner.actionsController->currentActionSpellcasting(getHoveredHex())
+			|| owner.actionsController->creatureSpellcastingModeActive()); //at least shooting with SPELL_LIKE_ATTACK can operate in spellcasting mode without being actual spellcast
 	bool useMoveRangeForMouse = !hoveredMoveHexes.empty() || !settings["battle"]["mouseShadow"].Bool();
 
 	const auto & hoveredMouseHexes = useSpellRangeForMouse ? hoveredSpellHexes : ( useMoveRangeForMouse ? hoveredMoveHexes : hoveredMouseHex);

+ 1 - 1
client/battle/BattleInterfaceClasses.cpp

@@ -327,7 +327,7 @@ void BattleHero::setPhase(EHeroAnimType newPhase)
 
 void BattleHero::heroLeftClicked()
 {
-	if(owner.actionsController->spellcastingModeActive()) //we are casting a spell
+	if(owner.actionsController->heroSpellcastingModeActive()) //we are casting a spell
 		return;
 
 	if(!hero || !owner.makingTurn())

+ 11 - 11
client/battle/BattleWindow.cpp

@@ -538,7 +538,7 @@ void BattleWindow::tacticPhaseEnded()
 
 void BattleWindow::bOptionsf()
 {
-	if (owner.actionsController->spellcastingModeActive())
+	if (owner.actionsController->heroSpellcastingModeActive())
 		return;
 
 	CCS->curh->set(Cursor::Map::POINTER);
@@ -548,7 +548,7 @@ void BattleWindow::bOptionsf()
 
 void BattleWindow::bSurrenderf()
 {
-	if (owner.actionsController->spellcastingModeActive())
+	if (owner.actionsController->heroSpellcastingModeActive())
 		return;
 
 	int cost = owner.getBattle()->battleGetSurrenderCost();
@@ -568,7 +568,7 @@ void BattleWindow::bSurrenderf()
 
 void BattleWindow::bFleef()
 {
-	if (owner.actionsController->spellcastingModeActive())
+	if (owner.actionsController->heroSpellcastingModeActive())
 		return;
 
 	if ( owner.getBattle()->battleCanFlee() )
@@ -675,7 +675,7 @@ void BattleWindow::setAlternativeActions(const std::list<PossiblePlayerBattleAct
 
 void BattleWindow::bAutofightf()
 {
-	if (owner.actionsController->spellcastingModeActive())
+	if (owner.actionsController->heroSpellcastingModeActive())
 		return;
 
 	if(settings["battle"]["endWithAutocombat"].Bool() && onlyOnePlayerHuman)
@@ -712,7 +712,7 @@ void BattleWindow::bAutofightf()
 
 void BattleWindow::bSpellf()
 {
-	if (owner.actionsController->spellcastingModeActive())
+	if (owner.actionsController->heroSpellcastingModeActive())
 		return;
 
 	if (!owner.makingTurn())
@@ -785,7 +785,7 @@ void BattleWindow::bSwitchActionf()
 
 void BattleWindow::bWaitf()
 {
-	if (owner.actionsController->spellcastingModeActive())
+	if (owner.actionsController->heroSpellcastingModeActive())
 		return;
 
 	if (owner.stacksController->getActiveStack() != nullptr)
@@ -794,7 +794,7 @@ void BattleWindow::bWaitf()
 
 void BattleWindow::bDefencef()
 {
-	if (owner.actionsController->spellcastingModeActive())
+	if (owner.actionsController->heroSpellcastingModeActive())
 		return;
 
 	if (owner.stacksController->getActiveStack() != nullptr)
@@ -803,7 +803,7 @@ void BattleWindow::bDefencef()
 
 void BattleWindow::bConsoleUpf()
 {
-	if (owner.actionsController->spellcastingModeActive())
+	if (owner.actionsController->heroSpellcastingModeActive())
 		return;
 
 	console->scrollUp();
@@ -811,7 +811,7 @@ void BattleWindow::bConsoleUpf()
 
 void BattleWindow::bConsoleDownf()
 {
-	if (owner.actionsController->spellcastingModeActive())
+	if (owner.actionsController->heroSpellcastingModeActive())
 		return;
 
 	console->scrollDown();
@@ -851,8 +851,8 @@ void BattleWindow::blockUI(bool on)
 	setShortcutBlocked(EShortcut::BATTLE_WAIT, on || owner.tacticsMode || !canWait);
 	setShortcutBlocked(EShortcut::BATTLE_DEFEND, on || owner.tacticsMode);
 	setShortcutBlocked(EShortcut::BATTLE_SELECT_ACTION, on || owner.tacticsMode);
-	setShortcutBlocked(EShortcut::BATTLE_AUTOCOMBAT, (settings["battle"]["endWithAutocombat"].Bool() && onlyOnePlayerHuman) ? on || owner.tacticsMode || owner.actionsController->spellcastingModeActive() : owner.actionsController->spellcastingModeActive());
-	setShortcutBlocked(EShortcut::BATTLE_END_WITH_AUTOCOMBAT, on || owner.tacticsMode || !onlyOnePlayerHuman || owner.actionsController->spellcastingModeActive());
+	setShortcutBlocked(EShortcut::BATTLE_AUTOCOMBAT, (settings["battle"]["endWithAutocombat"].Bool() && onlyOnePlayerHuman) ? on || owner.tacticsMode || owner.actionsController->heroSpellcastingModeActive() : owner.actionsController->heroSpellcastingModeActive());
+	setShortcutBlocked(EShortcut::BATTLE_END_WITH_AUTOCOMBAT, on || owner.tacticsMode || !onlyOnePlayerHuman || owner.actionsController->heroSpellcastingModeActive());
 	setShortcutBlocked(EShortcut::BATTLE_TACTICS_END, on || !owner.tacticsMode);
 	setShortcutBlocked(EShortcut::BATTLE_TACTICS_NEXT, on || !owner.tacticsMode);
 	setShortcutBlocked(EShortcut::BATTLE_CONSOLE_DOWN, on && !owner.tacticsMode);