2013-04-12 19:32:25 -07:00
|
|
|
package magic.model.action;
|
|
|
|
|
|
|
|
import magic.model.MagicAbility;
|
|
|
|
import magic.model.MagicCounterType;
|
|
|
|
import magic.model.MagicDamage;
|
|
|
|
import magic.model.MagicGame;
|
|
|
|
import magic.model.MagicPermanent;
|
|
|
|
import magic.model.MagicPermanentState;
|
|
|
|
import magic.model.MagicPlayer;
|
|
|
|
import magic.model.MagicPlayerState;
|
|
|
|
import magic.model.MagicSource;
|
|
|
|
import magic.model.MagicType;
|
2014-04-18 06:58:52 -07:00
|
|
|
import magic.model.event.MagicRedirectDamageEvent;
|
2013-04-12 19:32:25 -07:00
|
|
|
import magic.model.target.MagicTarget;
|
|
|
|
import magic.model.trigger.MagicTriggerType;
|
|
|
|
|
2015-04-14 02:14:43 -07:00
|
|
|
public class DealDamageAction extends MagicAction {
|
2013-06-23 18:33:35 -07:00
|
|
|
|
2013-04-12 19:32:25 -07:00
|
|
|
private static final int UNINIT = Integer.MIN_VALUE;
|
|
|
|
|
|
|
|
private final MagicDamage damage;
|
|
|
|
private MagicTarget target;
|
|
|
|
private int oldDamage = UNINIT;
|
2015-12-31 02:54:52 -08:00
|
|
|
|
2015-04-14 02:14:43 -07:00
|
|
|
public DealDamageAction(final MagicSource source, MagicTarget target, final int amt) {
|
2014-08-30 18:58:30 -07:00
|
|
|
this(new MagicDamage(source, target, amt), null);
|
|
|
|
}
|
2013-06-23 18:33:35 -07:00
|
|
|
|
2015-04-14 02:14:43 -07:00
|
|
|
public DealDamageAction(final MagicDamage damage) {
|
2013-04-12 19:32:25 -07:00
|
|
|
this(damage, null);
|
|
|
|
}
|
|
|
|
|
2015-04-14 02:14:43 -07:00
|
|
|
public static final DealDamageAction NoRedirect(final MagicDamage damage) {
|
|
|
|
return new DealDamageAction(damage, damage.getTarget());
|
2013-04-12 19:32:25 -07:00
|
|
|
}
|
2013-06-23 18:33:35 -07:00
|
|
|
|
2015-04-14 02:14:43 -07:00
|
|
|
private DealDamageAction(final MagicDamage aDamage, final MagicTarget aTarget) {
|
2013-04-12 19:32:25 -07:00
|
|
|
damage = aDamage;
|
|
|
|
target = aTarget;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void doAction(final MagicGame game) {
|
2013-09-13 18:11:01 -07:00
|
|
|
game.executeTrigger(MagicTriggerType.IfDamageWouldBeDealt,damage);
|
2015-12-31 02:54:52 -08:00
|
|
|
|
2013-04-12 19:32:25 -07:00
|
|
|
/*
|
|
|
|
306.7. If damage would be dealt to a player by a source
|
|
|
|
controlled by an opponent, that opponent may have that source deal that
|
|
|
|
damage to a planeswalker the first player controls instead.
|
|
|
|
*/
|
2013-07-13 18:42:29 -07:00
|
|
|
|
|
|
|
// in immediate mode, always deal damage to player
|
2018-04-07 17:59:14 -07:00
|
|
|
if (!game.isImmediate() &&
|
2013-07-13 18:38:42 -07:00
|
|
|
target == null &&
|
2013-06-23 18:33:35 -07:00
|
|
|
damage.getTarget().isPlayer() &&
|
2013-04-12 19:32:25 -07:00
|
|
|
damage.getSource().getController() != damage.getTarget() &&
|
2013-06-04 00:53:38 -07:00
|
|
|
damage.getTarget().getController().controlsPermanent(MagicType.Planeswalker)) {
|
2013-04-12 19:32:25 -07:00
|
|
|
game.addEvent(new MagicRedirectDamageEvent(damage));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
target = damage.getTarget();
|
|
|
|
|
|
|
|
/*
|
|
|
|
119.1. Objects can deal damage to creatures, planeswalkers, and players.
|
|
|
|
*/
|
2016-02-17 18:03:15 -08:00
|
|
|
if (!target.isCreaturePermanent() &&
|
|
|
|
!target.isPlaneswalkerPermanent() &&
|
2013-04-12 19:32:25 -07:00
|
|
|
!target.isPlayer()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
damage.setDealtAmount(0);
|
2015-05-01 18:41:49 -07:00
|
|
|
final int dealtAmount=damage.getAmount();
|
|
|
|
if (dealtAmount <= 0) {
|
2013-04-12 19:32:25 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
final MagicSource source=damage.getSource();
|
|
|
|
|
2016-02-17 18:03:15 -08:00
|
|
|
if (target.isPlaneswalkerPermanent()) {
|
2013-04-12 19:32:25 -07:00
|
|
|
final MagicPermanent targetPermanent=(MagicPermanent)target;
|
2018-04-09 21:08:37 -07:00
|
|
|
game.doAction(new ChangeCountersAction(damage.getSource().getController(),targetPermanent,MagicCounterType.Loyalty,-dealtAmount));
|
2013-06-23 18:33:35 -07:00
|
|
|
}
|
|
|
|
|
2016-02-17 18:03:15 -08:00
|
|
|
if (target.isCreaturePermanent()) {
|
2013-04-12 19:32:25 -07:00
|
|
|
final MagicPermanent targetPermanent=(MagicPermanent)target;
|
|
|
|
if (damage.hasNoRegeneration()) {
|
2015-04-13 02:22:38 -07:00
|
|
|
game.doAction(ChangeStateAction.Set(targetPermanent,MagicPermanentState.CannotBeRegenerated));
|
2013-04-12 19:32:25 -07:00
|
|
|
}
|
|
|
|
if (source.hasAbility(MagicAbility.Wither)||source.hasAbility(MagicAbility.Infect)) {
|
2018-04-09 21:08:37 -07:00
|
|
|
game.doAction(new ChangeCountersAction(damage.getSource().getController(),targetPermanent,MagicCounterType.MinusOne,dealtAmount));
|
2013-04-12 19:32:25 -07:00
|
|
|
} else {
|
|
|
|
oldDamage=targetPermanent.getDamage();
|
|
|
|
targetPermanent.setDamage(oldDamage+dealtAmount);
|
|
|
|
}
|
|
|
|
if (source.hasAbility(MagicAbility.Deathtouch)) {
|
2015-04-13 02:22:38 -07:00
|
|
|
game.doAction(ChangeStateAction.Set(targetPermanent,MagicPermanentState.Destroyed));
|
2013-04-12 19:32:25 -07:00
|
|
|
}
|
2015-04-13 02:22:38 -07:00
|
|
|
game.doAction(ChangeStateAction.Set(targetPermanent,MagicPermanentState.WasDealtDamage));
|
2013-06-23 18:33:35 -07:00
|
|
|
}
|
|
|
|
|
2013-04-12 19:32:25 -07:00
|
|
|
if (target.isPlayer()) {
|
|
|
|
final MagicPlayer targetPlayer = (MagicPlayer)target;
|
|
|
|
if (source.hasAbility(MagicAbility.Infect)) {
|
2018-04-09 21:08:37 -07:00
|
|
|
game.doAction(new ChangeCountersAction(damage.getSource().getController(),targetPlayer, MagicCounterType.Poison, dealtAmount));
|
2013-04-12 19:32:25 -07:00
|
|
|
} else {
|
2015-11-22 17:37:11 -08:00
|
|
|
game.doAction(new ChangeLifeAction(targetPlayer,-dealtAmount,true));
|
2013-04-12 19:32:25 -07:00
|
|
|
}
|
2015-04-13 01:02:54 -07:00
|
|
|
game.doAction(new ChangePlayerStateAction(targetPlayer,MagicPlayerState.WasDealtDamage));
|
2013-04-12 19:32:25 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
damage.setDealtAmount(dealtAmount);
|
2013-05-21 05:26:01 -07:00
|
|
|
if (source.hasAbility(MagicAbility.Lifelink)) {
|
2015-04-13 00:58:48 -07:00
|
|
|
game.doAction(new ChangeLifeAction(source.getController(),dealtAmount));
|
2013-04-12 19:32:25 -07:00
|
|
|
}
|
|
|
|
game.executeTrigger(MagicTriggerType.WhenDamageIsDealt,damage);
|
2013-06-23 18:33:35 -07:00
|
|
|
|
2013-04-12 19:32:25 -07:00
|
|
|
game.setStateCheckRequired();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void undoAction(final MagicGame game) {
|
|
|
|
if (oldDamage!=UNINIT) {
|
|
|
|
final MagicPermanent targetPermanent=(MagicPermanent)target;
|
|
|
|
targetPermanent.setDamage(oldDamage);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|