[LTR] Implement Radagast the Brown; also resolves #9419 (#10568)

* Fix #9419 bug with EntersBattlefieldThisOrAnotherTriggeredAbility
* Add test for Radagast as well as Risen Reef and Caldaia Guardian
* Minor associated cleanup for EntersBattlefieldAllTriggeredAbility
* New PermanentEnteringBattlefieldManaValue
This commit is contained in:
Bobby McCann 2023-07-10 03:04:45 +01:00 committed by GitHub
parent 39904d0ca3
commit 73104f6705
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 344 additions and 46 deletions

View file

@ -21,7 +21,6 @@ public class EntersBattlefieldAllTriggeredAbility extends TriggeredAbilityImpl {
protected String rule;
protected boolean controlledText;
protected SetTargetPointer setTargetPointer;
protected final boolean thisOrAnother;
/**
* zone = BATTLEFIELD optional = false
@ -54,16 +53,11 @@ public class EntersBattlefieldAllTriggeredAbility extends TriggeredAbilityImpl {
}
public EntersBattlefieldAllTriggeredAbility(Zone zone, Effect effect, FilterPermanent filter, boolean optional, SetTargetPointer setTargetPointer, String rule, boolean controlledText) {
this(zone, effect, filter, optional, setTargetPointer, rule, controlledText, false);
}
protected EntersBattlefieldAllTriggeredAbility(Zone zone, Effect effect, FilterPermanent filter, boolean optional, SetTargetPointer setTargetPointer, String rule, boolean controlledText, boolean thisOrAnother) {
super(zone, effect, optional);
this.filter = filter;
this.rule = rule;
this.controlledText = controlledText;
this.setTargetPointer = setTargetPointer;
this.thisOrAnother = thisOrAnother;
setTriggerPhrase(generateTriggerPhrase());
}
@ -73,7 +67,6 @@ public class EntersBattlefieldAllTriggeredAbility extends TriggeredAbilityImpl {
this.rule = ability.rule;
this.controlledText = ability.controlledText;
this.setTargetPointer = ability.setTargetPointer;
this.thisOrAnother = ability.thisOrAnother;
}
@Override
@ -93,12 +86,13 @@ public class EntersBattlefieldAllTriggeredAbility extends TriggeredAbilityImpl {
switch (setTargetPointer) {
case PLAYER:
this.getEffects().setTargetPointer(new FixedTarget(permanent.getControllerId()));
return true;
break;
case PERMANENT:
this.getEffects().setTargetPointer(new FixedTarget(permanent, game));
break;
default:
return true;
}
return true;
}
@Override
@ -111,9 +105,6 @@ public class EntersBattlefieldAllTriggeredAbility extends TriggeredAbilityImpl {
protected String generateTriggerPhrase() {
StringBuilder sb = new StringBuilder("Whenever ");
if (thisOrAnother) {
sb.append("{this} or another ");
}
sb.append(filter.getMessage());
if (filter.getMessage().startsWith("one or more")) {
sb.append(" enter the battlefield");

View file

@ -59,13 +59,7 @@ public class EntersBattlefieldCastTriggeredAbility extends EntersBattlefieldAllT
public EntersBattlefieldCastTriggeredAbility(Zone zone, Effect effect, FilterPermanent filter, boolean mustCast,
boolean optional,
SetTargetPointer setTargetPointer, String rule, boolean controlledText) {
this(zone, effect, filter, mustCast, optional, setTargetPointer, rule, controlledText, false);
}
protected EntersBattlefieldCastTriggeredAbility(Zone zone, Effect effect, FilterPermanent filter, boolean mustCast,
boolean optional,
SetTargetPointer setTargetPointer, String rule, boolean controlledText, boolean thisOrAnother) {
super(zone, effect, filter, optional, setTargetPointer, rule, controlledText, thisOrAnother);
super(zone, effect, filter, optional, setTargetPointer, rule, controlledText);
this.mustCast = mustCast;
this.addWatcher(new PermanentWasCastWatcher());

View file

@ -4,17 +4,13 @@ import mage.abilities.effects.Effect;
import mage.constants.SetTargetPointer;
import mage.constants.Zone;
import mage.filter.FilterPermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.filter.FilterPermanentThisOrAnother;
/**
* @author TheElk801
*/
public class EntersBattlefieldThisOrAnotherTriggeredAbility extends EntersBattlefieldAllTriggeredAbility {
private final boolean onlyControlled;
public EntersBattlefieldThisOrAnotherTriggeredAbility(Effect effect, FilterPermanent filter) {
this(effect, filter, false, false);
}
@ -28,35 +24,17 @@ public class EntersBattlefieldThisOrAnotherTriggeredAbility extends EntersBattle
}
public EntersBattlefieldThisOrAnotherTriggeredAbility(Zone zone, Effect effect, FilterPermanent filter, boolean optional, SetTargetPointer setTargetPointer, boolean onlyControlled) {
super(zone, effect, filter, optional, setTargetPointer, null, onlyControlled, true);
this.onlyControlled = onlyControlled;
super(zone, effect,
new FilterPermanentThisOrAnother(filter, onlyControlled),
optional, setTargetPointer, null, onlyControlled);
}
private EntersBattlefieldThisOrAnotherTriggeredAbility(final EntersBattlefieldThisOrAnotherTriggeredAbility ability) {
super(ability);
this.onlyControlled = ability.onlyControlled;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (!super.checkTrigger(event, game)) {
return false;
}
Permanent permanent = game.getPermanent(event.getTargetId());
if (permanent == null) {
return false;
}
if (permanent.getId().equals(getSourceId())) {
return true;
}
if (onlyControlled && !permanent.isControlledBy(this.getControllerId())) {
return false;
}
return filter.match(permanent, getControllerId(), this, game);
}
@Override
public EntersBattlefieldThisOrAnotherTriggeredAbility copy() {
return new EntersBattlefieldThisOrAnotherTriggeredAbility(this);
}
}
}

View file

@ -0,0 +1,59 @@
package mage.filter;
import mage.abilities.Ability;
import mage.game.Game;
import mage.game.permanent.Permanent;
import java.util.UUID;
public class FilterPermanentThisOrAnother extends FilterPermanent {
final FilterPermanent otherFilter;
final boolean onlyControlled;
public FilterPermanentThisOrAnother(FilterPermanent otherFilter, boolean onlyControlled) {
this(otherFilter, onlyControlled, generateFilterMessage(otherFilter));
}
public FilterPermanentThisOrAnother(FilterPermanent otherFilter, boolean onlyControlled, String name) {
super(name);
this.otherFilter = otherFilter;
this.onlyControlled = onlyControlled;
}
@Override
public boolean match(Permanent permanent, UUID playerId, Ability source, Game game) {
if (!super.match(permanent, playerId, source, game)) {
return false;
}
if (onlyControlled && !permanent.isControlledBy(source.getControllerId())) {
return false;
}
if (permanent.getId().equals(source.getSourceId())) {
return true;
} else {
return otherFilter.match(permanent, playerId, source, game);
}
}
private FilterPermanentThisOrAnother(FilterPermanentThisOrAnother filter) {
super(filter);
this.otherFilter = filter.otherFilter.copy();
this.onlyControlled = filter.onlyControlled;
}
@Override
public FilterPermanentThisOrAnother copy() {
return new FilterPermanentThisOrAnother(this);
}
protected static String generateFilterMessage(FilterPermanent otherFilter) {
// Remove the indefinite article from the beginning of the message:
String otherFilterMessage = otherFilter.getMessage();
if (otherFilterMessage.startsWith("a ")) {
otherFilterMessage = otherFilterMessage.substring(2);
} else if (otherFilterMessage.startsWith("an ")) {
otherFilterMessage = otherFilterMessage.substring(3);
}
return "{this} or another " + otherFilterMessage;
}
}