1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-07-05 00:49:09 +02:00

All spellcasters should work correctly now

This commit is contained in:
Ivan Savenko
2023-01-25 16:39:34 +02:00
parent 55a58596bc
commit f150ced14c
2 changed files with 40 additions and 41 deletions

View File

@ -42,44 +42,31 @@ static std::string formatDmgRange(std::pair<ui32, ui32> dmgRange)
BattleActionsController::BattleActionsController(BattleInterface & owner): BattleActionsController::BattleActionsController(BattleInterface & owner):
owner(owner), owner(owner),
heroSpellToCast(nullptr) heroSpellToCast(nullptr),
creatureSpellToCast(nullptr)
{} {}
void BattleActionsController::endCastingSpell() void BattleActionsController::endCastingSpell()
{ {
if(heroSpellToCast) if(heroSpellToCast)
{
heroSpellToCast.reset(); heroSpellToCast.reset();
if(owner.stacksController->getActiveStack()) if(owner.stacksController->getActiveStack())
possibleActions = getPossibleActionsForStack(owner.stacksController->getActiveStack()); //restore actions after they were cleared possibleActions = getPossibleActionsForStack(owner.stacksController->getActiveStack()); //restore actions after they were cleared
}
else
{
if(owner.stacksController->getActiveStack())
possibleActions = getPossibleActionsForStack(owner.stacksController->getActiveStack());
}
GH.fakeMouseMove(); GH.fakeMouseMove();
} }
bool BattleActionsController::isActiveStackFixedSpellcaster() const bool BattleActionsController::isActiveStackSpellcaster() const
{ {
const CStack * casterStack = owner.stacksController->getActiveStack(); const CStack * casterStack = owner.stacksController->getActiveStack();
assert(casterStack); if (!casterStack)
return false;
const auto randomSpellcaster = casterStack->getBonusLocalFirst(Selector::type()(Bonus::SPELLCASTER)); const auto randomSpellcaster = casterStack->getBonusLocalFirst(Selector::type()(Bonus::SPELLCASTER));
return (randomSpellcaster && casterStack->canCast()); return (randomSpellcaster && casterStack->canCast());
} }
bool BattleActionsController::isActiveStackRandomSpellcaster() const
{
const CStack * casterStack = owner.stacksController->getActiveStack();
assert(casterStack);
const auto randomSpellcaster = casterStack->getBonusLocalFirst(Selector::type()(Bonus::RANDOM_SPELLCASTER));
return (randomSpellcaster && casterStack->canCast());
}
void BattleActionsController::enterCreatureCastingMode() void BattleActionsController::enterCreatureCastingMode()
{ {
//silently check for possible errors //silently check for possible errors
@ -93,7 +80,7 @@ void BattleActionsController::enterCreatureCastingMode()
if (!owner.stacksController->getActiveStack()) if (!owner.stacksController->getActiveStack())
return; return;
if (!isActiveStackFixedSpellcaster()) if (!isActiveStackSpellcaster())
return; return;
if (vstd::contains(possibleActions, PossiblePlayerBattleAction::NO_LOCATION)) if (vstd::contains(possibleActions, PossiblePlayerBattleAction::NO_LOCATION))
@ -138,7 +125,12 @@ void BattleActionsController::enterCreatureCastingMode()
std::vector<PossiblePlayerBattleAction> BattleActionsController::getPossibleActionsForStack(const CStack *stack) const std::vector<PossiblePlayerBattleAction> BattleActionsController::getPossibleActionsForStack(const CStack *stack) const
{ {
BattleClientInterfaceData data; //hard to get rid of these things so for now they're required data to pass BattleClientInterfaceData data; //hard to get rid of these things so for now they're required data to pass
if (getStackSpellToCast(BattleHex::INVALID))
data.creatureSpellToCast = getStackSpellToCast(BattleHex::INVALID)->getId(); data.creatureSpellToCast = getStackSpellToCast(BattleHex::INVALID)->getId();
else
data.creatureSpellToCast = SpellID::NONE;
data.tacticsMode = owner.tacticsMode; data.tacticsMode = owner.tacticsMode;
auto allActions = owner.curInt->cb->getClientActionsForStack(stack, data); auto allActions = owner.curInt->cb->getClientActionsForStack(stack, data);
@ -233,6 +225,9 @@ const CSpell * BattleActionsController::getHeroSpellToCast( ) const
const CSpell * BattleActionsController::getStackSpellToCast( BattleHex targetHex ) const const CSpell * BattleActionsController::getStackSpellToCast( BattleHex targetHex ) const
{ {
if (isActiveStackSpellcaster())
return creatureSpellToCast;
return nullptr; return nullptr;
} }
@ -589,7 +584,7 @@ void BattleActionsController::actionRealize(PossiblePlayerBattleAction action, B
} }
} }
if (spellcastingModeActive()) if (!spellcastingModeActive())
{ {
if (getStackSpellToCast(targetHex)) if (getStackSpellToCast(targetHex))
{ {
@ -652,6 +647,15 @@ void BattleActionsController::onHexHovered(BattleHex hoveredHex)
if (owner.stacksController->getActiveStack() == nullptr) if (owner.stacksController->getActiveStack() == nullptr)
return; return;
if (hoveredHex == BattleHex::INVALID)
{
if (!currentConsoleMsg.empty())
GH.statusbar->clearIfMatching(currentConsoleMsg);
currentConsoleMsg.clear();
return;
}
auto action = selectAction(hoveredHex); auto action = selectAction(hoveredHex);
std::string newConsoleMsg; std::string newConsoleMsg;
@ -695,18 +699,14 @@ void BattleActionsController::onHexClicked(BattleHex clickedHex)
void BattleActionsController::tryActivateStackSpellcasting(const CStack *casterStack) void BattleActionsController::tryActivateStackSpellcasting(const CStack *casterStack)
{ {
//set casting flag to true if creature can use it to not check it every time const auto spellcaster = casterStack->getBonusLocalFirst(Selector::type()(Bonus::SPELLCASTER));
//const auto spellcaster = casterStack->getBonusLocalFirst(Selector::type()(Bonus::SPELLCASTER)); if(casterStack->canCast() && spellcaster)
//const auto randomSpellcaster = casterStack->getBonusLocalFirst(Selector::type()(Bonus::RANDOM_SPELLCASTER)); {
//if(casterStack->canCast() && (spellcaster || randomSpellcaster)) // faerie dragon can cast only one, randomly selected spell until their next move
//{ //TODO: what if creature can cast BOTH random genie spell and aimed spell?
// if(!randomSpellcaster) //TODO: faerie dragon type spell should be selected by server
// creatureSpellToCast = -1; //spell will be set later on cast creatureSpellToCast = owner.curInt->cb->battleGetRandomStackSpell(CRandomGenerator::getDefault(), casterStack, CBattleInfoCallback::RANDOM_AIMED).toSpell();
// else }
// creatureSpellToCast = owner.curInt->cb->battleGetRandomStackSpell(CRandomGenerator::getDefault(), casterStack, CBattleInfoCallback::RANDOM_AIMED); //faerie dragon can cast only one spell until their next move
// //TODO: what if creature can cast BOTH random genie spell and aimed spell?
// //TODO: faerie dragon type spell should be selected by server
//}
} }
const spells::Caster * BattleActionsController::getCurrentSpellcaster() const const spells::Caster * BattleActionsController::getCurrentSpellcaster() const
@ -759,6 +759,8 @@ void BattleActionsController::activateStack()
const CStack * s = owner.stacksController->getActiveStack(); const CStack * s = owner.stacksController->getActiveStack();
if(s) if(s)
{ {
tryActivateStackSpellcasting(s);
possibleActions = getPossibleActionsForStack(s); possibleActions = getPossibleActionsForStack(s);
std::list<PossiblePlayerBattleAction> actionsToSelect; std::list<PossiblePlayerBattleAction> actionsToSelect;
if(!possibleActions.empty()) if(!possibleActions.empty())

View File

@ -97,15 +97,12 @@ public:
/// returns spell that is currently being cast by hero or nullptr if none /// returns spell that is currently being cast by hero or nullptr if none
const CSpell * getHeroSpellToCast() const; const CSpell * getHeroSpellToCast() const;
/// if current stack is spellcaster, returns /// if current stack is spellcaster, returns spell being cast, or null othervice
const CSpell * getStackSpellToCast( BattleHex targetHex ) const; const CSpell * getStackSpellToCast( BattleHex targetHex ) const;
const CSpell * getAnySpellToCast( BattleHex targetHex ) const; const CSpell * getAnySpellToCast( BattleHex targetHex ) const;
/// returns true if current stack is a spellcaster /// returns true if current stack is a spellcaster
bool isActiveStackFixedSpellcaster() const; bool isActiveStackSpellcaster() const;
/// returns true if current stack is random spellcaster (e.g. Genie)
bool isActiveStackRandomSpellcaster() const;
/// methods to work with array of possible actions, needed to control special creatures abilities /// methods to work with array of possible actions, needed to control special creatures abilities
const std::vector<PossiblePlayerBattleAction> & getPossibleActions() const; const std::vector<PossiblePlayerBattleAction> & getPossibleActions() const;