Add ConditionalTriggeredAbility for non-intervening0f

This commit is contained in:
Noah Gleason 2018-06-24 20:02:40 -04:00
parent 37e800a7dd
commit 8949987b78
No known key found for this signature in database
GPG key ID: EC030EC6B0650A40
462 changed files with 1120 additions and 1017 deletions

View file

@ -8,7 +8,7 @@ import mage.abilities.condition.Condition;
import mage.abilities.condition.InvertCondition;
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.constants.TargetController;
import mage.filter.FilterPermanent;
@ -19,7 +19,7 @@ import mage.filter.predicate.mageobject.ColorPredicate;
*
* @author TheElk801
*/
public class SanctuaryTriggeredAbility extends ConditionalTriggeredAbility {
public class SanctuaryInterveningIfTriggeredAbility extends ConditionalInterveningIfTriggeredAbility {
private static Condition makeOrCondition(ObjectColor color1, ObjectColor color2) {
FilterPermanent filter = new FilterPermanent();
@ -48,7 +48,7 @@ public class SanctuaryTriggeredAbility extends ConditionalTriggeredAbility {
return ability;
}
public SanctuaryTriggeredAbility(OneShotEffect effect1, OneShotEffect effect2, ObjectColor color1, ObjectColor color2, String text) {
public SanctuaryInterveningIfTriggeredAbility(OneShotEffect effect1, OneShotEffect effect2, ObjectColor color1, ObjectColor color2, String text) {
super(makeTrigger(effect1, effect2, color1, color2), makeOrCondition(color1, color2), text);
}
}

View file

@ -0,0 +1,104 @@
package mage.abilities.decorator;
import mage.abilities.Modes;
import mage.abilities.TriggeredAbility;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.condition.Condition;
import mage.abilities.effects.Effect;
import mage.abilities.effects.Effects;
import mage.constants.EffectType;
import mage.game.Game;
import mage.game.events.GameEvent;
/**
* Adds condition to {@link mage.abilities.effects.ContinuousEffect}. Acts as
* decorator.
*
* @author nantuko
*/
public class ConditionalInterveningIfTriggeredAbility extends TriggeredAbilityImpl {
protected TriggeredAbility ability;
protected Condition condition;
protected String abilityText;
/**
* Triggered ability with a condition. Set the optionality for the trigger
* ability itself.
*
* @param ability
* @param condition
* @param text explicit rule text for the ability, if null or empty, the
* rule text generated by the triggered ability itself is used.
*/
public ConditionalInterveningIfTriggeredAbility(TriggeredAbility ability, Condition condition, String text) {
super(ability.getZone(), null);
this.ability = ability;
this.modes = ability.getModes();
this.condition = condition;
this.abilityText = text;
}
public ConditionalInterveningIfTriggeredAbility(final ConditionalInterveningIfTriggeredAbility triggered) {
super(triggered);
this.ability = triggered.ability.copy();
this.condition = triggered.condition;
this.abilityText = triggered.abilityText;
}
@Override
public boolean checkInterveningIfClause(Game game) {
return condition.apply(game, this);
}
@Override
public ConditionalInterveningIfTriggeredAbility copy() {
return new ConditionalInterveningIfTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return ability.checkEventType(event, game);
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
ability.setSourceId(this.getSourceId());
ability.setControllerId(this.getControllerId());
return ability.checkTrigger(event, game);
}
@Override
public String getRule() {
if (abilityText == null || abilityText.isEmpty()) {
return ability.getRule();
}
return abilityText;
}
@Override
public Effects getEffects() {
return ability.getEffects();
}
@Override
public void addEffect(Effect effect) {
ability.addEffect(effect);
}
@Override
public Modes getModes() {
return ability.getModes();
}
@Override
public Effects getEffects(Game game, EffectType effectType) {
return ability.getEffects(game, effectType);
}
@Override
public boolean isOptional() {
return ability.isOptional();
}
}

View file

@ -14,7 +14,7 @@ import mage.game.events.GameEvent;
* Adds condition to {@link mage.abilities.effects.ContinuousEffect}. Acts as
* decorator.
*
* @author nantuko
* @author noahg
*/
public class ConditionalTriggeredAbility extends TriggeredAbilityImpl {
@ -46,13 +46,6 @@ public class ConditionalTriggeredAbility extends TriggeredAbilityImpl {
this.abilityText = triggered.abilityText;
}
@Override
public boolean checkInterveningIfClause(Game game) {
System.out.println("Source ID: "+this.getControllerId());
System.out.println("Active player ID: "+game.getActivePlayerId());
return condition.apply(game, this);
}
@Override
public ConditionalTriggeredAbility copy() {
return new ConditionalTriggeredAbility(this);
@ -67,7 +60,7 @@ public class ConditionalTriggeredAbility extends TriggeredAbilityImpl {
public boolean checkTrigger(GameEvent event, Game game) {
ability.setSourceId(this.getSourceId());
ability.setControllerId(this.getControllerId());
return ability.checkTrigger(event, game);
return ability.checkTrigger(event, game) && condition.apply(game, this);
}
@Override

View file

@ -16,7 +16,7 @@ import mage.abilities.costs.Cost;
import mage.abilities.costs.Costs;
import mage.abilities.costs.CostsImpl;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
import mage.abilities.effects.common.SacrificeSourceEffect;
import mage.cards.Card;
import mage.constants.Outcome;
@ -42,7 +42,7 @@ public class EvokeAbility extends StaticAbility implements AlternativeSourceCost
super(Zone.ALL, null);
name = EVOKE_KEYWORD;
this.addEvokeCost(manaString);
Ability ability = new ConditionalTriggeredAbility(new EntersBattlefieldTriggeredAbility(new SacrificeSourceEffect()), EvokedCondition.instance, "Sacrifice {this} when it enters the battlefield and was evoked.");
Ability ability = new ConditionalInterveningIfTriggeredAbility(new EntersBattlefieldTriggeredAbility(new SacrificeSourceEffect()), EvokedCondition.instance, "Sacrifice {this} when it enters the battlefield and was evoked.");
ability.setRuleVisible(false);
addSubAbility(ability);

View file

@ -11,7 +11,7 @@ import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.common.DiesTriggeredAbility;
import mage.abilities.condition.common.SourceHasCounterCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.AsThoughEffectImpl;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
@ -36,7 +36,7 @@ public class RepairAbility extends DiesTriggeredAbility {
public RepairAbility(int count) {
super(new AddCountersSourceEffect(CounterType.REPAIR.createInstance(), new StaticValue(count), false, true));
addSubAbility(new RepairBeginningOfUpkeepTriggeredAbility());
addSubAbility(new RepairBeginningOfUpkeepInterveningIfTriggeredAbility());
addSubAbility(new RepairCastFromGraveyardTriggeredAbility());
ruleText = "Repair " + count + " <i>(When this creature dies, put " + count
@ -127,9 +127,9 @@ class RepairCastFromGraveyardTriggeredAbility extends TriggeredAbilityImpl {
}
}
class RepairBeginningOfUpkeepTriggeredAbility extends ConditionalTriggeredAbility {
class RepairBeginningOfUpkeepInterveningIfTriggeredAbility extends ConditionalInterveningIfTriggeredAbility {
public RepairBeginningOfUpkeepTriggeredAbility() {
public RepairBeginningOfUpkeepInterveningIfTriggeredAbility() {
super(new BeginningOfUpkeepTriggeredAbility(Zone.GRAVEYARD, new RemoveCounterSourceEffect(CounterType.REPAIR.createInstance()), TargetController.YOU, false),
new SourceHasCounterCondition(CounterType.REPAIR),
"At the beginning of your upkeep, remove a repair counter from {this}");
@ -137,12 +137,12 @@ class RepairBeginningOfUpkeepTriggeredAbility extends ConditionalTriggeredAbilit
}
public RepairBeginningOfUpkeepTriggeredAbility(final RepairBeginningOfUpkeepTriggeredAbility effect) {
public RepairBeginningOfUpkeepInterveningIfTriggeredAbility(final RepairBeginningOfUpkeepInterveningIfTriggeredAbility effect) {
super(effect);
}
@Override
public RepairBeginningOfUpkeepTriggeredAbility copy() {
return new RepairBeginningOfUpkeepTriggeredAbility(this);
public RepairBeginningOfUpkeepInterveningIfTriggeredAbility copy() {
return new RepairBeginningOfUpkeepInterveningIfTriggeredAbility(this);
}
}

View file

@ -14,7 +14,7 @@ import mage.abilities.condition.common.SuspendedCondition;
import mage.abilities.costs.mana.ManaCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.costs.mana.VariableManaCost;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.OneShotEffect;
@ -154,7 +154,7 @@ public class SuspendAbility extends SpecialAction {
if (card.getManaCost().isEmpty()) {
setRuleAtTheTop(true);
}
addSubAbility(new SuspendBeginningOfUpkeepTriggeredAbility());
addSubAbility(new SuspendBeginningOfUpkeepInterveningIfTriggeredAbility());
addSubAbility(new SuspendPlayCardAbility());
}
ruleText = sb.toString();
@ -174,7 +174,7 @@ public class SuspendAbility extends SpecialAction {
ability.setControllerId(card.getOwnerId());
game.getState().addOtherAbility(card, ability);
SuspendBeginningOfUpkeepTriggeredAbility ability1 = new SuspendBeginningOfUpkeepTriggeredAbility();
SuspendBeginningOfUpkeepInterveningIfTriggeredAbility ability1 = new SuspendBeginningOfUpkeepInterveningIfTriggeredAbility();
ability1.setSourceId(card.getId());
ability1.setControllerId(card.getOwnerId());
game.getState().addOtherAbility(card, ability1);
@ -343,7 +343,7 @@ class SuspendPlayCardEffect extends OneShotEffect {
}
if (!abilitiesToRemove.isEmpty()) {
for (Ability ability : card.getAbilities()) {
if (ability instanceof SuspendBeginningOfUpkeepTriggeredAbility || ability instanceof SuspendPlayCardAbility) {
if (ability instanceof SuspendBeginningOfUpkeepInterveningIfTriggeredAbility || ability instanceof SuspendPlayCardAbility) {
abilitiesToRemove.add(ability);
}
}
@ -405,9 +405,9 @@ class GainHasteEffect extends ContinuousEffectImpl {
}
class SuspendBeginningOfUpkeepTriggeredAbility extends ConditionalTriggeredAbility {
class SuspendBeginningOfUpkeepInterveningIfTriggeredAbility extends ConditionalInterveningIfTriggeredAbility {
public SuspendBeginningOfUpkeepTriggeredAbility() {
public SuspendBeginningOfUpkeepInterveningIfTriggeredAbility() {
super(new BeginningOfUpkeepTriggeredAbility(Zone.EXILED, new RemoveCounterSourceEffect(CounterType.TIME.createInstance()), TargetController.YOU, false),
SuspendedCondition.instance,
"At the beginning of your upkeep, if this card ({this}) is suspended, remove a time counter from it.");
@ -415,12 +415,12 @@ class SuspendBeginningOfUpkeepTriggeredAbility extends ConditionalTriggeredAbili
}
public SuspendBeginningOfUpkeepTriggeredAbility(final SuspendBeginningOfUpkeepTriggeredAbility effect) {
public SuspendBeginningOfUpkeepInterveningIfTriggeredAbility(final SuspendBeginningOfUpkeepInterveningIfTriggeredAbility effect) {
super(effect);
}
@Override
public SuspendBeginningOfUpkeepTriggeredAbility copy() {
return new SuspendBeginningOfUpkeepTriggeredAbility(this);
public SuspendBeginningOfUpkeepInterveningIfTriggeredAbility copy() {
return new SuspendBeginningOfUpkeepInterveningIfTriggeredAbility(this);
}
}

View file

@ -9,18 +9,21 @@ import mage.game.Game;
import mage.game.events.GameEvent;
import mage.watchers.Watcher;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
/**
* A triggered ability that combines several others and triggers whenever one or more of them would. The abilities
* passed in should have null as their effect, and should have their own targets set if necessary. All other information
* will be passed in from changes to this Ability.
* will be passed in from changes to this Ability. Note: this does NOT work with abilities that have intervening if clauses.
* @author noahg
*/
public class OrTriggeredAbility extends TriggeredAbilityImpl {
private final String ruleTrigger;
private TriggeredAbility[] triggeredAbilities;
private List<Integer> triggeringAbilities;
public OrTriggeredAbility(Zone zone, Effect effect, TriggeredAbility... abilities) {
this(zone, effect, false, null, abilities);
@ -30,6 +33,7 @@ public class OrTriggeredAbility extends TriggeredAbilityImpl {
super(zone, effect, optional);
this.triggeredAbilities = abilities;
this.ruleTrigger = ruleTrigger;
this.triggeringAbilities = new ArrayList<>();
for (TriggeredAbility ability : triggeredAbilities) {
//Remove useless data
ability.getEffects().clear();
@ -42,6 +46,7 @@ public class OrTriggeredAbility extends TriggeredAbilityImpl {
for (int i = 0; i < this.triggeredAbilities.length; i++){
this.triggeredAbilities[i] = ability.triggeredAbilities[i].copy();
}
this.triggeringAbilities = new ArrayList<>(ability.triggeringAbilities);
this.ruleTrigger = ability.ruleTrigger;
}
@ -59,14 +64,17 @@ public class OrTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
for (TriggeredAbility ability : triggeredAbilities) {
if (ability.checkEventType(event, game) && ability.checkTrigger(event, game)){
System.out.println("Triggered from "+ability.getRule());
return true;
boolean toRet = false;
for (int i = 0; i < triggeredAbilities.length; i++) {
TriggeredAbility ability = triggeredAbilities[i];
if (ability.checkEventType(event, game) && ability.checkTrigger(event, game)) {
System.out.println("Triggered from " + ability.getRule());
triggeringAbilities.add(i);
toRet = true;
}
System.out.println("Checked "+ability.getRule());
System.out.println("Checked " + ability.getRule());
}
return false;
return toRet;
}
@Override
@ -125,24 +133,4 @@ public class OrTriggeredAbility extends TriggeredAbilityImpl {
ability.setSourceObject(sourceObject, game);
}
}
@Override
public boolean checkInterveningIfClause(Game game) {
for (TriggeredAbility ability : triggeredAbilities) {
if (!ability.checkInterveningIfClause(game)){
return false;
}
}
return true;
}
@Override
public boolean checkIfClause(Game game) {
for (TriggeredAbility ability : triggeredAbilities) {
if (!ability.checkIfClause(game)){
return false;
}
}
return true;
}
}