forked from External/mage
refactor one-use prevention effect for a chosen source
fixes a few bugs along the way: [[Pilgrim and Justice]] & [[Pilgrim of Virue]] were incorrectly adding a "to you" to their damage clause. [[Ajani's Aid]] was improperly a one-use prevention effect. [[Story Circle]] and [[Prismatic Circle]] have not been refactor as it is not currently possible to have a proper filter for them. Would require a FilterSource with a 4-argument match most likely.
This commit is contained in:
parent
7d62aa9ec5
commit
a6ca052106
49 changed files with 1481 additions and 821 deletions
|
|
@ -16,33 +16,38 @@ import mage.target.TargetSource;
|
|||
* @author LevelX2
|
||||
*/
|
||||
|
||||
public class PreventDamageBySourceEffect extends PreventionEffectImpl {
|
||||
public class PreventDamageByChosenSourceEffect extends PreventionEffectImpl {
|
||||
|
||||
private TargetSource target;
|
||||
private MageObjectReference mageObjectReference;
|
||||
|
||||
public PreventDamageBySourceEffect() {
|
||||
this(new FilterObject("a"));
|
||||
public PreventDamageByChosenSourceEffect() {
|
||||
this(new FilterObject("a source"));
|
||||
}
|
||||
|
||||
public PreventDamageBySourceEffect(FilterObject filterObject) {
|
||||
super(Duration.EndOfTurn);
|
||||
public PreventDamageByChosenSourceEffect(FilterObject filterObject) {
|
||||
this(filterObject, false);
|
||||
}
|
||||
|
||||
public PreventDamageByChosenSourceEffect(FilterObject filterObject, boolean onlyCombat) {
|
||||
super(Duration.EndOfTurn, Integer.MAX_VALUE, onlyCombat);
|
||||
if (!filterObject.getMessage().endsWith("source")) {
|
||||
filterObject.setMessage(filterObject.getMessage() + " source");
|
||||
}
|
||||
this.target = new TargetSource(filterObject);
|
||||
staticText = "Prevent all damage " + filterObject.getMessage() + " of your choice would deal this turn";
|
||||
staticText = "Prevent all" + (onlyCombat ? " combat" : "")
|
||||
+ " damage " + filterObject.getMessage() + " of your choice would deal this turn";
|
||||
}
|
||||
|
||||
protected PreventDamageBySourceEffect(final PreventDamageBySourceEffect effect) {
|
||||
protected PreventDamageByChosenSourceEffect(final PreventDamageByChosenSourceEffect effect) {
|
||||
super(effect);
|
||||
this.target = effect.target.copy();
|
||||
this.mageObjectReference = effect.mageObjectReference;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PreventDamageBySourceEffect copy() {
|
||||
return new PreventDamageBySourceEffect(this);
|
||||
public PreventDamageByChosenSourceEffect copy() {
|
||||
return new PreventDamageByChosenSourceEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -0,0 +1,131 @@
|
|||
package mage.abilities.effects.common;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.PreventionEffectData;
|
||||
import mage.abilities.effects.PreventionEffectImpl;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.filter.FilterObject;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.players.Player;
|
||||
import mage.target.TargetSource;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author Quercitron, Susucr
|
||||
*/
|
||||
public class PreventNextDamageFromChosenSourceEffect extends PreventionEffectImpl {
|
||||
|
||||
protected final TargetSource targetSource;
|
||||
private final boolean toYou;
|
||||
private final ApplierOnPrevention onPrevention;
|
||||
|
||||
public interface ApplierOnPrevention {
|
||||
boolean apply(PreventionEffectData data, TargetSource targetsource, GameEvent event, Ability source, Game game);
|
||||
|
||||
String getText();
|
||||
}
|
||||
|
||||
public static ApplierOnPrevention ON_PREVENT_YOU_GAIN_THAT_MUCH_LIFE = new ApplierOnPrevention() {
|
||||
public String getText() {
|
||||
return "You gain life equal to the damage prevented this way";
|
||||
}
|
||||
|
||||
public boolean apply(PreventionEffectData data, TargetSource targetSource, GameEvent event, Ability source, Game game) {
|
||||
if (data == null || data.getPreventedDamage() <= 0) {
|
||||
return false;
|
||||
}
|
||||
int prevented = data.getPreventedDamage();
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller == null) {
|
||||
return false;
|
||||
}
|
||||
controller.gainLife(prevented, game, source);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
public PreventNextDamageFromChosenSourceEffect(Duration duration, boolean toYou) {
|
||||
this(duration, toYou, new FilterObject("source"));
|
||||
}
|
||||
|
||||
public PreventNextDamageFromChosenSourceEffect(Duration duration, boolean toYou, FilterObject filter) {
|
||||
this(duration, toYou, filter, false, null);
|
||||
}
|
||||
|
||||
public PreventNextDamageFromChosenSourceEffect(Duration duration, boolean toYou, ApplierOnPrevention onPrevention) {
|
||||
this(duration, toYou, new FilterObject("source"), onPrevention);
|
||||
}
|
||||
|
||||
public PreventNextDamageFromChosenSourceEffect(Duration duration, boolean toYou, FilterObject filter, ApplierOnPrevention onPrevention) {
|
||||
this(duration, toYou, filter, false, onPrevention);
|
||||
}
|
||||
|
||||
public PreventNextDamageFromChosenSourceEffect(Duration duration, boolean toYou, FilterObject filter, boolean onlyCombat, ApplierOnPrevention onPrevention) {
|
||||
super(duration, Integer.MAX_VALUE, onlyCombat);
|
||||
this.targetSource = new TargetSource(filter);
|
||||
this.toYou = toYou;
|
||||
this.onPrevention = onPrevention;
|
||||
this.staticText = setText();
|
||||
}
|
||||
|
||||
protected PreventNextDamageFromChosenSourceEffect(final PreventNextDamageFromChosenSourceEffect effect) {
|
||||
super(effect);
|
||||
this.targetSource = effect.targetSource.copy();
|
||||
this.toYou = effect.toYou;
|
||||
this.onPrevention = effect.onPrevention;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PreventNextDamageFromChosenSourceEffect copy() {
|
||||
return new PreventNextDamageFromChosenSourceEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Ability source, Game game) {
|
||||
super.init(source, game);
|
||||
UUID controllerId = source.getControllerId();
|
||||
if (this.targetSource.canChoose(controllerId, source, game)) {
|
||||
this.targetSource.choose(Outcome.PreventDamage, controllerId, source.getSourceId(), source, game);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
|
||||
PreventionEffectData data = preventDamageAction(event, source, game);
|
||||
this.used = true;
|
||||
if (onPrevention != null) {
|
||||
onPrevention.apply(data, targetSource, event, source, game);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applies(GameEvent event, Ability source, Game game) {
|
||||
return !this.used
|
||||
&& super.applies(event, source, game)
|
||||
&& (!toYou || event.getTargetId().equals(source.getControllerId()))
|
||||
&& event.getSourceId().equals(targetSource.getFirstTarget());
|
||||
}
|
||||
|
||||
private String setText() {
|
||||
StringBuilder sb = new StringBuilder("The next time ")
|
||||
.append(CardUtil.addArticle(targetSource.getFilter().getMessage()));
|
||||
sb.append(" of your choice would deal damage");
|
||||
if (toYou) {
|
||||
sb.append(" to you");
|
||||
}
|
||||
if (duration == Duration.EndOfTurn) {
|
||||
sb.append(" this turn");
|
||||
}
|
||||
sb.append(", prevent that damage");
|
||||
if (onPrevention != null) {
|
||||
sb.append(". ").append(onPrevention.getText());
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,77 +0,0 @@
|
|||
package mage.abilities.effects.common;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.PreventionEffectImpl;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.filter.FilterObject;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.target.TargetSource;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
/**
|
||||
* @author Quercitron
|
||||
*/
|
||||
public class PreventNextDamageFromChosenSourceToYouEffect extends PreventionEffectImpl {
|
||||
|
||||
protected final TargetSource targetSource;
|
||||
|
||||
public PreventNextDamageFromChosenSourceToYouEffect(Duration duration) {
|
||||
this(duration, new FilterObject("source"));
|
||||
}
|
||||
|
||||
public PreventNextDamageFromChosenSourceToYouEffect(Duration duration, FilterObject filter) {
|
||||
this(duration, filter, false);
|
||||
}
|
||||
|
||||
public PreventNextDamageFromChosenSourceToYouEffect(Duration duration, FilterObject filter, boolean onlyCombat) {
|
||||
super(duration, Integer.MAX_VALUE, onlyCombat);
|
||||
this.targetSource = new TargetSource(filter);
|
||||
this.staticText = setText();
|
||||
}
|
||||
|
||||
protected PreventNextDamageFromChosenSourceToYouEffect(final PreventNextDamageFromChosenSourceToYouEffect effect) {
|
||||
super(effect);
|
||||
this.targetSource = effect.targetSource.copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PreventNextDamageFromChosenSourceToYouEffect copy() {
|
||||
return new PreventNextDamageFromChosenSourceToYouEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Ability source, Game game) {
|
||||
super.init(source, game);
|
||||
this.targetSource.choose(Outcome.PreventDamage, source.getControllerId(), source.getSourceId(), source, game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
|
||||
preventDamageAction(event, source, game);
|
||||
this.used = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applies(GameEvent event, Ability source, Game game) {
|
||||
if (!this.used && super.applies(event, source, game)) {
|
||||
if (event.getTargetId().equals(source.getControllerId()) && event.getSourceId().equals(targetSource.getFirstTarget())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private String setText() {
|
||||
StringBuilder sb = new StringBuilder("The next time ").append(CardUtil.addArticle(targetSource.getFilter().getMessage()));
|
||||
sb.append(" of your choice would deal damage to you");
|
||||
if (duration == Duration.EndOfTurn) {
|
||||
sb.append(" this turn");
|
||||
}
|
||||
sb.append(", prevent that damage");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue