[STX] Implemented Hall of Oracles

This commit is contained in:
Evan Kranzler 2021-04-05 20:37:06 -04:00
parent d9adbd1627
commit cf2771e9fa
5 changed files with 108 additions and 32 deletions

View file

@ -0,0 +1,82 @@
package mage.cards.h;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.ActivatedAbility;
import mage.abilities.condition.Condition;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.decorator.ConditionalActivatedAbility;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.abilities.mana.AnyColorManaAbility;
import mage.abilities.mana.ColorlessManaAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.TimingRule;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.game.Game;
import mage.game.stack.Spell;
import mage.target.common.TargetCreaturePermanent;
import mage.watchers.common.SpellsCastWatcher;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class HallOfOracles extends CardImpl {
public HallOfOracles(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
// {T}: Add {C}.
this.addAbility(new ColorlessManaAbility());
// {1}, {T}: Add one mana of any color.
ActivatedAbility ability = new AnyColorManaAbility(new GenericManaCost(1));
ability.addCost(new TapSourceCost());
this.addAbility(ability);
// {T}: Put a +1/+1 counter on target creature. Activate only as a sorcery and only if you've cast an instant or sorcery spell this turn.
ability = new ConditionalActivatedAbility(
Zone.BATTLEFIELD, new AddCountersTargetEffect(CounterType.P1P1.createInstance()), new TapSourceCost(),
HallOfOraclesCondition.instance, "{T}: Put a +1/+1 counter on target creature. " +
"Activate only as a sorcery and only if you've cast an instant or sorcery spell this turn."
);
ability.addTarget(new TargetCreaturePermanent());
ability.setTiming(TimingRule.SORCERY);
this.addAbility(ability, new SpellsCastWatcher());
}
private HallOfOracles(final HallOfOracles card) {
super(card);
}
@Override
public HallOfOracles copy() {
return new HallOfOracles(this);
}
}
enum HallOfOraclesCondition implements Condition {
instance;
@Override
public boolean apply(Game game, Ability source) {
SpellsCastWatcher watcher = game.getState().getWatcher(SpellsCastWatcher.class);
if (watcher == null) {
return false;
}
List<Spell> spells = watcher.getSpellsCastThisTurn(source.getControllerId());
return spells != null && spells
.stream()
.filter(Objects::nonNull)
.filter(MageObject::isInstantOrSorcery)
.map(Spell::getSourceId)
.anyMatch(source.getSourceId()::equals);
}
}

View file

@ -1,26 +1,27 @@
package mage.cards.l; package mage.cards.l;
import java.util.List;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.Condition; import mage.abilities.condition.Condition;
import mage.abilities.decorator.ConditionalContinuousEffect; import mage.abilities.decorator.ConditionalContinuousEffect;
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.FlyingAbility;
import mage.constants.SubType;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Duration; import mage.constants.Duration;
import mage.constants.Zone; import mage.constants.SubType;
import mage.game.Game; import mage.game.Game;
import mage.game.stack.Spell; import mage.game.stack.Spell;
import mage.watchers.common.SpellsCastWatcher; import mage.watchers.common.SpellsCastWatcher;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
/** /**
*
* @author TheElk801 * @author TheElk801
*/ */
public final class Leapfrog extends CardImpl { public final class Leapfrog extends CardImpl {
@ -33,17 +34,12 @@ public final class Leapfrog extends CardImpl {
this.toughness = new MageInt(1); this.toughness = new MageInt(1);
// Leapfrog has flying as long as you've cast an instant or sorcery spell this turn. // Leapfrog has flying as long as you've cast an instant or sorcery spell this turn.
this.addAbility(new SimpleStaticAbility( this.addAbility(new SimpleStaticAbility(new ConditionalContinuousEffect(
Zone.BATTLEFIELD, new GainAbilitySourceEffect(
new ConditionalContinuousEffect( FlyingAbility.getInstance(), Duration.WhileOnBattlefield
new GainAbilitySourceEffect( ), LeapfrogCondition.instance, "{this} has flying as long as " +
FlyingAbility.getInstance(), "you've cast an instant or sorcery spell this turn."
Duration.WhileOnBattlefield )), new SpellsCastWatcher());
), LeapfrogCondition.instance,
"{this} has flying as long as you've cast "
+ "an instant or sorcery spell this turn."
)
), new SpellsCastWatcher());
} }
private Leapfrog(final Leapfrog card) { private Leapfrog(final Leapfrog card) {
@ -61,23 +57,16 @@ enum LeapfrogCondition implements Condition {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
SpellsCastWatcher watcher SpellsCastWatcher watcher = game.getState().getWatcher(SpellsCastWatcher.class);
= game.getState().getWatcher(
SpellsCastWatcher.class
);
if (watcher == null) { if (watcher == null) {
return false; return false;
} }
List<Spell> spells = watcher.getSpellsCastThisTurn(source.getControllerId()); List<Spell> spells = watcher.getSpellsCastThisTurn(source.getControllerId());
if (spells == null) { return spells != null && spells
return false; .stream()
} .filter(Objects::nonNull)
for (Spell spell : spells) { .filter(MageObject::isInstantOrSorcery)
if (!spell.getSourceId().equals(source.getSourceId()) .map(Spell::getSourceId)
&& spell.isInstantOrSorcery()) { .anyMatch(source.getSourceId()::equals);
return true;
}
}
return false;
} }
} }

