mirror of
https://github.com/magefree/mage.git
synced 2025-12-22 11:32:00 -08:00
[filters] Reimplemented Wicked Akuba and fixed filtered Player Targeting
This commit is contained in:
parent
93804656ea
commit
b230fc883a
4 changed files with 67 additions and 79 deletions
|
|
@ -33,24 +33,31 @@ import mage.Constants.CardType;
|
||||||
import mage.Constants.Rarity;
|
import mage.Constants.Rarity;
|
||||||
import mage.Constants.Zone;
|
import mage.Constants.Zone;
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.MageObject;
|
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.SimpleActivatedAbility;
|
import mage.abilities.common.SimpleActivatedAbility;
|
||||||
import mage.abilities.costs.mana.ColoredManaCost;
|
import mage.abilities.costs.mana.ColoredManaCost;
|
||||||
import mage.abilities.effects.common.LoseLifeTargetEffect;
|
import mage.abilities.effects.common.LoseLifeTargetEffect;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
|
import mage.filter.FilterPlayer;
|
||||||
|
import mage.filter.predicate.ObjectSourcePlayer;
|
||||||
|
import mage.filter.predicate.ObjectSourcePlayerPredicate;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.players.Player;
|
||||||
import mage.game.stack.StackAbility;
|
|
||||||
import mage.target.TargetPlayer;
|
import mage.target.TargetPlayer;
|
||||||
import mage.watchers.common.PlayerDamagedBySourceWatcher;
|
import mage.watchers.common.PlayerDamagedBySourceWatcher;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author LevelX
|
* @author North
|
||||||
*/
|
*/
|
||||||
public class WickedAkuba extends CardImpl<WickedAkuba> {
|
public class WickedAkuba extends CardImpl<WickedAkuba> {
|
||||||
|
|
||||||
|
private static final FilterPlayer filter = new FilterPlayer("player dealt damage by Wicked Akuba this turn");
|
||||||
|
|
||||||
|
static {
|
||||||
|
filter.add(new WickedAkubaPredicate());
|
||||||
|
}
|
||||||
|
|
||||||
public WickedAkuba(UUID ownerId) {
|
public WickedAkuba(UUID ownerId) {
|
||||||
super(ownerId, 150, "Wicked Akuba", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{B}{B}");
|
super(ownerId, 150, "Wicked Akuba", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{B}{B}");
|
||||||
this.expansionSetCode = "CHK";
|
this.expansionSetCode = "CHK";
|
||||||
|
|
@ -62,7 +69,7 @@ public class WickedAkuba extends CardImpl<WickedAkuba> {
|
||||||
|
|
||||||
// {B}: Target player dealt damage by Wicked Akuba this turn loses 1 life.
|
// {B}: Target player dealt damage by Wicked Akuba this turn loses 1 life.
|
||||||
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new LoseLifeTargetEffect(1), new ColoredManaCost(Constants.ColoredManaSymbol.B));
|
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new LoseLifeTargetEffect(1), new ColoredManaCost(Constants.ColoredManaSymbol.B));
|
||||||
ability.addTarget(new WickedAkubaTarget());
|
ability.addTarget(new TargetPlayer(1, 1, false, filter));
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -74,62 +81,22 @@ public class WickedAkuba extends CardImpl<WickedAkuba> {
|
||||||
public WickedAkuba copy() {
|
public WickedAkuba copy() {
|
||||||
return new WickedAkuba(this);
|
return new WickedAkuba(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class WickedAkubaTarget extends TargetPlayer<WickedAkubaTarget> {
|
class WickedAkubaPredicate implements ObjectSourcePlayerPredicate<ObjectSourcePlayer<Player>> {
|
||||||
|
|
||||||
public WickedAkubaTarget() {
|
|
||||||
super();
|
|
||||||
this.targetName = "player dealt damage by Wicked Akuba this turn";
|
|
||||||
}
|
|
||||||
|
|
||||||
public WickedAkubaTarget(final WickedAkubaTarget target) {
|
|
||||||
super(target);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canChoose(UUID sourceId, UUID sourceControllerId, Game game) {
|
public boolean apply(ObjectSourcePlayer<Player> input, Game game) {
|
||||||
filter.getPlayerId().clear();
|
PlayerDamagedBySourceWatcher watcher = (PlayerDamagedBySourceWatcher) game.getState().getWatchers().get("PlayerDamagedBySource", input.getObject().getId());
|
||||||
UUID source = null;
|
if (watcher != null && watcher.damageSources.contains(input.getSourceId())) {
|
||||||
MageObject targetSource = game.getObject(sourceId);
|
return true;
|
||||||
if (targetSource instanceof StackAbility) {
|
|
||||||
StackAbility stackAbility = (StackAbility) targetSource;
|
|
||||||
source = stackAbility.getSourceId();
|
|
||||||
}
|
}
|
||||||
if (targetSource instanceof Permanent) {
|
|
||||||
Permanent permanent = (Permanent) targetSource;
|
|
||||||
source = permanent.getId();
|
|
||||||
}
|
|
||||||
if (source != null) {
|
|
||||||
for (UUID playerId: game.getPlayer(sourceControllerId).getInRange()){
|
|
||||||
PlayerDamagedBySourceWatcher watcher = (PlayerDamagedBySourceWatcher) game.getState().getWatchers().get("PlayerDamagedBySource", playerId);
|
|
||||||
if (watcher != null && watcher.damageSources.contains(source))
|
|
||||||
filter.getPlayerId().add(playerId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (filter.getPlayerId().isEmpty()) // neccessary because empty playerId filter allows all players
|
|
||||||
return false;
|
return false;
|
||||||
return super.canChoose(sourceId, sourceControllerId, game);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canTarget(UUID id, Ability source, Game game) {
|
public String toString() {
|
||||||
filter.getPlayerId().clear();
|
return "(Player dealt damage by {source} this turn)";
|
||||||
for (UUID playerId: game.getPlayer(source.getControllerId()).getInRange()){
|
|
||||||
PlayerDamagedBySourceWatcher watcher = (PlayerDamagedBySourceWatcher) game.getState().getWatchers().get("PlayerDamagedBySource", playerId);
|
|
||||||
|
|
||||||
if (watcher != null && watcher.damageSources.contains(source.getSourceId()))
|
|
||||||
filter.getPlayerId().add(playerId);
|
|
||||||
}
|
}
|
||||||
if (filter.getPlayerId().isEmpty()) // neccessary because empty playerId filter allows all players
|
|
||||||
return false;
|
|
||||||
return super.canTarget(id, source, game);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public WickedAkubaTarget copy() {
|
|
||||||
return new WickedAkubaTarget(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -28,35 +28,49 @@
|
||||||
|
|
||||||
package mage.filter;
|
package mage.filter;
|
||||||
|
|
||||||
import mage.Constants.TargetController;
|
|
||||||
import mage.game.Game;
|
|
||||||
import mage.players.Player;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import mage.Constants.TargetController;
|
||||||
|
import mage.filter.predicate.ObjectPlayer;
|
||||||
|
import mage.filter.predicate.ObjectPlayerPredicate;
|
||||||
|
import mage.filter.predicate.ObjectSourcePlayer;
|
||||||
|
import mage.filter.predicate.Predicates;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.players.Player;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author BetaSteward_at_googlemail.com
|
* @author BetaSteward_at_googlemail.com
|
||||||
|
* @author North
|
||||||
*/
|
*/
|
||||||
public class FilterPlayer extends FilterImpl<Player> {
|
public class FilterPlayer extends FilterImpl<Player> {
|
||||||
|
|
||||||
|
protected List<ObjectPlayerPredicate<ObjectPlayer<Player>>> extraPredicates = new ArrayList<ObjectPlayerPredicate<ObjectPlayer<Player>>>();
|
||||||
protected List<UUID> playerId = new ArrayList<UUID>();
|
protected List<UUID> playerId = new ArrayList<UUID>();
|
||||||
protected boolean notPlayer;
|
protected boolean notPlayer;
|
||||||
protected TargetController playerTarget = TargetController.ANY;
|
protected TargetController playerTarget = TargetController.ANY;
|
||||||
|
|
||||||
public FilterPlayer() {
|
public FilterPlayer() {
|
||||||
super("player");
|
this("player");
|
||||||
}
|
}
|
||||||
|
|
||||||
public FilterPlayer(FilterPlayer filter) {
|
public FilterPlayer(String name) {
|
||||||
|
super(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FilterPlayer(final FilterPlayer filter) {
|
||||||
super(filter);
|
super(filter);
|
||||||
|
this.extraPredicates = new ArrayList<ObjectPlayerPredicate<ObjectPlayer<Player>>>(filter.extraPredicates);
|
||||||
this.playerId.addAll(filter.playerId);
|
this.playerId.addAll(filter.playerId);
|
||||||
this.notPlayer = filter.notPlayer;
|
this.notPlayer = filter.notPlayer;
|
||||||
this.playerTarget = filter.playerTarget;
|
this.playerTarget = filter.playerTarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void add(ObjectPlayerPredicate predicate) {
|
||||||
|
extraPredicates.add(predicate);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean match(Player player, Game game) {
|
public boolean match(Player player, Game game) {
|
||||||
|
|
||||||
|
|
@ -66,28 +80,28 @@ public class FilterPlayer extends FilterImpl<Player> {
|
||||||
return !notFilter;
|
return !notFilter;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean match(Player player, UUID sourceId, UUID playerId, Game game) {
|
public boolean match(Player player, UUID sourceId, UUID controllerId, Game game) {
|
||||||
if (!this.match(player, game))
|
if (!this.match(player, game))
|
||||||
return notFilter;
|
return notFilter;
|
||||||
|
|
||||||
if (playerTarget != TargetController.ANY && playerId != null) {
|
if (playerTarget != TargetController.ANY && controllerId != null) {
|
||||||
switch(playerTarget) {
|
switch(playerTarget) {
|
||||||
case YOU:
|
case YOU:
|
||||||
if (!player.getId().equals(playerId))
|
if (!player.getId().equals(controllerId))
|
||||||
return notFilter;
|
return notFilter;
|
||||||
break;
|
break;
|
||||||
case OPPONENT:
|
case OPPONENT:
|
||||||
if (!game.getOpponents(playerId).contains(player.getId()))
|
if (!game.getOpponents(controllerId).contains(player.getId()))
|
||||||
return notFilter;
|
return notFilter;
|
||||||
break;
|
break;
|
||||||
case NOT_YOU:
|
case NOT_YOU:
|
||||||
if (player.getId().equals(playerId))
|
if (player.getId().equals(controllerId))
|
||||||
return notFilter;
|
return notFilter;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return !notFilter;
|
return Predicates.and(extraPredicates).apply(new ObjectSourcePlayer(player, sourceId, controllerId), game);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<UUID> getPlayerId() {
|
public List<UUID> getPlayerId() {
|
||||||
|
|
|
||||||
|
|
@ -74,12 +74,12 @@ public class FilterCreatureOrPlayer extends FilterImpl<Object> implements Filter
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean match(Object o, UUID sourceId, UUID playerId, Game game) {
|
public boolean match(Object o, UUID sourceId, UUID controllerId, Game game) {
|
||||||
if (o instanceof Player) {
|
if (o instanceof Player) {
|
||||||
return playerFilter.match((Player)o, sourceId, playerId, game);
|
return playerFilter.match((Player)o, sourceId, controllerId, game);
|
||||||
}
|
}
|
||||||
else if (o instanceof Permanent) {
|
else if (o instanceof Permanent) {
|
||||||
return creatureFilter.match((Permanent)o, sourceId, playerId, game);
|
return creatureFilter.match((Permanent)o, sourceId, controllerId, game);
|
||||||
}
|
}
|
||||||
return notFilter;
|
return notFilter;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ import java.util.UUID;
|
||||||
*/
|
*/
|
||||||
public class TargetPlayer<T extends TargetPlayer<T>> extends TargetImpl<TargetPlayer<T>> {
|
public class TargetPlayer<T extends TargetPlayer<T>> extends TargetImpl<TargetPlayer<T>> {
|
||||||
|
|
||||||
protected FilterPlayer filter = new FilterPlayer();
|
protected FilterPlayer filter;
|
||||||
|
|
||||||
public TargetPlayer(boolean required) {
|
public TargetPlayer(boolean required) {
|
||||||
this();
|
this();
|
||||||
|
|
@ -60,9 +60,14 @@ public class TargetPlayer<T extends TargetPlayer<T>> extends TargetImpl<TargetPl
|
||||||
}
|
}
|
||||||
|
|
||||||
public TargetPlayer(int minNumTargets, int maxNumTargets, boolean notTarget) {
|
public TargetPlayer(int minNumTargets, int maxNumTargets, boolean notTarget) {
|
||||||
|
this(minNumTargets, maxNumTargets, notTarget, new FilterPlayer());
|
||||||
|
}
|
||||||
|
|
||||||
|
public TargetPlayer(int minNumTargets, int maxNumTargets, boolean notTarget, FilterPlayer filter) {
|
||||||
this.minNumberOfTargets = minNumTargets;
|
this.minNumberOfTargets = minNumTargets;
|
||||||
this.maxNumberOfTargets = maxNumTargets;
|
this.maxNumberOfTargets = maxNumTargets;
|
||||||
this.targetName = "player";
|
this.filter = filter;
|
||||||
|
this.targetName = filter.getMessage();
|
||||||
this.notTarget = notTarget;
|
this.notTarget = notTarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -91,7 +96,7 @@ public class TargetPlayer<T extends TargetPlayer<T>> extends TargetImpl<TargetPl
|
||||||
MageObject targetSource = game.getObject(sourceId);
|
MageObject targetSource = game.getObject(sourceId);
|
||||||
for (UUID playerId: game.getPlayer(sourceControllerId).getInRange()) {
|
for (UUID playerId: game.getPlayer(sourceControllerId).getInRange()) {
|
||||||
Player player = game.getPlayer(playerId);
|
Player player = game.getPlayer(playerId);
|
||||||
if (player != null && !player.hasLeft() && filter.match(player, game)) {
|
if (player != null && !player.hasLeft() && filter.match(player, sourceId, sourceControllerId, game)) {
|
||||||
if (player.canBeTargetedBy(targetSource, game)) {
|
if (player.canBeTargetedBy(targetSource, game)) {
|
||||||
count++;
|
count++;
|
||||||
if (count >= this.minNumberOfTargets)
|
if (count >= this.minNumberOfTargets)
|
||||||
|
|
@ -130,7 +135,7 @@ public class TargetPlayer<T extends TargetPlayer<T>> extends TargetImpl<TargetPl
|
||||||
MageObject targetSource = game.getObject(sourceId);
|
MageObject targetSource = game.getObject(sourceId);
|
||||||
for (UUID playerId: game.getPlayer(sourceControllerId).getInRange()) {
|
for (UUID playerId: game.getPlayer(sourceControllerId).getInRange()) {
|
||||||
Player player = game.getPlayer(playerId);
|
Player player = game.getPlayer(playerId);
|
||||||
if (player != null && !player.hasLeft() && filter.match(player, game)) {
|
if (player != null && !player.hasLeft() && filter.match(player, sourceId, sourceControllerId, game)) {
|
||||||
if (player.canBeTargetedBy(targetSource, game))
|
if (player.canBeTargetedBy(targetSource, game))
|
||||||
possibleTargets.add(playerId);
|
possibleTargets.add(playerId);
|
||||||
}
|
}
|
||||||
|
|
@ -173,11 +178,13 @@ public class TargetPlayer<T extends TargetPlayer<T>> extends TargetImpl<TargetPl
|
||||||
public boolean canTarget(UUID id, Ability source, Game game) {
|
public boolean canTarget(UUID id, Ability source, Game game) {
|
||||||
Player player = game.getPlayer(id);
|
Player player = game.getPlayer(id);
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
if (source != null)
|
if (source != null) {
|
||||||
return player.canBeTargetedBy(game.getObject(source.getSourceId()), game) && filter.match(player, game);
|
return player.canBeTargetedBy(game.getObject(source.getSourceId()), game)
|
||||||
else
|
&& filter.match(player, source.getSourceId(), source.getControllerId(), game);
|
||||||
|
} else {
|
||||||
return filter.match(player, game);
|
return filter.match(player, game);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue