[DOM] Implement Legendary Sorceries

Add: Target Any Target for damage spells
Add: Drudge Sentinel
Fix: Genesis Wave Filter
This commit is contained in:
Justin Herlehy 2018-04-08 18:37:11 -07:00
parent ecbe7e68a6
commit 702756b4e7
13 changed files with 935 additions and 12 deletions

View file

@ -0,0 +1,26 @@
package mage.abilities.common;
import mage.abilities.condition.common.LegendaryCondition;
import mage.constants.Zone;
/**
* @author JRHerlehy
* Created on 4/8/18.
*/
public class LegendarySpellAbility extends SimpleStaticAbility {
public LegendarySpellAbility() {
super(Zone.ALL, new CastOnlyIfConditionIsTrueEffect(LegendaryCondition.instance));
this.setRuleAtTheTop(true);
this.getEffects().get(0).setText("<i>(You may cast a legendary sorcery only if you control a legendary creature or planeswalker.)</i>");
}
private LegendarySpellAbility(final LegendarySpellAbility ability) {
super(ability);
}
@Override
public LegendarySpellAbility copy() {
return new LegendarySpellAbility(this);
}
}

View file

@ -0,0 +1,46 @@
package mage.abilities.condition.common;
import mage.abilities.Ability;
import mage.abilities.condition.Condition;
import mage.constants.CardType;
import mage.constants.SuperType;
import mage.filter.FilterPermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.filter.predicate.mageobject.SupertypePredicate;
import mage.game.Game;
/**
* @author JRHerlehy
* Created on 4/7/18.
*/
public enum LegendaryCondition implements Condition {
instance;
private static final FilterPermanent filter = new FilterPermanent("legendary creature or planeswalker");
static {
filter.add(
Predicates.and(
new SupertypePredicate(SuperType.LEGENDARY),
Predicates.or(
new CardTypePredicate(CardType.CREATURE),
new CardTypePredicate(CardType.PLANESWALKER)
)
)
);
}
@Override
public boolean apply(Game game, Ability source) {
return game.getBattlefield().contains(filter, source.getControllerId(), 1, game);
}
@Override
public String toString() {
return super.toString();
}
}

View file

@ -0,0 +1,87 @@
package mage.filter.common;
import java.util.UUID;
import mage.MageItem;
import mage.filter.FilterImpl;
import mage.filter.FilterInPlay;
import mage.filter.FilterPlayer;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
/**
* @author JRHerlehy
* Created on 4/8/18.
*/
public class FilterCreaturePlayerOrPlaneswalker extends FilterImpl<MageItem> implements FilterInPlay<MageItem> {
protected FilterCreaturePermanent creatureFilter;
protected FilterPlaneswalkerPermanent planeswalkerFilter;
protected final FilterPlayer playerFilter;
public FilterCreaturePlayerOrPlaneswalker() {
this("any target");
}
public FilterCreaturePlayerOrPlaneswalker(String name) {
super(name);
creatureFilter = new FilterCreaturePermanent();
playerFilter = new FilterPlayer();
planeswalkerFilter = new FilterPlaneswalkerPermanent();
}
public FilterCreaturePlayerOrPlaneswalker(final FilterCreaturePlayerOrPlaneswalker filter) {
super(filter);
this.creatureFilter = filter.creatureFilter.copy();
this.playerFilter = filter.playerFilter.copy();
this.planeswalkerFilter = filter.planeswalkerFilter.copy();
}
@Override
public boolean checkObjectClass(Object object) {
return true;
}
@Override
public boolean match(MageItem o, Game game) {
if (o instanceof Player) {
return playerFilter.match((Player) o, game);
} else if (o instanceof Permanent) {
return creatureFilter.match((Permanent) o, game) ||
planeswalkerFilter.match((Permanent) o, game);
}
return false;
}
@Override
public boolean match(MageItem o, UUID sourceId, UUID playerId, Game game) {
if (o instanceof Player) {
return playerFilter.match((Player) o, sourceId, playerId, game);
} else if (o instanceof Permanent) {
return creatureFilter.match((Permanent) o, sourceId, playerId, game) ||
planeswalkerFilter.match((Permanent) o, sourceId, playerId, game);
}
return false;
}
public FilterCreaturePermanent getCreatureFilter() {
return this.creatureFilter;
}
public FilterPlayer getPlayerFilter() {
return this.playerFilter;
}
public FilterPlaneswalkerPermanent getPlaneswalkerFilter() {
return this.planeswalkerFilter;
}
public void setCreatureFilter(FilterCreaturePermanent creatureFilter) {
this.creatureFilter = creatureFilter;
}
@Override
public FilterCreaturePlayerOrPlaneswalker copy() {
return new FilterCreaturePlayerOrPlaneswalker(this);
}
}