View file

@ -108,6 +108,7 @@ public final class StrixhavenSchoolOfMages extends ExpansionSet {
cards.add(new SetCardInfo("Grinning Ignus", 104, Rarity.UNCOMMON, mage.cards.g.GrinningIgnus.class)); cards.add(new SetCardInfo("Grinning Ignus", 104, Rarity.UNCOMMON, mage.cards.g.GrinningIgnus.class));
cards.add(new SetCardInfo("Guiding Voice", 19, Rarity.COMMON, mage.cards.g.GuidingVoice.class)); cards.add(new SetCardInfo("Guiding Voice", 19, Rarity.COMMON, mage.cards.g.GuidingVoice.class));
cards.add(new SetCardInfo("Hall Monitor", 105, Rarity.UNCOMMON, mage.cards.h.HallMonitor.class)); cards.add(new SetCardInfo("Hall Monitor", 105, Rarity.UNCOMMON, mage.cards.h.HallMonitor.class));
cards.add(new SetCardInfo("Hall of Oracles", 267, Rarity.RARE, mage.cards.h.HallOfOracles.class));
cards.add(new SetCardInfo("Heated Debate", 106, Rarity.COMMON, mage.cards.h.HeatedDebate.class)); cards.add(new SetCardInfo("Heated Debate", 106, Rarity.COMMON, mage.cards.h.HeatedDebate.class));
cards.add(new SetCardInfo("Honor Troll", 134, Rarity.UNCOMMON, mage.cards.h.HonorTroll.class)); cards.add(new SetCardInfo("Honor Troll", 134, Rarity.UNCOMMON, mage.cards.h.HonorTroll.class));
cards.add(new SetCardInfo("Humiliate", 193, Rarity.UNCOMMON, mage.cards.h.Humiliate.class)); cards.add(new SetCardInfo("Humiliate", 193, Rarity.UNCOMMON, mage.cards.h.Humiliate.class));

View file

@ -1,11 +1,12 @@
package mage.abilities; package mage.abilities;
import mage.ApprovingObject;
import mage.abilities.mana.ManaOptions; import mage.abilities.mana.ManaOptions;
import mage.constants.TargetController; import mage.constants.TargetController;
import mage.constants.TimingRule;
import mage.game.Game; import mage.game.Game;
import java.util.UUID; import java.util.UUID;
import mage.ApprovingObject;
/** /**
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
@ -68,4 +69,6 @@ public interface ActivatedAbility extends Ability {
void setMaxActivationsPerTurn(int maxActivationsPerTurn); void setMaxActivationsPerTurn(int maxActivationsPerTurn);
int getMaxActivationsPerTurn(Game game); int getMaxActivationsPerTurn(Game game);
public void setTiming(TimingRule timing);
} }

View file

@ -1,5 +1,6 @@
package mage.abilities; package mage.abilities;
import mage.ApprovingObject;
import mage.MageObject; import mage.MageObject;
import mage.abilities.condition.Condition; import mage.abilities.condition.Condition;
import mage.abilities.costs.Cost; import mage.abilities.costs.Cost;
@ -19,7 +20,6 @@ import mage.game.permanent.Permanent;
import mage.util.CardUtil; import mage.util.CardUtil;
import java.util.UUID; import java.util.UUID;
import mage.ApprovingObject;
/** /**
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
@ -237,6 +237,7 @@ public abstract class ActivatedAbilityImpl extends AbilityImpl implements Activa
return timing; return timing;
} }
@Override
public void setTiming(TimingRule timing) { public void setTiming(TimingRule timing) {
this.timing = timing; this.timing = timing;
} }