|  | @@ -863,7 +863,8 @@ void CGameHandler::applyBattleEffects(BattleAttack &bat, const CStack *att, cons
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  		StacksHealedOrResurrected::HealInfo hi;
 | 
	
		
			
				|  |  |  		hi.stackID = att->ID;
 | 
	
		
			
				|  |  | -		hi.healedHP = std::min<int>(bsa.damageAmount, att->MaxHealth() - att->firstHPleft + att->MaxHealth() * (att->baseAmount - att->count) );
 | 
	
		
			
				|  |  | +		hi.healedHP = std::min<int> (bsa.damageAmount * att->valOfBonuses (Bonus::LIFE_DRAIN) / 100,
 | 
	
		
			
				|  |  | +			att->MaxHealth() - att->firstHPleft + att->MaxHealth() * (att->baseAmount - att->count) );
 | 
	
		
			
				|  |  |  		hi.lowLevelResurrection = false;
 | 
	
		
			
				|  |  |  		shi.healedStacks.push_back(hi);
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -3457,38 +3458,32 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
 | 
	
		
			
				|  |  |  			}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  			//attack
 | 
	
		
			
				|  |  | -			if(stack->alive()) //move can cause death, eg. by walking into the moat
 | 
	
		
			
				|  |  | -			{
 | 
	
		
			
				|  |  | -				BattleAttack bat;
 | 
	
		
			
				|  |  | -				prepareAttack(bat, stack, stackAtEnd, distance, ba.additionalInfo);
 | 
	
		
			
				|  |  | -				handleAttackBeforeCasting(bat); //only before first attack
 | 
	
		
			
				|  |  | -				sendAndApply(&bat);
 | 
	
		
			
				|  |  | -				handleAfterAttackCasting(bat);
 | 
	
		
			
				|  |  | -			}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -			//counterattack
 | 
	
		
			
				|  |  | -			if(!stack->hasBonusOfType(Bonus::BLOCKS_RETALIATION)
 | 
	
		
			
				|  |  | -				&& stackAtEnd->ableToRetaliate()
 | 
	
		
			
				|  |  | -				&& stack->alive()) //attacker may have died (fire shield)
 | 
	
		
			
				|  |  | -			{
 | 
	
		
			
				|  |  | -				BattleAttack bat;
 | 
	
		
			
				|  |  | -				prepareAttack(bat, stackAtEnd, stack, 0, stack->position);
 | 
	
		
			
				|  |  | -				bat.flags |= BattleAttack::COUNTER;
 | 
	
		
			
				|  |  | -				sendAndApply(&bat);
 | 
	
		
			
				|  |  | -				handleAfterAttackCasting(bat);
 | 
	
		
			
				|  |  | -			}
 | 
	
		
			
				|  |  | +			int totalAttacks = 1 + stack->getBonuses(Selector::type (Bonus::ADDITIONAL_ATTACK),
 | 
	
		
			
				|  |  | +				(Selector::effectRange (Bonus::NO_LIMIT) || Selector::effectRange(Bonus::ONLY_MELEE_FIGHT)))->totalValue(); //all unspicified attacks + melee attacks
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -			//second attack
 | 
	
		
			
				|  |  | -			if(stack //FIXME: clones tend to disapear during actions
 | 
	
		
			
				|  |  | -				&& stack->valOfBonuses(Bonus::ADDITIONAL_ATTACK) > 0
 | 
	
		
			
				|  |  | -				&& !stack->hasBonusOfType(Bonus::SHOOTER)
 | 
	
		
			
				|  |  | -				&& stack->alive()
 | 
	
		
			
				|  |  | -				&& stackAtEnd->alive()  )
 | 
	
		
			
				|  |  | +			for (int i = 0; i < totalAttacks; ++i)
 | 
	
		
			
				|  |  |  			{
 | 
	
		
			
				|  |  | -				BattleAttack bat;
 | 
	
		
			
				|  |  | -				prepareAttack(bat, stack, stackAtEnd, 0, ba.additionalInfo);
 | 
	
		
			
				|  |  | -				sendAndApply(&bat);
 | 
	
		
			
				|  |  | -				handleAfterAttackCasting(bat);
 | 
	
		
			
				|  |  | +				if( stack &&stack->alive()) //move can cause death, eg. by walking into the moat
 | 
	
		
			
				|  |  | +				{
 | 
	
		
			
				|  |  | +					BattleAttack bat;
 | 
	
		
			
				|  |  | +					prepareAttack(bat, stack, stackAtEnd, distance, ba.additionalInfo);
 | 
	
		
			
				|  |  | +					handleAttackBeforeCasting(bat); //only before first attack
 | 
	
		
			
				|  |  | +					sendAndApply(&bat);
 | 
	
		
			
				|  |  | +					handleAfterAttackCasting(bat);
 | 
	
		
			
				|  |  | +				}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +				//counterattack
 | 
	
		
			
				|  |  | +				if(!stack->hasBonusOfType(Bonus::BLOCKS_RETALIATION)
 | 
	
		
			
				|  |  | +					&& stackAtEnd->ableToRetaliate()
 | 
	
		
			
				|  |  | +					&& stack->alive()) //attacker may have died (fire shield)
 | 
	
		
			
				|  |  | +				{
 | 
	
		
			
				|  |  | +					BattleAttack bat;
 | 
	
		
			
				|  |  | +					prepareAttack(bat, stackAtEnd, stack, 0, stack->position);
 | 
	
		
			
				|  |  | +					bat.flags |= BattleAttack::COUNTER;
 | 
	
		
			
				|  |  | +					sendAndApply(&bat);
 | 
	
		
			
				|  |  | +					handleAfterAttackCasting(bat);
 | 
	
		
			
				|  |  | +				}
 | 
	
		
			
				|  |  |  			}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  			//return
 | 
	
	
		
			
				|  | @@ -3529,18 +3524,24 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
 | 
	
		
			
				|  |  |  				prepareAttack(bat2, stack, destStack, 0, ba.destinationTile);
 | 
	
		
			
				|  |  |  				sendAndApply(&bat2);
 | 
	
		
			
				|  |  |  			}
 | 
	
		
			
				|  |  | -			//TODO: allow more than one additional attack
 | 
	
		
			
				|  |  | -			if(stack->valOfBonuses(Bonus::ADDITIONAL_ATTACK) > 0 //if unit shots twice let's make another shot
 | 
	
		
			
				|  |  | -				&& stack->alive()
 | 
	
		
			
				|  |  | -				&& destStack->alive()
 | 
	
		
			
				|  |  | -				&& stack->shots
 | 
	
		
			
				|  |  | -				)
 | 
	
		
			
				|  |  | +			//allow more than one additional attack
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +			int additionalAttacks = stack->getBonuses(Selector::type (Bonus::ADDITIONAL_ATTACK),
 | 
	
		
			
				|  |  | +				(Selector::effectRange (Bonus::NO_LIMIT) || Selector::effectRange(Bonus::ONLY_DISTANCE_FIGHT)))->totalValue();
 | 
	
		
			
				|  |  | +			for (int i = 0; i < additionalAttacks; ++i)
 | 
	
		
			
				|  |  |  			{
 | 
	
		
			
				|  |  | -				BattleAttack bat;
 | 
	
		
			
				|  |  | -				bat.flags |= BattleAttack::SHOT;
 | 
	
		
			
				|  |  | -				prepareAttack(bat, stack, destStack, 0, ba.destinationTile);
 | 
	
		
			
				|  |  | -				sendAndApply(&bat);
 | 
	
		
			
				|  |  | -				handleAfterAttackCasting(bat);
 | 
	
		
			
				|  |  | +				if(
 | 
	
		
			
				|  |  | +					stack->alive()
 | 
	
		
			
				|  |  | +					&& destStack->alive()
 | 
	
		
			
				|  |  | +					&& stack->shots
 | 
	
		
			
				|  |  | +					)
 | 
	
		
			
				|  |  | +				{
 | 
	
		
			
				|  |  | +					BattleAttack bat;
 | 
	
		
			
				|  |  | +					bat.flags |= BattleAttack::SHOT;
 | 
	
		
			
				|  |  | +					prepareAttack(bat, stack, destStack, 0, ba.destinationTile);
 | 
	
		
			
				|  |  | +					sendAndApply(&bat);
 | 
	
		
			
				|  |  | +					handleAfterAttackCasting(bat);
 | 
	
		
			
				|  |  | +				}
 | 
	
		
			
				|  |  |  			}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  			sendAndApply(&end_action);
 |