1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-06-17 00:07:41 +02:00

Merged fixes from the branch.

This commit is contained in:
Michał W. Urbańczyk
2013-09-28 00:58:33 +00:00
20 changed files with 167 additions and 61 deletions

View File

@ -3253,13 +3253,18 @@ static EndAction end_action;
bool CGameHandler::makeBattleAction( BattleAction &ba )
{
logGlobal->errorStream() << "\tMaking action of type " << ba.actionType;
bool ok = true;
const CStack *stack = battleGetStackByID(ba.stackNumber); //may be nullptr if action is not about stack
const CStack *destinationStack = ba.actionType == Battle::WALK_AND_ATTACK ? gs->curB->battleGetStackByPos(ba.additionalInfo)
: ba.actionType == Battle::SHOOT ? gs->curB->battleGetStackByPos(ba.destinationTile)
: nullptr;
const bool isAboutActiveStack = stack && (stack == battleActiveStack());
logGlobal->traceStream() << boost::format(
"Making action: type=%d; side=%d; stack=%s; dst=%s; additionalInfo=%d; stackAtDst=%s")
% ba.actionType % (int)ba.side % (stack ? stack->getName() : std::string("none"))
% ba.destinationTile % ba.additionalInfo % (destinationStack ? destinationStack->getName() : std::string("none"));
switch(ba.actionType)
{
@ -3370,8 +3375,7 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
StartAction start_action(ba);
sendAndApply(&start_action); //start movement and attack
const CStack *stackAtEnd = gs->curB->battleGetStackByPos(ba.additionalInfo);
if(!stack || !stackAtEnd)
if(!stack || !destinationStack)
{
sendAndApply(&end_action);
break;
@ -3380,7 +3384,7 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
BattleHex startingPos = stack->position;
int distance = moveStack(ba.stackNumber, ba.destinationTile);
logGlobal->traceStream() << stack->nodeName() << " will attack " << stackAtEnd->nodeName();
logGlobal->traceStream() << stack->nodeName() << " will attack " << destinationStack->nodeName();
if(stack->position != ba.destinationTile //we wasn't able to reach destination tile
&& !(stack->doubleWide()
@ -3396,12 +3400,12 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
break;
}
if(stackAtEnd && stack->ID == stackAtEnd->ID) //we should just move, it will be handled by following check
if(destinationStack && stack->ID == destinationStack->ID) //we should just move, it will be handled by following check
{
stackAtEnd = nullptr;
destinationStack = nullptr;
}
if(!stackAtEnd)
if(!destinationStack)
{
complain(boost::str(boost::format("walk and attack error: no stack at additionalInfo tile (%d)!\n") % ba.additionalInfo));
ok = false;
@ -3409,7 +3413,7 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
break;
}
if( !CStack::isMeleeAttackPossible(stack, stackAtEnd) )
if( !CStack::isMeleeAttackPossible(stack, destinationStack) )
{
complain("Attack cannot be performed!");
sendAndApply(&end_action);
@ -3426,10 +3430,10 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
{
if (stack &&
stack->alive() && //move can cause death, eg. by walking into the moat
stackAtEnd->alive())
destinationStack->alive())
{
BattleAttack bat;
prepareAttack(bat, stack, stackAtEnd, (i ? 0 : distance), ba.additionalInfo); //no distance travelled on second attack
prepareAttack(bat, stack, destinationStack, (i ? 0 : distance), ba.additionalInfo); //no distance travelled on second attack
//prepareAttack(bat, stack, stackAtEnd, 0, ba.additionalInfo);
handleAttackBeforeCasting(bat); //only before first attack
sendAndApply(&bat);
@ -3437,13 +3441,13 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
}
//counterattack
if (stackAtEnd
if (destinationStack
&& !stack->hasBonusOfType(Bonus::BLOCKS_RETALIATION)
&& stackAtEnd->ableToRetaliate()
&& destinationStack->ableToRetaliate()
&& stack->alive()) //attacker may have died (fire shield)
{
BattleAttack bat;
prepareAttack(bat, stackAtEnd, stack, 0, stack->position);
prepareAttack(bat, destinationStack, stack, 0, stack->position);
bat.flags |= BattleAttack::COUNTER;
sendAndApply(&bat);
handleAfterAttackCasting(bat);
@ -3462,7 +3466,6 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
}
case Battle::SHOOT:
{
const CStack *destStack= gs->curB->battleGetStackByPos(ba.destinationTile);
if( !gs->curB->battleCanShoot(stack, ba.destinationTile) )
{
complain("Cannot shoot!");
@ -3475,7 +3478,7 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
{
BattleAttack bat;
bat.flags |= BattleAttack::SHOT;
prepareAttack(bat, stack, destStack, 0, ba.destinationTile);
prepareAttack(bat, stack, destinationStack, 0, ba.destinationTile);
handleAttackBeforeCasting(bat);
sendAndApply(&bat);
handleAfterAttackCasting(bat);
@ -3485,14 +3488,14 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
const CGHeroInstance * attackingHero = gs->curB->battleGetFightingHero(ba.side);
if( destStack->alive()
if( destinationStack->alive()
&& (stack->getCreature()->idNumber == CreatureID::BALLISTA)
&& (attackingHero->getSecSkillLevel(SecondarySkill::ARTILLERY) >= SecSkillLevel::ADVANCED)
)
{
BattleAttack bat2;
bat2.flags |= BattleAttack::SHOT;
prepareAttack(bat2, stack, destStack, 0, ba.destinationTile);
prepareAttack(bat2, stack, destinationStack, 0, ba.destinationTile);
sendAndApply(&bat2);
}
//allow more than one additional attack
@ -3503,13 +3506,13 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
{
if(
stack->alive()
&& destStack->alive()
&& destinationStack->alive()
&& stack->shots
)
{
BattleAttack bat;
bat.flags |= BattleAttack::SHOT;
prepareAttack(bat, stack, destStack, 0, ba.destinationTile);
prepareAttack(bat, stack, destinationStack, 0, ba.destinationTile);
sendAndApply(&bat);
handleAfterAttackCasting(bat);
}
@ -4983,6 +4986,7 @@ void CGameHandler::objectVisited( const CGObjectInstance * obj, const CGHeroInst
HeroVisit hv;
hv.obj = obj;
hv.hero = h;
hv.player = h->tempOwner;
hv.starting = true;
sendAndApply(&hv);
@ -4996,6 +5000,7 @@ void CGameHandler::objectVisitEnded(const CObjectVisitQuery &query)
logGlobal->traceStream() << query.visitingHero->nodeName() << " visit ends.\n";
HeroVisit hv;
hv.player = query.players.front();
hv.obj = nullptr; //not necessary, moreover may have been deleted in the meantime
hv.hero = query.visitingHero;
assert(hv.hero);
@ -5059,6 +5064,7 @@ void CGameHandler::engageIntoBattle( PlayerColor player )
PlayerBlocked pb;
pb.player = player;
pb.reason = PlayerBlocked::UPCOMING_BATTLE;
pb.startOrEnd = PlayerBlocked::BLOCKADE_STARTED;
sendAndApply(&pb);
}