136 lines
5.6 KiB
Java
136 lines
5.6 KiB
Java
package magic.model.action;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.Collection;
|
|
|
|
import magic.model.MagicAbility;
|
|
import magic.model.MagicDamage;
|
|
import magic.model.MagicGame;
|
|
import magic.model.MagicPermanent;
|
|
import magic.model.MagicPermanentList;
|
|
import magic.model.MagicPermanentState;
|
|
import magic.model.MagicPlayer;
|
|
|
|
/**
|
|
* Simplification of the rules:
|
|
* - the first blocker gets all remaining damage when the attacker does not have trample.
|
|
* - when the attacker has deathtouch, lethal damage for each blocker is 1.
|
|
*/
|
|
public class CombatDamageAction extends MagicAction {
|
|
|
|
private final MagicPlayer attackingPlayer;
|
|
private final MagicPlayer defendingPlayer;
|
|
private final boolean first;
|
|
private boolean dealtDamage = false;
|
|
|
|
public CombatDamageAction(final MagicPlayer attackingPlayer, final MagicPlayer defendingPlayer, final boolean first) {
|
|
this.attackingPlayer=attackingPlayer;
|
|
this.defendingPlayer=defendingPlayer;
|
|
this.first = first;
|
|
}
|
|
|
|
private boolean dealsCombatDamage(final MagicPermanent creature) {
|
|
return first ?
|
|
creature.hasAbility(MagicAbility.FirstStrike) ||
|
|
creature.hasAbility(MagicAbility.DoubleStrike)
|
|
:
|
|
!creature.hasState(MagicPermanentState.DealtFirstStrike) ||
|
|
creature.hasAbility(MagicAbility.DoubleStrike);
|
|
}
|
|
|
|
private void combatDamage(final MagicGame game, final MagicPlayer aAttackingPlayer, final MagicPlayer aDefendingPlayer) {
|
|
|
|
final Collection<MagicDamage> combatDamage= new ArrayList<>();
|
|
|
|
// Determine all combat damage that must be dealt.
|
|
for (final MagicPermanent attacker : aAttackingPlayer.getPermanents()) {
|
|
|
|
if (attacker.isAttacking()) {
|
|
// Let blockers deal damage first.
|
|
for (final MagicPermanent blocker : attacker.getBlockingCreatures()) {
|
|
|
|
// Checks if blocker deals first strike or regular combat damage.
|
|
if (dealsCombatDamage(blocker)) {
|
|
final int power=blocker.getPower();
|
|
// Checks if blocker has power > 0.
|
|
if (power>0) {
|
|
combatDamage.add(MagicDamage.Combat(blocker,attacker,power));
|
|
}
|
|
if (first) {
|
|
game.doAction(ChangeStateAction.Set(blocker, MagicPermanentState.DealtFirstStrike));
|
|
}
|
|
}
|
|
}
|
|
|
|
// Check if attacker deals first strike or regular combat damage.
|
|
if (dealsCombatDamage(attacker)) {
|
|
// Checks if attacker has power > 0.
|
|
int power=attacker.getPower();
|
|
if (power>0 && !attacker.hasState(MagicPermanentState.NoCombatDamage)) {
|
|
if (attacker.hasState(MagicPermanentState.Blocked)) {
|
|
// Determine what damage must be dealt to each blocker.
|
|
final boolean deathtouch = attacker.hasAbility(MagicAbility.Deathtouch);
|
|
final MagicPermanentList blockers=attacker.getBlockingCreatures();
|
|
final int[] attackerDamage=new int[blockers.size()];
|
|
for (int index=0;power>0&&index<attackerDamage.length;index++) {
|
|
|
|
final MagicPermanent blocker=blockers.get(index);
|
|
final int toughness=blocker.getToughness();
|
|
attackerDamage[index]=Math.min(deathtouch?1:power,blocker.getLethalDamage(toughness));
|
|
power-=attackerDamage[index];
|
|
}
|
|
|
|
// Check what to do with the remaining damage from attacker.
|
|
if (power>0) {
|
|
if (attacker.hasAbility(MagicAbility.Trample)) {
|
|
combatDamage.add(MagicDamage.Combat(attacker,aDefendingPlayer,power));
|
|
} else if (attackerDamage.length>0) {
|
|
attackerDamage[0]+=power;
|
|
}
|
|
}
|
|
|
|
// Deal damage from attacker to blockers.
|
|
for (int index=0;index<attackerDamage.length;index++) {
|
|
|
|
final int amount=attackerDamage[index];
|
|
if (amount>0) {
|
|
combatDamage.add(MagicDamage.Combat(attacker,blockers.get(index),amount));
|
|
}
|
|
}
|
|
} else {
|
|
// Deal all damage to defending player.
|
|
combatDamage.add(MagicDamage.Combat(attacker,aDefendingPlayer,power));
|
|
}
|
|
}
|
|
if (first) {
|
|
game.doAction(ChangeStateAction.Set(attacker, MagicPermanentState.DealtFirstStrike));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Deal combat damage.
|
|
if (!combatDamage.isEmpty()) {
|
|
for (final MagicDamage damage: combatDamage) {
|
|
game.doAction(new DealDamageAction(damage));
|
|
}
|
|
dealtDamage = true;
|
|
game.setStateCheckRequired();
|
|
}
|
|
}
|
|
|
|
public boolean dealtDamage() {
|
|
return dealtDamage;
|
|
}
|
|
|
|
@Override
|
|
public void doAction(final MagicGame game) {
|
|
combatDamage(game,attackingPlayer,defendingPlayer);
|
|
}
|
|
|
|
@Override
|
|
public void undoAction(final MagicGame game) {
|
|
|
|
}
|
|
}
|