1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-24 08:32:34 +02:00

Moved battle netpack validation to battle processor

This commit is contained in:
Ivan Savenko 2023-08-13 23:08:53 +03:00
parent 323772fc2e
commit 5c78060a07
3 changed files with 86 additions and 42 deletions

View File

@ -282,48 +282,18 @@ void ApplyGhNetPackVisitor::visitQueryReply(QueryReply & pack)
void ApplyGhNetPackVisitor::visitMakeAction(MakeAction & pack)
{
const BattleInfo * b = gs.curB;
if(!b)
gh.throwAndComplain(&pack, "Can not make action - there is no battle ongoing!");
if (!gh.hasPlayerAt(pack.player, pack.c))
gh.throwAndComplain(&pack, "No such pack.player!");
if(b->tacticDistance)
{
if(pack.ba.actionType != EActionType::WALK && pack.ba.actionType != EActionType::END_TACTIC_PHASE
&& pack.ba.actionType != EActionType::RETREAT && pack.ba.actionType != EActionType::SURRENDER)
gh.throwAndComplain(&pack, "Can not make actions while in tactics mode!");
if(!vstd::contains(gh.connections[b->sides[b->tacticsSide].color], pack.c))
gh.throwAndComplain(&pack, "Can not make actions in battles you are not part of!");
}
else
{
auto active = b->battleActiveUnit();
if(!active)
gh.throwAndComplain(&pack, "No active unit in battle!");
auto unitOwner = b->battleGetOwner(active);
if(!vstd::contains(gh.connections[unitOwner], pack.c))
gh.throwAndComplain(&pack, "Can not make actions in battles you are not part of!");
}
result = gh.battles->makeBattleAction(pack.ba);
result = gh.battles->makeBattleAction(pack.player, pack.ba);
}
void ApplyGhNetPackVisitor::visitMakeCustomAction(MakeCustomAction & pack)
{
const BattleInfo * b = gs.curB;
if(!b)
gh.throwNotAllowedAction(&pack);
if(b->tacticDistance)
gh.throwNotAllowedAction(&pack);
auto active = b->battleActiveUnit();
if(!active)
gh.throwNotAllowedAction(&pack);
auto unitOwner = b->battleGetOwner(active);
if(!vstd::contains(gh.connections[unitOwner], pack.c))
gh.throwNotAllowedAction(&pack);
if(pack.ba.actionType != EActionType::HERO_SPELL)
gh.throwNotAllowedAction(&pack);
if (!gh.hasPlayerAt(pack.player, pack.c))
gh.throwAndComplain(&pack, "No such pack.player!");
result = gh.battles->makeCustomAction(pack.ba);
result = gh.battles->makeCustomAction(pack.player, pack.ba);
}
void ApplyGhNetPackVisitor::visitDigWithHero(DigWithHero & pack)

View File

@ -349,7 +349,6 @@ void BattleProcessor::startBattlePrimary(const CArmedInstance *army1, const CArm
heroes[0] = hero1;
heroes[1] = hero2;
setupBattle(tile, armies, heroes, creatureBank, town); //initializes stacks, places creatures on battlefield, blocks and informs player interfaces
auto lastBattleQuery = std::dynamic_pointer_cast<CBattleQuery>(gameHandler->queries->topQuery(gameHandler->gameState()->curB->sides[0].color));
@ -819,7 +818,7 @@ bool BattleProcessor::makeAutomaticAction(const CStack *stack, BattleAction &ba)
bsa.askPlayerInterface = false;
gameHandler->sendAndApply(&bsa);
bool ret = makeBattleAction(ba);
bool ret = makeBattleActionImpl(ba);
checkBattleStateChanges();
return ret;
}
@ -2022,7 +2021,7 @@ void BattleProcessor::checkBattleStateChanges()
}
}
bool BattleProcessor::makeBattleAction(BattleAction &ba)
bool BattleProcessor::makeBattleActionImpl(BattleAction &ba)
{
bool ok = true;
@ -2445,7 +2444,7 @@ bool BattleProcessor::makeBattleAction(BattleAction &ba)
return ok;
}
bool BattleProcessor::makeCustomAction(BattleAction & ba)
bool BattleProcessor::makeCustomActionImpl(BattleAction & ba)
{
switch(ba.actionType)
{
@ -2752,3 +2751,75 @@ void BattleProcessor::updateGateState()
gameHandler->sendAndApply(&db);
}
bool BattleProcessor::makeBattleAction(PlayerColor player, BattleAction &ba)
{
boost::unique_lock lock(battleActionMutex);
const BattleInfo * b = gameHandler->gameState()->curB;
if(!b && gameHandler->complain("Can not make action - there is no battle ongoing!"))
return false;
if (ba.side != 0 && ba.side != 1 && gameHandler->complain("Can not make action - invalid battle side!"))
return false;
if(b->tacticDistance)
{
if(ba.actionType != EActionType::WALK && ba.actionType != EActionType::END_TACTIC_PHASE
&& ba.actionType != EActionType::RETREAT && ba.actionType != EActionType::SURRENDER)
{
gameHandler->complain("Can not make actions while in tactics mode!");
return false;
}
if(player != b->sides[ba.side].color)
{
gameHandler->complain("Can not make actions in battles you are not part of!");
return false;
}
}
else
{
auto active = b->battleActiveUnit();
if(!active && gameHandler->complain("No active unit in battle!"))
return false;
auto unitOwner = b->battleGetOwner(active);
if(player != unitOwner && gameHandler->complain("Can not make actions in battles you are not part of!"))
return false;
}
return makeBattleActionImpl(ba);
}
bool BattleProcessor::makeCustomAction(PlayerColor player, BattleAction &ba)
{
const BattleInfo * b = gameHandler->gameState()->curB;
if(!b && gameHandler->complain("Can not make action - there is no battle ongoing!"))
return false;
if (ba.side != 0 && ba.side != 1 && gameHandler->complain("Can not make action - invalid battle side!"))
return false;
if(b->tacticDistance)
{
gameHandler->complain("Can not cast spell during tactics mode!");
return false;
}
auto active = b->battleActiveUnit();
if(!active && gameHandler->complain("No active unit in battle!"))
return false;
auto unitOwner = b->battleGetOwner(active);
if(player != unitOwner && gameHandler->complain("Can not make actions in battles you are not part of!"))
return false;
if(ba.actionType != EActionType::HERO_SPELL && gameHandler->complain("Invalid custom action type!"))
return false;
return makeCustomActionImpl(ba);
}

View File

@ -100,6 +100,9 @@ class BattleProcessor : boost::noncopyable
void setupBattle(int3 tile, const CArmedInstance *armies[2], const CGHeroInstance *heroes[2], bool creatureBank, const CGTownInstance *town);
void setBattleResult(BattleResult::EResult resultType, int victoriusSide);
bool makeBattleActionImpl(BattleAction &ba);
bool makeCustomActionImpl(BattleAction &ba);
public:
CGameHandler * gameHandler;
@ -114,8 +117,8 @@ public:
void battleAfterLevelUp(const BattleResult &result);
bool makeBattleAction(BattleAction &ba);
bool makeCustomAction(BattleAction &ba);
bool makeBattleAction(PlayerColor player, BattleAction &ba);
bool makeCustomAction(PlayerColor player, BattleAction &ba);
void endBattle(int3 tile, const CGHeroInstance * hero1, const CGHeroInstance * hero2); //ends battle
void endBattleConfirm(const BattleInfo * battleInfo);