1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-04-11 11:31:52 +02:00

Business logic of alternative actions

This commit is contained in:
nordsoft 2022-12-20 03:28:20 +04:00 committed by Nordsoft91
parent ebe4121327
commit 87c47fff1d
4 changed files with 134 additions and 3 deletions

View File

@ -759,7 +759,30 @@ void BattleActionsController::activateStack()
{
const CStack * s = owner.stacksController->getActiveStack();
if(s)
{
possibleActions = getPossibleActionsForStack(s);
std::list<PossiblePlayerBattleAction> actionsToSelect;
if(!possibleActions.empty())
{
switch(possibleActions.front())
{
case PossiblePlayerBattleAction::SHOOT:
actionsToSelect.push_back(possibleActions.front());
actionsToSelect.push_back(PossiblePlayerBattleAction::ATTACK);
break;
case PossiblePlayerBattleAction::ATTACK_AND_RETURN:
actionsToSelect.push_back(possibleActions.front());
actionsToSelect.push_back(PossiblePlayerBattleAction::WALK_AND_ATTACK);
break;
case PossiblePlayerBattleAction::AIMED_SPELL_CREATURE:
actionsToSelect.push_back(possibleActions.front());
break;
}
}
owner.controlPanel->setAlternativeActions(actionsToSelect);
}
}
bool BattleActionsController::spellcastingModeActive() const
@ -773,3 +796,18 @@ SpellID BattleActionsController::selectedSpell() const
return SpellID::NONE;
return SpellID(spellToCast->actionSubtype);
}
const std::vector<PossiblePlayerBattleAction> & BattleActionsController::getPossibleActions() const
{
return possibleActions;
}
void BattleActionsController::removePossibleAction(PossiblePlayerBattleAction action)
{
vstd::erase(possibleActions, action);
}
void BattleActionsController::pushFrontPossibleAction(PossiblePlayerBattleAction action)
{
possibleActions.insert(possibleActions.begin(), action);
}

View File

@ -92,5 +92,12 @@ public:
/// returns true if UI is currently in target selection mode
bool spellcastingModeActive() const;
/// methods to work with array of possible actions, needed to control special creatures abilities
const std::vector<PossiblePlayerBattleAction> & getPossibleActions() const;
void removePossibleAction(PossiblePlayerBattleAction);
/// inserts possible action in the beggining in order to prioritize it
void pushFrontPossibleAction(PossiblePlayerBattleAction);
};

View File

