mirror of
https://github.com/magefree/mage.git
synced 2025-12-25 04:52:07 -08:00
[DOM] Implement Legendary Sorceries
Add: Target Any Target for damage spells Add: Drudge Sentinel Fix: Genesis Wave Filter
This commit is contained in:
parent
ecbe7e68a6
commit
702756b4e7
13 changed files with 935 additions and 12 deletions
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
221
Mage/src/main/java/mage/target/common/TargetAnyTarget.java
Normal file
221
Mage/src/main/java/mage/target/common/TargetAnyTarget.java
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue