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:
@ -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())
|
||||||
|
@ -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;
|
||||||
|
Reference in New Issue
Block a user