[filters] Reimplemented Wicked Akuba and fixed filtered Player Targeting

This commit is contained in:
North 2012-07-22 21:59:21 +03:00
parent 93804656ea
commit b230fc883a
4 changed files with 67 additions and 79 deletions

View file

@ -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);
}
} }

View file

@ -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() {

View file

@ -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;
} }

View file

@ -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;
} }