mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-24 08:32:34 +02:00
Spellcasters UI now shares handling with hero spellcasting
This commit is contained in:
parent
dbbbba5f2d
commit
c3b79c786b
@ -86,7 +86,7 @@ void BattleActionsController::enterCreatureCastingMode()
|
||||
if (vstd::contains(possibleActions, PossiblePlayerBattleAction::NO_LOCATION))
|
||||
{
|
||||
const spells::Caster * caster = owner.stacksController->getActiveStack();
|
||||
const CSpell * spell = getStackSpellToCast(BattleHex::INVALID);
|
||||
const CSpell * spell = getStackSpellToCast();
|
||||
|
||||
spells::Target target;
|
||||
target.emplace_back();
|
||||
@ -126,8 +126,8 @@ std::vector<PossiblePlayerBattleAction> BattleActionsController::getPossibleActi
|
||||
{
|
||||
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();
|
||||
if (getStackSpellToCast())
|
||||
data.creatureSpellToCast = getStackSpellToCast()->getId();
|
||||
else
|
||||
data.creatureSpellToCast = SpellID::NONE;
|
||||
|
||||
@ -175,6 +175,8 @@ void BattleActionsController::reorderPossibleActionsPriority(const CStack * stac
|
||||
return 10; break;
|
||||
case PossiblePlayerBattleAction::CREATURE_INFO:
|
||||
return 11; break;
|
||||
case PossiblePlayerBattleAction::TELEPORT:
|
||||
return 12; break;
|
||||
default:
|
||||
assert(0);
|
||||
return 200; break;
|
||||
@ -223,7 +225,7 @@ const CSpell * BattleActionsController::getHeroSpellToCast( ) const
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const CSpell * BattleActionsController::getStackSpellToCast( BattleHex targetHex ) const
|
||||
const CSpell * BattleActionsController::getStackSpellToCast( ) const
|
||||
{
|
||||
if (isActiveStackSpellcaster())
|
||||
return creatureSpellToCast;
|
||||
@ -231,11 +233,11 @@ const CSpell * BattleActionsController::getStackSpellToCast( BattleHex targetHex
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const CSpell * BattleActionsController::getAnySpellToCast( BattleHex targetHex ) const
|
||||
const CSpell * BattleActionsController::getCurrentSpell( ) const
|
||||
{
|
||||
if (getHeroSpellToCast())
|
||||
return getHeroSpellToCast();
|
||||
return getStackSpellToCast(targetHex);
|
||||
return getStackSpellToCast();
|
||||
}
|
||||
|
||||
const CStack * BattleActionsController::getStackForHex(BattleHex hoveredHex)
|
||||
@ -364,10 +366,10 @@ std::string BattleActionsController::actionGetStatusMessage(PossiblePlayerBattle
|
||||
}
|
||||
|
||||
case PossiblePlayerBattleAction::AIMED_SPELL_CREATURE:
|
||||
return boost::str(boost::format(CGI->generaltexth->allTexts[27]) % getAnySpellToCast(targetHex)->getNameTranslated() % targetStack->getName()); //Cast %s on %s
|
||||
return boost::str(boost::format(CGI->generaltexth->allTexts[27]) % getCurrentSpell()->getNameTranslated() % targetStack->getName()); //Cast %s on %s
|
||||
|
||||
case PossiblePlayerBattleAction::ANY_LOCATION:
|
||||
return boost::str(boost::format(CGI->generaltexth->allTexts[26]) % getAnySpellToCast(targetHex)->getNameTranslated()); //Cast %s
|
||||
return boost::str(boost::format(CGI->generaltexth->allTexts[26]) % getCurrentSpell()->getNameTranslated()); //Cast %s
|
||||
|
||||
case PossiblePlayerBattleAction::RANDOM_GENIE_SPELL: //we assume that teleport / sacrifice will never be available as random spell
|
||||
return boost::str(boost::format(CGI->generaltexth->allTexts[301]) % targetStack->getName()); //Cast a spell on %
|
||||
@ -382,7 +384,7 @@ std::string BattleActionsController::actionGetStatusMessage(PossiblePlayerBattle
|
||||
return (boost::format(CGI->generaltexth->allTexts[549]) % targetStack->getName()).str(); //sacrifice the %s
|
||||
|
||||
case PossiblePlayerBattleAction::FREE_LOCATION:
|
||||
return boost::str(boost::format(CGI->generaltexth->allTexts[26]) % getAnySpellToCast(targetHex)->getNameTranslated()); //Cast %s
|
||||
return boost::str(boost::format(CGI->generaltexth->allTexts[26]) % getCurrentSpell()->getNameTranslated()); //Cast %s
|
||||
|
||||
case PossiblePlayerBattleAction::HEAL:
|
||||
return (boost::format(CGI->generaltexth->allTexts[419]) % targetStack->getName()).str(); //Apply first aid to the %s
|
||||
@ -412,7 +414,7 @@ std::string BattleActionsController::actionGetStatusMessageBlocked(PossiblePlaye
|
||||
return CGI->generaltexth->allTexts[543]; //choose army to sacrifice
|
||||
break;
|
||||
case PossiblePlayerBattleAction::FREE_LOCATION:
|
||||
return boost::str(boost::format(CGI->generaltexth->allTexts[181]) % getAnySpellToCast(targetHex)->getNameTranslated()); //No room to place %s here
|
||||
return boost::str(boost::format(CGI->generaltexth->allTexts[181]) % getCurrentSpell()->getNameTranslated()); //No room to place %s here
|
||||
break;
|
||||
default:
|
||||
return "";
|
||||
@ -570,25 +572,27 @@ void BattleActionsController::actionRealize(PossiblePlayerBattleAction action, B
|
||||
{
|
||||
if (action == PossiblePlayerBattleAction::AIMED_SPELL_CREATURE )
|
||||
{
|
||||
if (getAnySpellToCast(targetHex)->id == SpellID::SACRIFICE)
|
||||
if (getCurrentSpell()->id == SpellID::SACRIFICE)
|
||||
{
|
||||
heroSpellToCast->aimToHex(targetHex);
|
||||
possibleActions.push_back(PossiblePlayerBattleAction::SACRIFICE);
|
||||
owner.stacksController->setSelectedStack(targetStack);
|
||||
return;
|
||||
}
|
||||
if (getAnySpellToCast(targetHex)->id == SpellID::TELEPORT)
|
||||
if (getCurrentSpell()->id == SpellID::TELEPORT)
|
||||
{
|
||||
heroSpellToCast->aimToUnit(targetStack);
|
||||
possibleActions.push_back(PossiblePlayerBattleAction::TELEPORT);
|
||||
owner.stacksController->setSelectedStack(targetStack);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!spellcastingModeActive())
|
||||
{
|
||||
if (getStackSpellToCast(targetHex))
|
||||
if (getStackSpellToCast())
|
||||
{
|
||||
owner.giveCommand(EActionType::MONSTER_SPELL, targetHex, getStackSpellToCast(targetHex)->getId());
|
||||
owner.giveCommand(EActionType::MONSTER_SPELL, targetHex, getStackSpellToCast()->getId());
|
||||
}
|
||||
else //unknown random spell
|
||||
{
|
||||
@ -703,7 +707,6 @@ void BattleActionsController::tryActivateStackSpellcasting(const CStack *casterS
|
||||
if(casterStack->canCast() && spellcaster)
|
||||
{
|
||||
// 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?
|
||||
//TODO: faerie dragon type spell should be selected by server
|
||||
creatureSpellToCast = owner.curInt->cb->battleGetRandomStackSpell(CRandomGenerator::getDefault(), casterStack, CBattleInfoCallback::RANDOM_AIMED).toSpell();
|
||||
}
|
||||
@ -715,12 +718,20 @@ const spells::Caster * BattleActionsController::getCurrentSpellcaster() const
|
||||
return owner.getActiveHero();
|
||||
else
|
||||
return owner.stacksController->getActiveStack();
|
||||
}
|
||||
|
||||
spells::Mode BattleActionsController::getCurrentCastMode() const
|
||||
{
|
||||
if (heroSpellToCast)
|
||||
return spells::Mode::HERO;
|
||||
else
|
||||
return spells::Mode::CREATURE_ACTIVE;
|
||||
|
||||
}
|
||||
|
||||
bool BattleActionsController::isCastingPossibleHere(const CStack *casterStack, const CStack *targetStack, BattleHex targetHex)
|
||||
{
|
||||
auto currentSpell = getAnySpellToCast(targetHex);
|
||||
auto currentSpell = getCurrentSpell();
|
||||
assert(currentSpell);
|
||||
|
||||
if (!currentSpell)
|
||||
@ -791,6 +802,24 @@ bool BattleActionsController::spellcastingModeActive() const
|
||||
return heroSpellToCast != nullptr;;
|
||||
}
|
||||
|
||||
bool BattleActionsController::currentActionSpellcasting(BattleHex hoveredHex)
|
||||
{
|
||||
if (heroSpellToCast)
|
||||
return true;
|
||||
|
||||
if (!owner.stacksController->getActiveStack())
|
||||
return false;
|
||||
|
||||
auto action = selectAction(hoveredHex);
|
||||
|
||||
return
|
||||
action == PossiblePlayerBattleAction::ANY_LOCATION ||
|
||||
action == PossiblePlayerBattleAction::NO_LOCATION ||
|
||||
action == PossiblePlayerBattleAction::FREE_LOCATION ||
|
||||
action == PossiblePlayerBattleAction::AIMED_SPELL_CREATURE ||
|
||||
action == PossiblePlayerBattleAction::OBSTACLE;
|
||||
}
|
||||
|
||||
const std::vector<PossiblePlayerBattleAction> & BattleActionsController::getPossibleActions() const
|
||||
{
|
||||
return possibleActions;
|
||||
|
@ -16,6 +16,7 @@ VCMI_LIB_NAMESPACE_BEGIN
|
||||
class BattleAction;
|
||||
namespace spells {
|
||||
class Caster;
|
||||
enum class Mode;
|
||||
}
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
@ -63,13 +64,21 @@ class BattleActionsController
|
||||
|
||||
PossiblePlayerBattleAction selectAction(BattleHex myNumber);
|
||||
|
||||
const CStack * getStackForHex(BattleHex myNumber);
|
||||
const CStack * getStackForHex(BattleHex myNumber) ;
|
||||
|
||||
/// attempts to initialize spellcasting action for stack
|
||||
/// will silently return if stack is not a spellcaster
|
||||
void tryActivateStackSpellcasting(const CStack *casterStack);
|
||||
|
||||
const spells::Caster * getCurrentSpellcaster() const;
|
||||
/// returns spell that is currently being cast by hero or nullptr if none
|
||||
const CSpell * getHeroSpellToCast() const;
|
||||
|
||||
/// if current stack is spellcaster, returns spell being cast, or null othervice
|
||||
const CSpell * getStackSpellToCast( ) const;
|
||||
|
||||
/// returns true if current stack is a spellcaster
|
||||
bool isActiveStackSpellcaster() const;
|
||||
|
||||
public:
|
||||
BattleActionsController(BattleInterface & owner);
|
||||
|
||||
@ -79,6 +88,12 @@ public:
|
||||
/// returns true if UI is currently in target selection mode
|
||||
bool spellcastingModeActive() const;
|
||||
|
||||
/// returns true if one of the following is true:
|
||||
/// - we are casting spell by hero
|
||||
/// - we are casting spell by creature in targeted mode (F hotkey)
|
||||
/// - current creature is spellcaster and preferred action for current hex is spellcast
|
||||
bool currentActionSpellcasting(BattleHex hoveredHex);
|
||||
|
||||
/// enter targeted spellcasting mode for creature, e.g. via "F" hotkey
|
||||
void enterCreatureCastingMode();
|
||||
|
||||
@ -94,15 +109,9 @@ public:
|
||||
/// performs action according to selected hex
|
||||
void onHexClicked(BattleHex clickedHex);
|
||||
|
||||
/// returns spell that is currently being cast by hero or nullptr if none
|
||||
const CSpell * getHeroSpellToCast() const;
|
||||
|
||||
/// if current stack is spellcaster, returns spell being cast, or null othervice
|
||||
const CSpell * getStackSpellToCast( BattleHex targetHex ) const;
|
||||
const CSpell * getAnySpellToCast( BattleHex targetHex ) const;
|
||||
|
||||
/// returns true if current stack is a spellcaster
|
||||
bool isActiveStackSpellcaster() const;
|
||||
const spells::Caster * getCurrentSpellcaster() const;
|
||||
const CSpell * getCurrentSpell() const;
|
||||
spells::Mode getCurrentCastMode() const;
|
||||
|
||||
/// methods to work with array of possible actions, needed to control special creatures abilities
|
||||
const std::vector<PossiblePlayerBattleAction> & getPossibleActions() const;
|
||||
|
@ -230,25 +230,15 @@ std::set<BattleHex> BattleFieldController::getHighlightedHexesSpellRange()
|
||||
if(!settings["battle"]["mouseShadow"].Bool())
|
||||
return result;
|
||||
|
||||
const spells::Caster *caster = nullptr;
|
||||
const CSpell *spell = nullptr;
|
||||
|
||||
spells::Mode mode = spells::Mode::HERO;
|
||||
|
||||
if(owner.actionsController->spellcastingModeActive())//hero casts spell
|
||||
{
|
||||
spell = owner.actionsController->getHeroSpellToCast();
|
||||
caster = owner.getActiveHero();
|
||||
}
|
||||
else if(owner.actionsController->getStackSpellToCast(hoveredHex) != nullptr)//stack casts spell
|
||||
{
|
||||
spell = owner.actionsController->getStackSpellToCast(hoveredHex);
|
||||
caster = owner.stacksController->getActiveStack();
|
||||
mode = spells::Mode::CREATURE_ACTIVE;
|
||||
}
|
||||
|
||||
if(caster && spell) //when casting spell
|
||||
{
|
||||
const spells::Caster *caster = nullptr;
|
||||
const CSpell *spell = nullptr;
|
||||
|
||||
spells::Mode mode = owner.actionsController->getCurrentCastMode();
|
||||
spell = owner.actionsController->getCurrentSpell();
|
||||
caster = owner.actionsController->getCurrentSpellcaster();
|
||||
|
||||
if(caster && spell) //when casting spell
|
||||
{
|
||||
// printing shaded hex(es)
|
||||
spells::BattleCast event(owner.curInt->cb.get(), caster, mode, spell);
|
||||
auto shaded = spell->battleMechanics(&event)->rangeInHexes(hoveredHex);
|
||||
@ -307,13 +297,16 @@ std::set<BattleHex> BattleFieldController::getHighlightedHexesMovementTarget()
|
||||
void BattleFieldController::showHighlightedHexes(Canvas & canvas)
|
||||
{
|
||||
std::set<BattleHex> hoveredStack = getHighlightedHexesStackRange();
|
||||
std::set<BattleHex> hoveredSpell = getHighlightedHexesSpellRange();
|
||||
std::set<BattleHex> hoveredMove = getHighlightedHexesMovementTarget();
|
||||
|
||||
auto const & hoveredMouse = owner.actionsController->spellcastingModeActive() ? hoveredSpell : hoveredMove;
|
||||
|
||||
for(int b=0; b<GameConstants::BFIELD_SIZE; ++b)
|
||||
{
|
||||
std::set<BattleHex> hoveredSpell = getHighlightedHexesSpellRange();
|
||||
std::set<BattleHex> hoveredMove = getHighlightedHexesMovementTarget();
|
||||
|
||||
if (getHoveredHex() == BattleHex::INVALID)
|
||||
return;
|
||||
|
||||
auto const & hoveredMouse = owner.actionsController->currentActionSpellcasting(getHoveredHex()) ? hoveredSpell : hoveredMove;
|
||||
|
||||
for(int b=0; b<GameConstants::BFIELD_SIZE; ++b)
|
||||
{
|
||||
bool stack = hoveredStack.count(b);
|
||||
bool mouse = hoveredMouse.count(b);
|
||||
|
||||
|
@ -871,21 +871,11 @@ std::vector<const CStack *> BattleStacksController::selectHoveredStacks()
|
||||
const spells::Caster *caster = nullptr;
|
||||
const CSpell *spell = nullptr;
|
||||
|
||||
spells::Mode mode = spells::Mode::HERO;
|
||||
spells::Mode mode = owner.actionsController->getCurrentCastMode();
|
||||
spell = owner.actionsController->getCurrentSpell();
|
||||
caster = owner.actionsController->getCurrentSpellcaster();
|
||||
|
||||
if(owner.actionsController->spellcastingModeActive())//hero casts spell
|
||||
{
|
||||
spell = owner.actionsController->getHeroSpellToCast();
|
||||
caster = owner.getActiveHero();
|
||||
}
|
||||
else if(owner.actionsController->getStackSpellToCast(hoveredHex) != nullptr)//stack casts spell
|
||||
{
|
||||
spell = owner.actionsController->getStackSpellToCast(hoveredHex);
|
||||
caster = owner.stacksController->getActiveStack();
|
||||
mode = spells::Mode::CREATURE_ACTIVE;
|
||||
}
|
||||
|
||||
if(caster && spell) //when casting spell
|
||||
if(caster && spell && owner.actionsController->currentActionSpellcasting(hoveredHex) ) //when casting spell
|
||||
{
|
||||
spells::Target target;
|
||||
target.emplace_back(hoveredHex);
|
||||
|
Loading…
Reference in New Issue
Block a user