@ -19,6 +19,7 @@
#include "../CPlayerInterface.h"
#include "../gui/CCursorHandler.h"
#include "../gui/CGuiHandler.h"
#include "../gui/CAnimation.h"
#include "../windows/CSpellWindow.h"
#include "../widgets/Buttons.h"
#include "../widgets/Images.h"
@ -43,14 +44,15 @@ BattleControlPanel::BattleControlPanel(BattleInterface & owner, const Point & po
bSpell = std::make_shared<CButton> (Point(645, 5), "icm005.def", CGI->generaltexth->zelp[385], std::bind(&BattleControlPanel::bSpellf,this), SDLK_c);
bWait = std::make_shared<CButton> (Point(696, 5), "icm006.def", CGI->generaltexth->zelp[386], std::bind(&BattleControlPanel::bWaitf,this), SDLK_w);
bDefence = std::make_shared<CButton> (Point(747, 5), "icm007.def", CGI->generaltexth->zelp[387], std::bind(&BattleControlPanel::bDefencef,this), SDLK_d);
bConsoleUp = std::make_shared<CButton> (Point(624, 5), "ComSlide.def", std::make_pair("", ""), std::bind(&BattleControlPanel::bConsoleUpf,this), SDLK_UP);
bConsoleDown = std::make_shared<CButton>(Point(624, 24), "ComSlide.def", std::make_pair("", ""), std::bind(&BattleControlPanel::bConsoleDownf,this), SDLK_DOWN);
bSwitchAction = std::make_shared<CButton>(Point(589, 5), "icmalt00", CGI->generaltexth->zelp[387], std::bind(&BattleControlPanel::bSwitchActionf,this), SDLK_r);
bConsoleUp = std::make_shared<CButton> (Point(578, 5), "ComSlide.def", std::make_pair("", ""), std::bind(&BattleControlPanel::bConsoleUpf,this), SDLK_UP);
bConsoleDown = std::make_shared<CButton>(Point(578, 24), "ComSlide.def", std::make_pair("", ""), std::bind(&BattleControlPanel::bConsoleDownf,this), SDLK_DOWN);
bDefence->assignedKeys.insert(SDLK_SPACE);
bConsoleUp->setImageOrder(0, 1, 0, 0);
bConsoleDown->setImageOrder(2, 3, 2, 2);
console = std::make_shared<BattleConsole>(Rect(211, 4, 406,38));
console = std::make_shared<BattleConsole>(Rect(211, 4, 350 ,38));
GH.statusbar = console;
if ( owner.tacticsMode )
@ -174,6 +176,52 @@ void BattleControlPanel::reallySurrender()
}
}
void BattleControlPanel::showAlternativeActionIcon(PossiblePlayerBattleAction action)
{
std::string iconName = "icmalt00";
switch(action)
{
case PossiblePlayerBattleAction::ATTACK:
iconName = "icmalt01";
break;
case PossiblePlayerBattleAction::SHOOT:
iconName = "icmalt02";
break;
case PossiblePlayerBattleAction::AIMED_SPELL_CREATURE:
iconName = "icmalt03";
break;
//case PossiblePlayerBattleAction::ATTACK_AND_RETURN:
//iconName = "icmalt04";
//break;
case PossiblePlayerBattleAction::ATTACK_AND_RETURN:
iconName = "icmalt05";
break;
case PossiblePlayerBattleAction::WALK_AND_ATTACK:
iconName = "icmalt06";
break;
}
auto anim = std::make_shared<CAnimation>(iconName);
bSwitchAction->setImage(anim, false);
}
void BattleControlPanel::setAlternativeActions(const std::list<PossiblePlayerBattleAction> & actions)
{
alternativeActions = actions;
defaultAction = PossiblePlayerBattleAction::INVALID;
if(alternativeActions.size() > 1)
defaultAction = alternativeActions.back();
if(!alternativeActions.empty())
showAlternativeActionIcon(alternativeActions.front());
else
showAlternativeActionIcon(defaultAction);
}
void BattleControlPanel::bAutofightf()
{
if (owner.actionsController->spellcastingModeActive())
@ -243,6 +291,33 @@ void BattleControlPanel::bSpellf()
}
}
void BattleControlPanel::bSwitchActionf()
{
if(alternativeActions.empty())
return;
if(alternativeActions.front() == defaultAction)
{
alternativeActions.push_back(alternativeActions.front());
alternativeActions.pop_front();
}
auto actions = owner.actionsController->getPossibleActions();
if(!actions.empty() && actions.front() == alternativeActions.front())
{
owner.actionsController->removePossibleAction(alternativeActions.front());
showAlternativeActionIcon(defaultAction);
}
else
{
owner.actionsController->pushFrontPossibleAction(alternativeActions.front());
showAlternativeActionIcon(alternativeActions.front());
}
alternativeActions.push_back(alternativeActions.front());
alternativeActions.pop_front();
}
void BattleControlPanel::bWaitf()
{
if (owner.actionsController->spellcastingModeActive())

View File

@ -10,6 +10,7 @@
#pragma once
#include "../gui/CIntObject.h"
#include "../../lib/battle/CBattleInfoCallback.h"
VCMI_LIB_NAMESPACE_BEGIN
class CStack;
@ -31,6 +32,7 @@ class BattleControlPanel : public CIntObject
std::shared_ptr<CButton> bSurrender;
std::shared_ptr<CButton> bFlee;
std::shared_ptr<CButton> bAutofight;
std::shared_ptr<CButton> bSwitchAction;
std::shared_ptr<CButton> bSpell;
std::shared_ptr<CButton> bWait;
std::shared_ptr<CButton> bDefence;
@ -46,6 +48,7 @@ class BattleControlPanel : public CIntObject
void bAutofightf();
void bSpellf();
void bWaitf();
void bSwitchActionf();
void bDefencef();
void bConsoleUpf();
void bConsoleDownf();
@ -55,6 +58,11 @@ class BattleControlPanel : public CIntObject
/// functions for handling actions after they were confirmed by popup window
void reallyFlee();
void reallySurrender();
/// management of alternative actions
std::list<PossiblePlayerBattleAction> alternativeActions;
PossiblePlayerBattleAction defaultAction;
void showAlternativeActionIcon(PossiblePlayerBattleAction);
public:
std::shared_ptr<BattleConsole> console;
@ -70,6 +78,9 @@ public:
/// Toggle UI to displaying battle log in place of tactics UI
void tacticPhaseEnded();
/// Set possible alternative options. If more than 1 - the last will be considered as default option
void setAlternativeActions(const std::list<PossiblePlayerBattleAction> &);
BattleControlPanel(BattleInterface & owner, const Point & position);
};