View file

@ -0,0 +1,221 @@
package mage.target.common;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.constants.Zone;
import mage.filter.Filter;
import mage.filter.common.FilterCreaturePlayerOrPlaneswalker;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetImpl;
/**
* @author JRHerlehy
* Created on 4/8/18.
*/
public class TargetAnyTarget extends TargetImpl {
protected FilterCreaturePlayerOrPlaneswalker filter;
public TargetAnyTarget() {
this(1, 1, new FilterCreaturePlayerOrPlaneswalker());
}
public TargetAnyTarget(int numTargets) {
this(numTargets, numTargets, new FilterCreaturePlayerOrPlaneswalker());
}
public TargetAnyTarget(FilterCreaturePlayerOrPlaneswalker filter) {
this(1, 1, filter);
}
public TargetAnyTarget(int numTargets, int maxNumTargets) {
this(numTargets, maxNumTargets, new FilterCreaturePlayerOrPlaneswalker());
}
public TargetAnyTarget(int minNumTargets, int maxNumTargets, FilterCreaturePlayerOrPlaneswalker filter) {
this.minNumberOfTargets = minNumTargets;
this.maxNumberOfTargets = maxNumTargets;
this.zone = Zone.ALL;
this.filter = filter;
this.targetName = filter.getMessage();
}
public TargetAnyTarget(final TargetAnyTarget target) {
super(target);
this.filter = target.filter.copy();
}
@Override
public Filter getFilter() {
return this.filter;
}
@Override
public boolean canTarget(UUID id, Game game) {
Permanent permanent = game.getPermanent(id);
if (permanent != null) {
return filter.match(permanent, game);
}
Player player = game.getPlayer(id);
return player != null && filter.match(player, game);
}
@Override
public boolean canTarget(UUID id, Ability source, Game game) {
return canTarget(source.getControllerId(), id, source, game);
}
@Override
public boolean canTarget(UUID controllerId, UUID id, Ability source, Game game) {
Permanent permanent = game.getPermanent(id);
Player player = game.getPlayer(id);
if (source != null) {
MageObject targetSource = game.getObject(source.getSourceId());
if (permanent != null) {
return permanent.canBeTargetedBy(targetSource, source.getControllerId(), game) && filter.match(permanent, source.getSourceId(), source.getControllerId(), game);
}
if (player != null) {
return player.canBeTargetedBy(targetSource, source.getControllerId(), game) && filter.match(player, game);
}
}
if (permanent != null) {
return filter.match(permanent, game);
}
return player != null && filter.match(player, game);
}
/**
* Checks if there are enough {@link Permanent} or {@link Player} that can
* be chosen. Should only be used for Ability targets since this checks for
* protection, shroud etc.
*
* @param sourceId - the target event source
* @param sourceControllerId - controller of the target event source
* @param game
* @return - true if enough valid {@link Permanent} or {@link Player} exist
*/
@Override
public boolean canChoose(UUID sourceId, UUID sourceControllerId, Game game) {
int count = 0;
MageObject targetSource = game.getObject(sourceId);
for (UUID playerId : game.getState().getPlayersInRange(sourceControllerId, game)) {
Player player = game.getPlayer(playerId);
if (player != null && player.canBeTargetedBy(targetSource, sourceControllerId, game) && filter.match(player, game)) {
count++;
if (count >= this.minNumberOfTargets) {
return true;
}
}
}
for (Permanent permanent : game.getBattlefield().getActivePermanents(filter.getCreatureFilter(), sourceControllerId, game)) {
if (permanent.canBeTargetedBy(targetSource, sourceControllerId, game) && filter.match(permanent, sourceId, sourceControllerId, game)) {
count++;
if (count >= this.minNumberOfTargets) {
return true;
}
}
}
return false;
}
/**
* Checks if there are enough {@link Permanent} or {@link Player} that can
* be selected. Should not be used for Ability targets since this does not
* check for protection, shroud etc.
*
* @param sourceControllerId - controller of the select event
* @param game
* @return - true if enough valid {@link Permanent} or {@link Player} exist
*/
@Override
public boolean canChoose(UUID sourceControllerId, Game game) {
int count = 0;
for (UUID playerId : game.getState().getPlayersInRange(sourceControllerId, game)) {
Player player = game.getPlayer(playerId);
if (player != null && filter.match(player, game)) {
count++;
if (count >= this.minNumberOfTargets) {
return true;
}
}
}
for (Permanent permanent : game.getBattlefield().getActivePermanents(filter.getCreatureFilter(), sourceControllerId, game)) {
if (filter.match(permanent, null, sourceControllerId, game)) {
count++;
if (count >= this.minNumberOfTargets) {
return true;
}
}
}
return false;
}
@Override
public Set<UUID> possibleTargets(UUID sourceId, UUID sourceControllerId, Game game) {
Set<UUID> possibleTargets = new HashSet<>();
MageObject targetSource = game.getObject(sourceId);
for (UUID playerId : game.getState().getPlayersInRange(sourceControllerId, game)) {
Player player = game.getPlayer(playerId);
if (player != null
&& player.canBeTargetedBy(targetSource, sourceControllerId, game)
&& filter.getPlayerFilter().match(player, sourceId, sourceControllerId, game)) {
possibleTargets.add(playerId);
}
}
for (Permanent permanent : game.getBattlefield().getActivePermanents(filter.getCreatureFilter(), sourceControllerId, game)) {
if (permanent.canBeTargetedBy(targetSource, sourceControllerId, game)
&& filter.getCreatureFilter().match(permanent, sourceId, sourceControllerId, game)) {
possibleTargets.add(permanent.getId());
}
}
return possibleTargets;
}
@Override
public Set<UUID> possibleTargets(UUID sourceControllerId, Game game) {
Set<UUID> possibleTargets = new HashSet<>();
for (UUID playerId : game.getState().getPlayersInRange(sourceControllerId, game)) {
Player player = game.getPlayer(playerId);
if (player != null && filter.getPlayerFilter().match(player, game)) {
possibleTargets.add(playerId);
}
}
for (Permanent permanent : game.getBattlefield().getActivePermanents(filter.getCreatureFilter(), sourceControllerId, game)) {
if (filter.getCreatureFilter().match(permanent, null, sourceControllerId, game)) {
possibleTargets.add(permanent.getId());
}
}
return possibleTargets;
}
@Override
public String getTargetedName(Game game) {
StringBuilder sb = new StringBuilder();
for (UUID targetId : getTargets()) {
Permanent permanent = game.getPermanent(targetId);
if (permanent != null) {
sb.append(permanent.getLogName()).append(' ');
} else {
Player player = game.getPlayer(targetId);
if (player != null) {
sb.append(player.getLogName()).append(' ');
}
}
}
return sb.toString();
}
@Override
public TargetAnyTarget copy() {
return new TargetAnyTarget(this);
}
}