mirror of
https://github.com/correl/mage.git
synced 2024-12-26 11:09:27 +00:00
Merge pull request #1504 from skyler91/master
Issue #1311: Cards with 'another target creature or player'
This commit is contained in:
commit
e6d7ec511e
4 changed files with 70 additions and 28 deletions
|
@ -34,9 +34,12 @@ import mage.cards.CardImpl;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.Outcome;
|
import mage.constants.Outcome;
|
||||||
import mage.constants.Rarity;
|
import mage.constants.Rarity;
|
||||||
|
import mage.filter.common.FilterCreatureOrPlayer;
|
||||||
|
import mage.filter.predicate.mageobject.AnotherTargetPredicate;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
|
import mage.target.Target;
|
||||||
import mage.target.common.TargetCreatureOrPlayer;
|
import mage.target.common.TargetCreatureOrPlayer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -51,8 +54,28 @@ public class ConeOfFlame extends CardImpl {
|
||||||
|
|
||||||
|
|
||||||
// Cone of Flame deals 1 damage to target creature or player, 2 damage to another target creature or player, and 3 damage to a third target creature or player.
|
// Cone of Flame deals 1 damage to target creature or player, 2 damage to another target creature or player, and 3 damage to a third target creature or player.
|
||||||
|
FilterCreatureOrPlayer filter1 = new FilterCreatureOrPlayer("creature or player to deal 1 damage");
|
||||||
|
TargetCreatureOrPlayer target1 = new TargetCreatureOrPlayer(1, 1, filter1);
|
||||||
|
target1.setTargetTag(1);
|
||||||
|
this.getSpellAbility().addTarget(target1);
|
||||||
|
|
||||||
|
FilterCreatureOrPlayer filter2 = new FilterCreatureOrPlayer("another creature or player to deal 2 damage");
|
||||||
|
AnotherTargetPredicate predicate2 = new AnotherTargetPredicate(2);
|
||||||
|
filter2.getCreatureFilter().add(predicate2);
|
||||||
|
filter2.getPlayerFilter().add(predicate2);
|
||||||
|
TargetCreatureOrPlayer target2 = new TargetCreatureOrPlayer(1, 1, filter2);
|
||||||
|
target2.setTargetTag(2);
|
||||||
|
this.getSpellAbility().addTarget(target2);
|
||||||
|
|
||||||
|
FilterCreatureOrPlayer filter3 = new FilterCreatureOrPlayer("another creature or player to deal 3 damage");
|
||||||
|
AnotherTargetPredicate predicate3 = new AnotherTargetPredicate(3);
|
||||||
|
filter3.getCreatureFilter().add(predicate3);
|
||||||
|
filter3.getPlayerFilter().add(predicate3);
|
||||||
|
TargetCreatureOrPlayer target3 = new TargetCreatureOrPlayer(1, 1, filter3);
|
||||||
|
target3.setTargetTag(3);
|
||||||
|
this.getSpellAbility().addTarget(target3);
|
||||||
|
|
||||||
this.getSpellAbility().addEffect(new ConeOfFlameEffect());
|
this.getSpellAbility().addEffect(new ConeOfFlameEffect());
|
||||||
this.getSpellAbility().addTarget(new TargetCreatureOrPlayer(3));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConeOfFlame(final ConeOfFlame card) {
|
public ConeOfFlame(final ConeOfFlame card) {
|
||||||
|
@ -85,12 +108,12 @@ class ConeOfFlameEffect extends OneShotEffect {
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
boolean applied = false;
|
boolean applied = false;
|
||||||
int damage = 1;
|
int damage = 1;
|
||||||
for (UUID targetId : targetPointer.getTargets(game, source)) {
|
for (Target target : source.getTargets()) {
|
||||||
Permanent permanent = game.getPermanent(targetId);
|
Permanent permanent = game.getPermanent(target.getFirstTarget());
|
||||||
if (permanent != null) {
|
if (permanent != null) {
|
||||||
applied |= (permanent.damage(damage, source.getSourceId(), game, false, true) > 0);
|
applied |= (permanent.damage(damage, source.getSourceId(), game, false, true) > 0);
|
||||||
}
|
}
|
||||||
Player player = game.getPlayer(targetId);
|
Player player = game.getPlayer(target.getFirstTarget());
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
applied |= (player.damage(damage, source.getSourceId(), game, false, true) > 0);
|
applied |= (player.damage(damage, source.getSourceId(), game, false, true) > 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,8 @@ import mage.abilities.Ability;
|
||||||
import mage.abilities.effects.Effect;
|
import mage.abilities.effects.Effect;
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
|
import mage.filter.common.FilterCreatureOrPlayer;
|
||||||
|
import mage.filter.predicate.mageobject.AnotherTargetPredicate;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
|
@ -53,9 +55,20 @@ public class ArcTrail extends CardImpl {
|
||||||
super(ownerId, 81, "Arc Trail", Rarity.UNCOMMON, new CardType[] { CardType.SORCERY }, "{1}{R}");
|
super(ownerId, 81, "Arc Trail", Rarity.UNCOMMON, new CardType[] { CardType.SORCERY }, "{1}{R}");
|
||||||
this.expansionSetCode = "SOM";
|
this.expansionSetCode = "SOM";
|
||||||
|
|
||||||
|
// Arc Trail deals 2 damage to target creature or player and 1 damage to another target creature or player
|
||||||
|
FilterCreatureOrPlayer filter1 = new FilterCreatureOrPlayer("creature or player to deal 2 damage");
|
||||||
|
TargetCreatureOrPlayer target1 = new TargetCreatureOrPlayer(1, 1, filter1);
|
||||||
|
target1.setTargetTag(1);
|
||||||
|
this.getSpellAbility().addTarget(target1);
|
||||||
|
|
||||||
|
FilterCreatureOrPlayer filter2 = new FilterCreatureOrPlayer("another creature or player to deal 1 damage");
|
||||||
|
AnotherTargetPredicate predicate = new AnotherTargetPredicate(2);
|
||||||
|
filter2.getCreatureFilter().add(predicate);
|
||||||
|
filter2.getPlayerFilter().add(predicate);
|
||||||
|
TargetCreatureOrPlayer target2 = new TargetCreatureOrPlayer(1, 1, filter2);
|
||||||
|
target2.setTargetTag(2);
|
||||||
|
this.getSpellAbility().addTarget(target2);
|
||||||
|
|
||||||
Target target = new TargetCreatureOrPlayer(2);
|
|
||||||
this.getSpellAbility().addTarget(target);
|
|
||||||
this.getSpellAbility().addEffect(ArcTrailEffect.getInstance());
|
this.getSpellAbility().addEffect(ArcTrailEffect.getInstance());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,8 +107,8 @@ class ArcTrailEffect extends OneShotEffect {
|
||||||
boolean twoDamageDone = false;
|
boolean twoDamageDone = false;
|
||||||
int damage = 2;
|
int damage = 2;
|
||||||
|
|
||||||
for ( UUID target : targetPointer.getTargets(game, source) ) {
|
for ( Target target : source.getTargets() ) {
|
||||||
Permanent permanent = game.getPermanent(target);
|
Permanent permanent = game.getPermanent(target.getFirstTarget());
|
||||||
|
|
||||||
if ( twoDamageDone ) {
|
if ( twoDamageDone ) {
|
||||||
damage = 1;
|
damage = 1;
|
||||||
|
@ -104,7 +117,7 @@ class ArcTrailEffect extends OneShotEffect {
|
||||||
if (permanent != null) {
|
if (permanent != null) {
|
||||||
applied |= (permanent.damage( damage, source.getSourceId(), game, false, true ) > 0);
|
applied |= (permanent.damage( damage, source.getSourceId(), game, false, true ) > 0);
|
||||||
}
|
}
|
||||||
Player player = game.getPlayer(target);
|
Player player = game.getPlayer(target.getFirstTarget());
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
applied |= (player.damage( damage, source.getSourceId(), game, false, true ) > 0);
|
applied |= (player.damage( damage, source.getSourceId(), game, false, true ) > 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
*/
|
*/
|
||||||
package mage.filter.predicate.mageobject;
|
package mage.filter.predicate.mageobject;
|
||||||
|
|
||||||
import mage.MageObject;
|
import mage.MageItem;
|
||||||
import mage.filter.predicate.ObjectSourcePlayer;
|
import mage.filter.predicate.ObjectSourcePlayer;
|
||||||
import mage.filter.predicate.ObjectSourcePlayerPredicate;
|
import mage.filter.predicate.ObjectSourcePlayerPredicate;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
|
@ -42,7 +42,7 @@ import mage.target.Target;
|
||||||
*
|
*
|
||||||
* @author LevelX2
|
* @author LevelX2
|
||||||
*/
|
*/
|
||||||
public class AnotherTargetPredicate implements ObjectSourcePlayerPredicate<ObjectSourcePlayer<MageObject>> {
|
public class AnotherTargetPredicate implements ObjectSourcePlayerPredicate<ObjectSourcePlayer<MageItem>> {
|
||||||
|
|
||||||
private final int targetTag;
|
private final int targetTag;
|
||||||
|
|
||||||
|
@ -51,13 +51,13 @@ public class AnotherTargetPredicate implements ObjectSourcePlayerPredicate<Objec
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(ObjectSourcePlayer<MageObject> input, Game game) {
|
public boolean apply(ObjectSourcePlayer<MageItem> input, Game game) {
|
||||||
StackObject source = game.getStack().getStackObject(input.getSourceId());
|
StackObject source = game.getStack().getStackObject(input.getSourceId());
|
||||||
if (source != null) {
|
if (source != null) {
|
||||||
for (Target target : source.getStackAbility().getTargets()) {
|
for (Target target : source.getStackAbility().getTargets()) {
|
||||||
if (target.getTargetTag() > 0 // target is included in the target group to check
|
if (target.getTargetTag() > 0 // target is included in the target group to check
|
||||||
&& target.getTargetTag() != targetTag // it's not the target of this predicate
|
&& target.getTargetTag() != targetTag // it's not the target of this predicate
|
||||||
&& target.getTargets().contains(input.getObject().getId())) { // if the uuid already is used for another target in the group it's no allowed here
|
&& target.getTargets().contains(input.getObject().getId())) { // if the uuid already is used for another target in the group it's not allowed here
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,6 @@ import mage.MageObject;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.filter.Filter;
|
import mage.filter.Filter;
|
||||||
import mage.filter.common.FilterCreatureOrPlayer;
|
import mage.filter.common.FilterCreatureOrPlayer;
|
||||||
import mage.filter.common.FilterCreaturePermanent;
|
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
|
@ -52,18 +51,22 @@ public class TargetCreatureOrPlayer extends TargetImpl {
|
||||||
protected FilterCreatureOrPlayer filter;
|
protected FilterCreatureOrPlayer filter;
|
||||||
|
|
||||||
public TargetCreatureOrPlayer() {
|
public TargetCreatureOrPlayer() {
|
||||||
this(1, 1);
|
this(1, 1, new FilterCreatureOrPlayer());
|
||||||
}
|
}
|
||||||
|
|
||||||
public TargetCreatureOrPlayer(int numTargets) {
|
public TargetCreatureOrPlayer(int numTargets) {
|
||||||
this(numTargets, numTargets);
|
this(numTargets, numTargets, new FilterCreatureOrPlayer());
|
||||||
}
|
}
|
||||||
|
|
||||||
public TargetCreatureOrPlayer(int minNumTargets, int maxNumTargets) {
|
public TargetCreatureOrPlayer(int numTargets, int maxNumTargets) {
|
||||||
|
this(numTargets, maxNumTargets, new FilterCreatureOrPlayer());
|
||||||
|
}
|
||||||
|
|
||||||
|
public TargetCreatureOrPlayer(int minNumTargets, int maxNumTargets, FilterCreatureOrPlayer filter) {
|
||||||
this.minNumberOfTargets = minNumTargets;
|
this.minNumberOfTargets = minNumTargets;
|
||||||
this.maxNumberOfTargets = maxNumTargets;
|
this.maxNumberOfTargets = maxNumTargets;
|
||||||
this.zone = Zone.ALL;
|
this.zone = Zone.ALL;
|
||||||
this.filter = new FilterCreatureOrPlayer();
|
this.filter = filter;
|
||||||
this.targetName = filter.getMessage();
|
this.targetName = filter.getMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,7 +144,7 @@ public class TargetCreatureOrPlayer extends TargetImpl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (Permanent permanent: game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), sourceControllerId, game)) {
|
for (Permanent permanent: game.getBattlefield().getActivePermanents(filter.getCreatureFilter(), sourceControllerId, game)) {
|
||||||
if (permanent.canBeTargetedBy(targetSource, sourceControllerId, game) && filter.match(permanent, sourceId, sourceControllerId, game)) {
|
if (permanent.canBeTargetedBy(targetSource, sourceControllerId, game) && filter.match(permanent, sourceId, sourceControllerId, game)) {
|
||||||
count++;
|
count++;
|
||||||
if (count >= this.minNumberOfTargets) {
|
if (count >= this.minNumberOfTargets) {
|
||||||
|
@ -172,7 +175,7 @@ public class TargetCreatureOrPlayer extends TargetImpl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (Permanent permanent: game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), sourceControllerId, game)) {
|
for (Permanent permanent: game.getBattlefield().getActivePermanents(filter.getCreatureFilter(), sourceControllerId, game)) {
|
||||||
if (filter.match(permanent, null, sourceControllerId, game)) {
|
if (filter.match(permanent, null, sourceControllerId, game)) {
|
||||||
count++;
|
count++;
|
||||||
if (count >= this.minNumberOfTargets) {
|
if (count >= this.minNumberOfTargets) {
|
||||||
|
@ -189,12 +192,15 @@ public class TargetCreatureOrPlayer extends TargetImpl {
|
||||||
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.canBeTargetedBy(targetSource, sourceControllerId, game) && filter.match(player, game)) {
|
if (player != null
|
||||||
|
&& player.canBeTargetedBy(targetSource, sourceControllerId, game)
|
||||||
|
&& filter.getPlayerFilter().match(player, sourceId, sourceControllerId, game)) {
|
||||||
possibleTargets.add(playerId);
|
possibleTargets.add(playerId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (Permanent permanent: game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), sourceControllerId, game)) {
|
for (Permanent permanent: game.getBattlefield().getActivePermanents(filter.getCreatureFilter(), sourceControllerId, game)) {
|
||||||
if (permanent.canBeTargetedBy(targetSource, sourceControllerId, game) && filter.match(permanent, sourceId, sourceControllerId, game)) {
|
if (permanent.canBeTargetedBy(targetSource, sourceControllerId, game)
|
||||||
|
&& filter.getCreatureFilter().match(permanent, sourceId, sourceControllerId, game)) {
|
||||||
possibleTargets.add(permanent.getId());
|
possibleTargets.add(permanent.getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -206,12 +212,12 @@ public class TargetCreatureOrPlayer extends TargetImpl {
|
||||||
Set<UUID> possibleTargets = new HashSet<>();
|
Set<UUID> possibleTargets = new HashSet<>();
|
||||||
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 && filter.match(player, game)) {
|
if (player != null && filter.getPlayerFilter().match(player, game)) {
|
||||||
possibleTargets.add(playerId);
|
possibleTargets.add(playerId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (Permanent permanent: game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), sourceControllerId, game)) {
|
for (Permanent permanent: game.getBattlefield().getActivePermanents(filter.getCreatureFilter(), sourceControllerId, game)) {
|
||||||
if (filter.match(permanent, null, sourceControllerId, game)) {
|
if (filter.getCreatureFilter().match(permanent, null, sourceControllerId, game)) {
|
||||||
possibleTargets.add(permanent.getId());
|
possibleTargets.add(permanent.getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue