mirror of
https://github.com/correl/mage.git
synced 2025-04-09 17:00:09 -09:00
(WIP) Replacing blocking/blocked by predicates (#8729)
* replaced blocking/blocked by predicates * added test for knight of dusk (currently fails) * added source parameter to filters and everything else that needs it * some changes to various predicates * test fix * small changes to filter code * merge fix * fixed a test failure * small change to Karn, Scion of Urza * removed sourceId from filter methods and other similar places * added new getobject method to fix some test failures * a few more fixes * fixed merge conflicts * merge fix
This commit is contained in:
parent
53877424a0
commit
80e11b2052
1719 changed files with 3384 additions and 3325 deletions
Mage.Server.Plugins
Mage.Player.AI.MA/src/mage/player/ai
Mage.Player.AI/src/main/java/mage/player/ai
Mage.Player.AIMCTS/src/mage/player/ai
Mage.Player.AIMinimax/src/mage/player/ai
Mage.Player.Human/src/mage/player/human
Mage.Sets/src/mage/cards
a
Abeyance.javaAbuJafar.javaAbundance.javaAcademyResearchers.javaAcererakTheArchlich.javaAcidicSoil.javaAcolyteOfAffliction.javaAdviceFromTheFae.javaAerialSurveyor.javaAetherVial.javaAetherbornMarauder.javaAethermagesTouch.javaAetherplasm.javaAetherspouts.javaAgadeemOccultist.javaAgadeemsAwakening.javaAgitatorAnt.javaAidFromTheCowl.javaAkiriFearlessVoyager.javaAkromaVisionOfIxidor.javaAlhammarretHighArbiter.javaAlibouAncientWitness.javaAlignedHedronNetwork.javaAliveWell.javaAllureOfTheUnknown.javaAminatouTheFateshifter.javaAmuletOfSafekeeping.javaAnHavvaConstable.javaAnHavvaInn.javaAnathemancer.javaAngelOfGlorysRise.javaAnimalMagnetism.javaAnimistsAwakening.javaAnuridScavenger.javaArashinWarBeast.javaAraumiOfTheDeadTide.javaArcbond.javaArchaeomancersMap.javaArchdemonOfGreed.javaArchfiendOfDepravity.javaArcticFoxes.javaArdennIntrepidArchaeologist.javaArdentDustspeaker.javaArmedAndArmored.javaArmoredSkyhunter.javaArmoryAutomaton.javaArniBrokenbrow.javaArsenalThresher.javaArterialAlchemy.javaAryelKnightOfWindgrace.javaAsForetold.javaAscendantAcolyte.javaAscentOfTheWorthy.javaAshayaSoulOfTheWild.javaAshiokDreamRender.javaAshiokNightmareWeaver.javaAspectOfWolf.javaAssemblyHall.javaAtarkaWorldRender.javaAthreosGodOfPassage.javaAugurOfBolas.javaAuntiesSnitch.javaAuraBarbs.javaAuraGraft.javaAuraThief.javaAureliasFury.javaAurraSingBaneOfJedi.javaAvenShrine.javaAvenSoulgazer.javaAzorTheLawbringer.javaAzoriusAethermage.javaAzorsGateway.javaAzraBladeseeker.javaAzraOddsmaker.java
b
BINGO.javaBackFromTheBrink.javaBagOfDevouring.javaBakisCurse.javaBalancingAct.javaBalduvianWarlord.javaBalthorTheDefiled.javaBaneOfProgress.javaBaneclawMarauder.javaBarbedBackWurm.javaBaronVonCount.javaBaseCamp.javaBatheInLight.javaBattleForBretagard.javaBattlefieldScrounger.javaBattlefieldThaumaturge.javaBeaconOfDestiny.javaBeamsplitterMage.javaBeckCall.javaBendOrBreak.javaBenefactionOfRhonas.java
|
@ -396,7 +396,7 @@ public class ComputerPlayer6 extends ComputerPlayer /*implements Player*/ {
|
||||||
&& stackObject.getControllerId().equals(playerId)) {
|
&& stackObject.getControllerId().equals(playerId)) {
|
||||||
Target target = effect.getTarget();
|
Target target = effect.getTarget();
|
||||||
if (!target.doneChosing()) {
|
if (!target.doneChosing()) {
|
||||||
for (UUID targetId : target.possibleTargets(stackObject.getSourceId(), stackObject.getControllerId(), game)) {
|
for (UUID targetId : target.possibleTargets(stackObject.getControllerId(), stackObject.getStackAbility(), game)) {
|
||||||
Game sim = game.copy();
|
Game sim = game.copy();
|
||||||
StackAbility newAbility = (StackAbility) stackObject.copy();
|
StackAbility newAbility = (StackAbility) stackObject.copy();
|
||||||
SearchEffect newEffect = getSearchEffect(newAbility);
|
SearchEffect newEffect = getSearchEffect(newAbility);
|
||||||
|
|
|
@ -122,12 +122,12 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean choose(Outcome outcome, Target target, UUID sourceId, Game game) {
|
public boolean choose(Outcome outcome, Target target, Ability source, Game game) {
|
||||||
return choose(outcome, target, sourceId, game, null);
|
return choose(outcome, target, source, game, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean choose(Outcome outcome, Target target, UUID sourceId, Game game, Map<String, Serializable> options) {
|
public boolean choose(Outcome outcome, Target target, Ability source, Game game, Map<String, Serializable> options) {
|
||||||
|
|
||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
log.debug("choose: " + outcome.toString() + ':' + target.toString());
|
log.debug("choose: " + outcome.toString() + ':' + target.toString());
|
||||||
|
@ -143,9 +143,10 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
||||||
&& target.getAbilityController() != null) {
|
&& target.getAbilityController() != null) {
|
||||||
abilityControllerId = target.getAbilityController();
|
abilityControllerId = target.getAbilityController();
|
||||||
}
|
}
|
||||||
|
UUID sourceId = source != null ? source.getSourceId() : null;
|
||||||
|
|
||||||
boolean required = target.isRequired(sourceId, game);
|
boolean required = target.isRequired(sourceId, game);
|
||||||
Set<UUID> possibleTargets = target.possibleTargets(sourceId, abilityControllerId, game);
|
Set<UUID> possibleTargets = target.possibleTargets(abilityControllerId, source, game);
|
||||||
if (possibleTargets.isEmpty() || target.getTargets().size() >= target.getNumberOfTargets()) {
|
if (possibleTargets.isEmpty() || target.getTargets().size() >= target.getNumberOfTargets()) {
|
||||||
required = false;
|
required = false;
|
||||||
}
|
}
|
||||||
|
@ -160,7 +161,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target.getOriginalTarget() instanceof TargetPlayer) {
|
if (target.getOriginalTarget() instanceof TargetPlayer) {
|
||||||
return setTargetPlayer(outcome, target, null, sourceId, abilityControllerId, randomOpponentId, game, required);
|
return setTargetPlayer(outcome, target, null, abilityControllerId, randomOpponentId, game, required);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target.getOriginalTarget() instanceof TargetDiscard) {
|
if (target.getOriginalTarget() instanceof TargetDiscard) {
|
||||||
|
@ -191,12 +192,12 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
||||||
if (target.getOriginalTarget() instanceof TargetControlledPermanent) {
|
if (target.getOriginalTarget() instanceof TargetControlledPermanent) {
|
||||||
List<Permanent> targets;
|
List<Permanent> targets;
|
||||||
TargetControlledPermanent origTarget = (TargetControlledPermanent) target.getOriginalTarget();
|
TargetControlledPermanent origTarget = (TargetControlledPermanent) target.getOriginalTarget();
|
||||||
targets = threats(abilityControllerId, sourceId, origTarget.getFilter(), game, target.getTargets());
|
targets = threats(abilityControllerId, source, origTarget.getFilter(), game, target.getTargets());
|
||||||
if (!outcome.isGood()) {
|
if (!outcome.isGood()) {
|
||||||
Collections.reverse(targets);
|
Collections.reverse(targets);
|
||||||
}
|
}
|
||||||
for (Permanent permanent : targets) {
|
for (Permanent permanent : targets) {
|
||||||
if (origTarget.canTarget(abilityControllerId, permanent.getId(), sourceId, game, false) && !target.getTargets().contains(permanent.getId())) {
|
if (origTarget.canTarget(abilityControllerId, permanent.getId(), source, game, false) && !target.getTargets().contains(permanent.getId())) {
|
||||||
target.add(permanent.getId(), game);
|
target.add(permanent.getId(), game);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -217,18 +218,18 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
||||||
|
|
||||||
List<Permanent> targets;
|
List<Permanent> targets;
|
||||||
if (outcome.isCanTargetAll()) {
|
if (outcome.isCanTargetAll()) {
|
||||||
targets = threats(null, sourceId, filter, game, target.getTargets());
|
targets = threats(null, source, filter, game, target.getTargets());
|
||||||
} else {
|
} else {
|
||||||
if (outcome.isGood()) {
|
if (outcome.isGood()) {
|
||||||
targets = threats(abilityControllerId, sourceId, filter, game, target.getTargets());
|
targets = threats(abilityControllerId, source, filter, game, target.getTargets());
|
||||||
} else {
|
} else {
|
||||||
targets = threats(randomOpponentId, sourceId, filter, game, target.getTargets());
|
targets = threats(randomOpponentId, source, filter, game, target.getTargets());
|
||||||
}
|
}
|
||||||
if (targets.isEmpty() && target.isRequired()) {
|
if (targets.isEmpty() && target.isRequired()) {
|
||||||
if (!outcome.isGood()) {
|
if (!outcome.isGood()) {
|
||||||
targets = threats(abilityControllerId, sourceId, filter, game, target.getTargets());
|
targets = threats(abilityControllerId, source, filter, game, target.getTargets());
|
||||||
} else {
|
} else {
|
||||||
targets = threats(randomOpponentId, sourceId, filter, game, target.getTargets());
|
targets = threats(randomOpponentId, source, filter, game, target.getTargets());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -257,7 +258,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
||||||
if (target.getOriginalTarget() instanceof TargetCardInHand
|
if (target.getOriginalTarget() instanceof TargetCardInHand
|
||||||
|| (target.getZone() == Zone.HAND && (target.getOriginalTarget() instanceof TargetCard))) {
|
|| (target.getZone() == Zone.HAND && (target.getOriginalTarget() instanceof TargetCard))) {
|
||||||
List<Card> cards = new ArrayList<>();
|
List<Card> cards = new ArrayList<>();
|
||||||
for (UUID cardId : target.possibleTargets(sourceId, this.getId(), game)) {
|
for (UUID cardId : target.possibleTargets(this.getId(), source, game)) {
|
||||||
Card card = game.getCard(cardId);
|
Card card = game.getCard(cardId);
|
||||||
if (card != null) {
|
if (card != null) {
|
||||||
cards.add(card);
|
cards.add(card);
|
||||||
|
@ -278,9 +279,9 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
||||||
List<Permanent> targets;
|
List<Permanent> targets;
|
||||||
TargetAnyTarget origTarget = (TargetAnyTarget) target.getOriginalTarget();
|
TargetAnyTarget origTarget = (TargetAnyTarget) target.getOriginalTarget();
|
||||||
if (outcome.isGood()) {
|
if (outcome.isGood()) {
|
||||||
targets = threats(abilityControllerId, sourceId, ((FilterCreaturePlayerOrPlaneswalker) origTarget.getFilter()).getPermanentFilter(), game, target.getTargets());
|
targets = threats(abilityControllerId, source, ((FilterCreaturePlayerOrPlaneswalker) origTarget.getFilter()).getPermanentFilter(), game, target.getTargets());
|
||||||
} else {
|
} else {
|
||||||
targets = threats(randomOpponentId, sourceId, ((FilterCreaturePlayerOrPlaneswalker) origTarget.getFilter()).getPermanentFilter(), game, target.getTargets());
|
targets = threats(randomOpponentId, source, ((FilterCreaturePlayerOrPlaneswalker) origTarget.getFilter()).getPermanentFilter(), game, target.getTargets());
|
||||||
}
|
}
|
||||||
for (Permanent permanent : targets) {
|
for (Permanent permanent : targets) {
|
||||||
List<UUID> alreadyTargetted = target.getTargets();
|
List<UUID> alreadyTargetted = target.getTargets();
|
||||||
|
@ -309,9 +310,9 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
||||||
List<Permanent> targets;
|
List<Permanent> targets;
|
||||||
TargetCreatureOrPlayer origTarget = (TargetCreatureOrPlayer) target.getOriginalTarget();
|
TargetCreatureOrPlayer origTarget = (TargetCreatureOrPlayer) target.getOriginalTarget();
|
||||||
if (outcome.isGood()) {
|
if (outcome.isGood()) {
|
||||||
targets = threats(abilityControllerId, sourceId, ((FilterCreatureOrPlayer) origTarget.getFilter()).getCreatureFilter(), game, target.getTargets());
|
targets = threats(abilityControllerId, source, ((FilterCreatureOrPlayer) origTarget.getFilter()).getCreatureFilter(), game, target.getTargets());
|
||||||
} else {
|
} else {
|
||||||
targets = threats(randomOpponentId, sourceId, ((FilterCreatureOrPlayer) origTarget.getFilter()).getCreatureFilter(), game, target.getTargets());
|
targets = threats(randomOpponentId, source, ((FilterCreatureOrPlayer) origTarget.getFilter()).getCreatureFilter(), game, target.getTargets());
|
||||||
}
|
}
|
||||||
for (Permanent permanent : targets) {
|
for (Permanent permanent : targets) {
|
||||||
List<UUID> alreadyTargeted = target.getTargets();
|
List<UUID> alreadyTargeted = target.getTargets();
|
||||||
|
@ -339,8 +340,8 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
||||||
if (target.getOriginalTarget() instanceof TargetPermanentOrPlayer) {
|
if (target.getOriginalTarget() instanceof TargetPermanentOrPlayer) {
|
||||||
List<Permanent> targets;
|
List<Permanent> targets;
|
||||||
TargetPermanentOrPlayer origTarget = (TargetPermanentOrPlayer) target.getOriginalTarget();
|
TargetPermanentOrPlayer origTarget = (TargetPermanentOrPlayer) target.getOriginalTarget();
|
||||||
List<Permanent> ownedTargets = threats(abilityControllerId, sourceId, ((FilterPermanentOrPlayer) origTarget.getFilter()).getPermanentFilter(), game, target.getTargets());
|
List<Permanent> ownedTargets = threats(abilityControllerId, source, ((FilterPermanentOrPlayer) origTarget.getFilter()).getPermanentFilter(), game, target.getTargets());
|
||||||
List<Permanent> opponentTargets = threats(randomOpponentId, sourceId, ((FilterPermanentOrPlayer) origTarget.getFilter()).getPermanentFilter(), game, target.getTargets());
|
List<Permanent> opponentTargets = threats(randomOpponentId, source, ((FilterPermanentOrPlayer) origTarget.getFilter()).getPermanentFilter(), game, target.getTargets());
|
||||||
if (outcome.isGood()) {
|
if (outcome.isGood()) {
|
||||||
targets = ownedTargets;
|
targets = ownedTargets;
|
||||||
} else {
|
} else {
|
||||||
|
@ -463,7 +464,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
||||||
|
|
||||||
if (target.getOriginalTarget() instanceof TargetSource) {
|
if (target.getOriginalTarget() instanceof TargetSource) {
|
||||||
Set<UUID> targets;
|
Set<UUID> targets;
|
||||||
targets = target.possibleTargets(sourceId, abilityControllerId, game);
|
targets = target.possibleTargets(abilityControllerId, source, game);
|
||||||
for (UUID targetId : targets) {
|
for (UUID targetId : targets) {
|
||||||
MageObject targetObject = game.getObject(targetId);
|
MageObject targetObject = game.getObject(targetId);
|
||||||
if (targetObject != null) {
|
if (targetObject != null) {
|
||||||
|
@ -517,7 +518,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean required = target.isRequired(sourceId, game);
|
boolean required = target.isRequired(sourceId, game);
|
||||||
Set<UUID> possibleTargets = target.possibleTargets(sourceId, abilityControllerId, game);
|
Set<UUID> possibleTargets = target.possibleTargets(abilityControllerId, source, game);
|
||||||
if (possibleTargets.isEmpty() || target.getTargets().size() >= target.getNumberOfTargets()) {
|
if (possibleTargets.isEmpty() || target.getTargets().size() >= target.getNumberOfTargets()) {
|
||||||
required = false;
|
required = false;
|
||||||
}
|
}
|
||||||
|
@ -537,7 +538,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target.getOriginalTarget() instanceof TargetPlayer) {
|
if (target.getOriginalTarget() instanceof TargetPlayer) {
|
||||||
return setTargetPlayer(outcome, target, source, sourceId, abilityControllerId, randomOpponentId, game, required);
|
return setTargetPlayer(outcome, target, source, abilityControllerId, randomOpponentId, game, required);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Angel of Serenity trigger
|
// Angel of Serenity trigger
|
||||||
|
@ -642,7 +643,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
||||||
if (target.getOriginalTarget() instanceof TargetControlledPermanent) {
|
if (target.getOriginalTarget() instanceof TargetControlledPermanent) {
|
||||||
TargetControlledPermanent origTarget = (TargetControlledPermanent) target.getOriginalTarget();
|
TargetControlledPermanent origTarget = (TargetControlledPermanent) target.getOriginalTarget();
|
||||||
List<Permanent> targets;
|
List<Permanent> targets;
|
||||||
targets = threats(abilityControllerId, sourceId, origTarget.getFilter(), game, target.getTargets());
|
targets = threats(abilityControllerId, source, origTarget.getFilter(), game, target.getTargets());
|
||||||
if (!outcome.isGood()) {
|
if (!outcome.isGood()) {
|
||||||
Collections.reverse(targets);
|
Collections.reverse(targets);
|
||||||
}
|
}
|
||||||
|
@ -671,7 +672,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
||||||
+ target.getOriginalTarget().getClass().getCanonicalName());
|
+ target.getOriginalTarget().getClass().getCanonicalName());
|
||||||
}
|
}
|
||||||
|
|
||||||
findBestPermanentTargets(outcome, abilityControllerId, sourceId, filter,
|
findBestPermanentTargets(outcome, abilityControllerId, sourceId, source, filter,
|
||||||
game, target, goodList, badList, allList);
|
game, target, goodList, badList, allList);
|
||||||
|
|
||||||
// use good list all the time and add maximum targets
|
// use good list all the time and add maximum targets
|
||||||
|
@ -700,9 +701,9 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
||||||
List<Permanent> targets;
|
List<Permanent> targets;
|
||||||
TargetCreatureOrPlayer origTarget = ((TargetCreatureOrPlayer) target.getOriginalTarget());
|
TargetCreatureOrPlayer origTarget = ((TargetCreatureOrPlayer) target.getOriginalTarget());
|
||||||
if (outcome.isGood()) {
|
if (outcome.isGood()) {
|
||||||
targets = threats(abilityControllerId, sourceId, ((FilterCreatureOrPlayer) origTarget.getFilter()).getCreatureFilter(), game, target.getTargets());
|
targets = threats(abilityControllerId, source, ((FilterCreatureOrPlayer) origTarget.getFilter()).getCreatureFilter(), game, target.getTargets());
|
||||||
} else {
|
} else {
|
||||||
targets = threats(randomOpponentId, sourceId, ((FilterCreatureOrPlayer) origTarget.getFilter()).getCreatureFilter(), game, target.getTargets());
|
targets = threats(randomOpponentId, source, ((FilterCreatureOrPlayer) origTarget.getFilter()).getCreatureFilter(), game, target.getTargets());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (targets.isEmpty()) {
|
if (targets.isEmpty()) {
|
||||||
|
@ -742,9 +743,9 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
||||||
List<Permanent> targets;
|
List<Permanent> targets;
|
||||||
TargetAnyTarget origTarget = ((TargetAnyTarget) target.getOriginalTarget());
|
TargetAnyTarget origTarget = ((TargetAnyTarget) target.getOriginalTarget());
|
||||||
if (outcome.isGood()) {
|
if (outcome.isGood()) {
|
||||||
targets = threats(abilityControllerId, sourceId, ((FilterCreaturePlayerOrPlaneswalker) origTarget.getFilter()).getPermanentFilter(), game, target.getTargets());
|
targets = threats(abilityControllerId, source, ((FilterCreaturePlayerOrPlaneswalker) origTarget.getFilter()).getPermanentFilter(), game, target.getTargets());
|
||||||
} else {
|
} else {
|
||||||
targets = threats(randomOpponentId, sourceId, ((FilterCreaturePlayerOrPlaneswalker) origTarget.getFilter()).getPermanentFilter(), game, target.getTargets());
|
targets = threats(randomOpponentId, source, ((FilterCreaturePlayerOrPlaneswalker) origTarget.getFilter()).getPermanentFilter(), game, target.getTargets());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (targets.isEmpty()) {
|
if (targets.isEmpty()) {
|
||||||
|
@ -785,9 +786,9 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
||||||
List<Permanent> targets;
|
List<Permanent> targets;
|
||||||
TargetPermanentOrPlayer origTarget = ((TargetPermanentOrPlayer) target.getOriginalTarget());
|
TargetPermanentOrPlayer origTarget = ((TargetPermanentOrPlayer) target.getOriginalTarget());
|
||||||
if (outcome.isGood()) {
|
if (outcome.isGood()) {
|
||||||
targets = threats(abilityControllerId, source.getSourceId(), ((FilterPermanentOrPlayer) origTarget.getFilter()).getPermanentFilter(), game, target.getTargets());
|
targets = threats(abilityControllerId, source, ((FilterPermanentOrPlayer) origTarget.getFilter()).getPermanentFilter(), game, target.getTargets());
|
||||||
} else {
|
} else {
|
||||||
targets = threats(randomOpponentId, source.getSourceId(), ((FilterPermanentOrPlayer) origTarget.getFilter()).getPermanentFilter(), game, target.getTargets());
|
targets = threats(randomOpponentId, source, ((FilterPermanentOrPlayer) origTarget.getFilter()).getPermanentFilter(), game, target.getTargets());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (targets.isEmpty()) {
|
if (targets.isEmpty()) {
|
||||||
|
@ -823,9 +824,9 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
||||||
// normal cycle (good for you, bad for opponents)
|
// normal cycle (good for you, bad for opponents)
|
||||||
// possible good/bad permanents
|
// possible good/bad permanents
|
||||||
if (outcome.isGood()) {
|
if (outcome.isGood()) {
|
||||||
targets = threats(abilityControllerId, source.getSourceId(), ((FilterPermanentOrPlayer) target.getFilter()).getPermanentFilter(), game, target.getTargets());
|
targets = threats(abilityControllerId, source, ((FilterPermanentOrPlayer) target.getFilter()).getPermanentFilter(), game, target.getTargets());
|
||||||
} else {
|
} else {
|
||||||
targets = threats(randomOpponentId, source.getSourceId(), ((FilterPermanentOrPlayer) target.getFilter()).getPermanentFilter(), game, target.getTargets());
|
targets = threats(randomOpponentId, source, ((FilterPermanentOrPlayer) target.getFilter()).getPermanentFilter(), game, target.getTargets());
|
||||||
}
|
}
|
||||||
|
|
||||||
// possible good/bad players
|
// possible good/bad players
|
||||||
|
@ -930,12 +931,12 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
||||||
List<Permanent> targets;
|
List<Permanent> targets;
|
||||||
boolean outcomeTargets = true;
|
boolean outcomeTargets = true;
|
||||||
if (outcome.isGood()) {
|
if (outcome.isGood()) {
|
||||||
targets = threats(abilityControllerId, source == null ? null : source.getSourceId(), origTarget.getPermanentFilter(), game, target.getTargets());
|
targets = threats(abilityControllerId, source, origTarget.getPermanentFilter(), game, target.getTargets());
|
||||||
} else {
|
} else {
|
||||||
targets = threats(randomOpponentId, source == null ? null : source.getSourceId(), origTarget.getPermanentFilter(), game, target.getTargets());
|
targets = threats(randomOpponentId, source, origTarget.getPermanentFilter(), game, target.getTargets());
|
||||||
}
|
}
|
||||||
if (targets.isEmpty() && required) {
|
if (targets.isEmpty() && required) {
|
||||||
targets = threats(null, source == null ? null : source.getSourceId(), origTarget.getPermanentFilter(), game, target.getTargets());
|
targets = threats(null, source, origTarget.getPermanentFilter(), game, target.getTargets());
|
||||||
Collections.reverse(targets);
|
Collections.reverse(targets);
|
||||||
outcomeTargets = false;
|
outcomeTargets = false;
|
||||||
}
|
}
|
||||||
|
@ -1008,7 +1009,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Card> cards = new ArrayList<>();
|
List<Card> cards = new ArrayList<>();
|
||||||
for (UUID uuid : target.possibleTargets(source.getSourceId(), source.getControllerId(), game)) {
|
for (UUID uuid : target.possibleTargets(source.getControllerId(), source, game)) {
|
||||||
Card card = game.getCard(uuid);
|
Card card = game.getCard(uuid);
|
||||||
if (card != null && game.getState().getZone(card.getId()) == Zone.EXILED) {
|
if (card != null && game.getState().getZone(card.getId()) == Zone.EXILED) {
|
||||||
cards.add(card);
|
cards.add(card);
|
||||||
|
@ -1026,7 +1027,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
||||||
|
|
||||||
if (target.getOriginalTarget() instanceof TargetActivatedAbility) {
|
if (target.getOriginalTarget() instanceof TargetActivatedAbility) {
|
||||||
List<StackObject> stackObjects = new ArrayList<>();
|
List<StackObject> stackObjects = new ArrayList<>();
|
||||||
for (UUID uuid : target.possibleTargets(source.getSourceId(), source.getControllerId(), game)) {
|
for (UUID uuid : target.possibleTargets(source.getControllerId(), source, game)) {
|
||||||
StackObject stackObject = game.getStack().getStackObject(uuid);
|
StackObject stackObject = game.getStack().getStackObject(uuid);
|
||||||
if (stackObject != null) {
|
if (stackObject != null) {
|
||||||
stackObjects.add(stackObject);
|
stackObjects.add(stackObject);
|
||||||
|
@ -1129,7 +1130,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
||||||
|
|
||||||
// permanents kill
|
// permanents kill
|
||||||
for (UUID opponentId : opponents) {
|
for (UUID opponentId : opponents) {
|
||||||
targets = threats(opponentId, sourceId, StaticFilters.FILTER_PERMANENT_CREATURE_OR_PLANESWALKER_A, game, target.getTargets());
|
targets = threats(opponentId, source, StaticFilters.FILTER_PERMANENT_CREATURE_OR_PLANESWALKER_A, game, target.getTargets());
|
||||||
|
|
||||||
// planeswalker kill
|
// planeswalker kill
|
||||||
for (Permanent permanent : targets) {
|
for (Permanent permanent : targets) {
|
||||||
|
@ -1156,9 +1157,9 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
||||||
// own permanents will be checked multiple times... that's ok
|
// own permanents will be checked multiple times... that's ok
|
||||||
for (UUID opponentId : opponents) {
|
for (UUID opponentId : opponents) {
|
||||||
if (outcome.isGood()) {
|
if (outcome.isGood()) {
|
||||||
targets = threats(getId(), sourceId, StaticFilters.FILTER_PERMANENT, game, target.getTargets());
|
targets = threats(getId(), source, StaticFilters.FILTER_PERMANENT, game, target.getTargets());
|
||||||
} else {
|
} else {
|
||||||
targets = threats(opponentId, sourceId, StaticFilters.FILTER_PERMANENT, game, target.getTargets());
|
targets = threats(opponentId, source, StaticFilters.FILTER_PERMANENT, game, target.getTargets());
|
||||||
}
|
}
|
||||||
|
|
||||||
// planeswalkers
|
// planeswalkers
|
||||||
|
@ -1192,9 +1193,9 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
||||||
for (UUID opponentId : opponents) {
|
for (UUID opponentId : opponents) {
|
||||||
if (!outcome.isGood()) {
|
if (!outcome.isGood()) {
|
||||||
// bad on yourself, uses weakest targets
|
// bad on yourself, uses weakest targets
|
||||||
targets = threats(getId(), sourceId, StaticFilters.FILTER_PERMANENT, game, target.getTargets(), false);
|
targets = threats(getId(), source, StaticFilters.FILTER_PERMANENT, game, target.getTargets(), false);
|
||||||
} else {
|
} else {
|
||||||
targets = threats(opponentId, sourceId, StaticFilters.FILTER_PERMANENT, game, target.getTargets(), false);
|
targets = threats(opponentId, source, StaticFilters.FILTER_PERMANENT, game, target.getTargets(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// creatures - non killable (TODO: add extra skill checks like undestructeable)
|
// creatures - non killable (TODO: add extra skill checks like undestructeable)
|
||||||
|
@ -1989,7 +1990,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
||||||
}
|
}
|
||||||
|
|
||||||
// we still use playerId when getting cards even if they don't control the search
|
// we still use playerId when getting cards even if they don't control the search
|
||||||
List<Card> cardChoices = new ArrayList<>(cards.getCards(target.getFilter(), source != null ? source.getSourceId() : null, playerId, game));
|
List<Card> cardChoices = new ArrayList<>(cards.getCards(target.getFilter(), playerId, source, game));
|
||||||
while (!target.doneChosing()) {
|
while (!target.doneChosing()) {
|
||||||
Card card = pickTarget(abilityControllerId, cardChoices, outcome, target, source, game);
|
Card card = pickTarget(abilityControllerId, cardChoices, outcome, target, source, game);
|
||||||
if (card != null) {
|
if (card != null) {
|
||||||
|
@ -2109,7 +2110,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
||||||
continue AvailableMode;
|
continue AvailableMode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mode.getTargets().canChoose(source.getSourceId(), source.getControllerId(), game)) { // and where targets are available
|
if (mode.getTargets().canChoose(source.getControllerId(), source, game)) { // and where targets are available
|
||||||
return mode;
|
return mode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2694,7 +2695,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
||||||
return worst;
|
return worst;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void findBestPermanentTargets(Outcome outcome, UUID abilityControllerId, UUID sourceId, FilterPermanent filter, Game game, Target target,
|
protected void findBestPermanentTargets(Outcome outcome, UUID abilityControllerId, UUID sourceId, Ability source, FilterPermanent filter, Game game, Target target,
|
||||||
List<Permanent> goodList, List<Permanent> badList, List<Permanent> allList) {
|
List<Permanent> goodList, List<Permanent> badList, List<Permanent> allList) {
|
||||||
// searching for most valuable/powerfull permanents
|
// searching for most valuable/powerfull permanents
|
||||||
goodList.clear();
|
goodList.clear();
|
||||||
|
@ -2703,7 +2704,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
||||||
List<UUID> usedTargets = target.getTargets();
|
List<UUID> usedTargets = target.getTargets();
|
||||||
|
|
||||||
// search all
|
// search all
|
||||||
for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, abilityControllerId, sourceId, game)) {
|
for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, abilityControllerId, source, game)) {
|
||||||
if (usedTargets.contains(permanent.getId())) {
|
if (usedTargets.contains(permanent.getId())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -2751,19 +2752,19 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected List<Permanent> threats(UUID playerId, UUID sourceId, FilterPermanent filter, Game game, List<UUID> targets) {
|
protected List<Permanent> threats(UUID playerId, Ability source, FilterPermanent filter, Game game, List<UUID> targets) {
|
||||||
return threats(playerId, sourceId, filter, game, targets, true);
|
return threats(playerId, source, filter, game, targets, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected List<Permanent> threats(UUID playerId, UUID sourceId, FilterPermanent filter, Game game, List<UUID> targets, boolean mostValueableGoFirst) {
|
protected List<Permanent> threats(UUID playerId, Ability source, FilterPermanent filter, Game game, List<UUID> targets, boolean mostValueableGoFirst) {
|
||||||
// most valuable/powerfull permanents goes at first
|
// most valuable/powerfull permanents goes at first
|
||||||
List<Permanent> threats;
|
List<Permanent> threats;
|
||||||
if (playerId == null) {
|
if (playerId == null) {
|
||||||
threats = game.getBattlefield().getActivePermanents(filter, this.getId(), sourceId, game); // all permanents within the range of the player
|
threats = game.getBattlefield().getActivePermanents(filter, this.getId(), source, game); // all permanents within the range of the player
|
||||||
} else {
|
} else {
|
||||||
FilterPermanent filterCopy = filter.copy();
|
FilterPermanent filterCopy = filter.copy();
|
||||||
filterCopy.add(new ControllerIdPredicate(playerId));
|
filterCopy.add(new ControllerIdPredicate(playerId));
|
||||||
threats = game.getBattlefield().getActivePermanents(filter, this.getId(), sourceId, game);
|
threats = game.getBattlefield().getActivePermanents(filter, this.getId(), source, game);
|
||||||
}
|
}
|
||||||
Iterator<Permanent> it = threats.iterator();
|
Iterator<Permanent> it = threats.iterator();
|
||||||
while (it.hasNext()) { // remove permanents already targeted
|
while (it.hasNext()) { // remove permanents already targeted
|
||||||
|
@ -2881,7 +2882,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
||||||
*
|
*
|
||||||
* @param source null on choose and non-null on chooseTarget
|
* @param source null on choose and non-null on chooseTarget
|
||||||
*/
|
*/
|
||||||
private boolean setTargetPlayer(Outcome outcome, Target target, Ability source, UUID sourceId, UUID abilityControllerId, UUID randomOpponentId, Game game, boolean required) {
|
private boolean setTargetPlayer(Outcome outcome, Target target, Ability source, UUID abilityControllerId, UUID randomOpponentId, Game game, boolean required) {
|
||||||
Outcome affectedOutcome;
|
Outcome affectedOutcome;
|
||||||
if (abilityControllerId == this.playerId) {
|
if (abilityControllerId == this.playerId) {
|
||||||
// selects for itself
|
// selects for itself
|
||||||
|
@ -2915,6 +2916,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UUID sourceId = source != null ? source.getSourceId() : null;
|
||||||
if (target.getOriginalTarget() instanceof TargetPlayer) {
|
if (target.getOriginalTarget() instanceof TargetPlayer) {
|
||||||
if (affectedOutcome.isGood()) {
|
if (affectedOutcome.isGood()) {
|
||||||
if (source == null) {
|
if (source == null) {
|
||||||
|
|
|
@ -221,7 +221,7 @@ public class SimulatedPlayerMCTS extends MCTSPlayer {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean chooseRandomTarget(Target target, Ability source, Game game) {
|
protected boolean chooseRandomTarget(Target target, Ability source, Game game) {
|
||||||
Set<UUID> possibleTargets = target.possibleTargets(source == null ? null : source.getSourceId(), playerId, game);
|
Set<UUID> possibleTargets = target.possibleTargets(playerId, source, game);
|
||||||
if (possibleTargets.isEmpty()) {
|
if (possibleTargets.isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -245,19 +245,19 @@ public class SimulatedPlayerMCTS extends MCTSPlayer {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean choose(Outcome outcome, Target target, UUID sourceId, Game game) {
|
public boolean choose(Outcome outcome, Target target, Ability source, Game game) {
|
||||||
if (this.isHuman()) {
|
if (this.isHuman()) {
|
||||||
return chooseRandom(target, game);
|
return chooseRandom(target, game);
|
||||||
}
|
}
|
||||||
return super.choose(outcome, target, sourceId, game);
|
return super.choose(outcome, target, source, game);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean choose(Outcome outcome, Target target, UUID sourceId, Game game, Map<String, Serializable> options) {
|
public boolean choose(Outcome outcome, Target target, Ability source, Game game, Map<String, Serializable> options) {
|
||||||
if (this.isHuman()) {
|
if (this.isHuman()) {
|
||||||
return chooseRandom(target, game);
|
return chooseRandom(target, game);
|
||||||
}
|
}
|
||||||
return super.choose(outcome, target, sourceId, game, options);
|
return super.choose(outcome, target, source, game, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -302,7 +302,7 @@ public class SimulatedPlayerMCTS extends MCTSPlayer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean chooseTargetAmount(Outcome outcome, TargetAmount target, Ability source, Game game) {
|
public boolean chooseTargetAmount(Outcome outcome, TargetAmount target, Ability source, Game game) {
|
||||||
Set<UUID> possibleTargets = target.possibleTargets(source == null ? null : source.getSourceId(), playerId, game);
|
Set<UUID> possibleTargets = target.possibleTargets(playerId, source, game);
|
||||||
if (possibleTargets.isEmpty()) {
|
if (possibleTargets.isEmpty()) {
|
||||||
return !target.isRequired(source);
|
return !target.isRequired(source);
|
||||||
}
|
}
|
||||||
|
|
|
@ -235,7 +235,7 @@ public class ComputerPlayer2 extends ComputerPlayer implements Player {
|
||||||
if (effect != null && ability.getControllerId().equals(playerId)) {
|
if (effect != null && ability.getControllerId().equals(playerId)) {
|
||||||
Target target = effect.getTarget();
|
Target target = effect.getTarget();
|
||||||
if (!target.doneChosing()) {
|
if (!target.doneChosing()) {
|
||||||
for (UUID targetId: target.possibleTargets(ability.getSourceId(), ability.getControllerId(), game)) {
|
for (UUID targetId: target.possibleTargets(ability.getControllerId(), ability.getStackAbility(), game)) {
|
||||||
Game sim = game.copy();
|
Game sim = game.copy();
|
||||||
StackAbility newAbility = (StackAbility) ability.copy();
|
StackAbility newAbility = (StackAbility) ability.copy();
|
||||||
SearchEffect newEffect = getSearchEffect((StackAbility) newAbility);
|
SearchEffect newEffect = getSearchEffect((StackAbility) newAbility);
|
||||||
|
|
|
@ -498,12 +498,12 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean choose(Outcome outcome, Target target, UUID sourceId, Game game) {
|
public boolean choose(Outcome outcome, Target target, Ability source, Game game) {
|
||||||
return choose(outcome, target, sourceId, game, null);
|
return choose(outcome, target, source, game, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean choose(Outcome outcome, Target target, UUID sourceId, Game game, Map<String, Serializable> options) {
|
public boolean choose(Outcome outcome, Target target, Ability source, Game game, Map<String, Serializable> options) {
|
||||||
if (gameInCheckPlayableState(game)) {
|
if (gameInCheckPlayableState(game)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -519,12 +519,12 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
while (canRespond()) {
|
while (canRespond()) {
|
||||||
Set<UUID> targetIds = target.possibleTargets(sourceId, abilityControllerId, game);
|
Set<UUID> targetIds = target.possibleTargets(abilityControllerId, source, game);
|
||||||
if (targetIds == null || targetIds.isEmpty()) {
|
if (targetIds == null || targetIds.isEmpty()) {
|
||||||
return target.getTargets().size() >= target.getNumberOfTargets();
|
return target.getTargets().size() >= target.getNumberOfTargets();
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean required = target.isRequired(sourceId, game);
|
boolean required = target.isRequired(source != null ? source.getSourceId() : null, game);
|
||||||
if (target.getTargets().size() >= target.getNumberOfTargets()) {
|
if (target.getTargets().size() >= target.getNumberOfTargets()) {
|
||||||
required = false;
|
required = false;
|
||||||
}
|
}
|
||||||
|
@ -535,7 +535,7 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
updateGameStatePriority("choose(5)", game);
|
updateGameStatePriority("choose(5)", game);
|
||||||
prepareForResponse(game);
|
prepareForResponse(game);
|
||||||
if (!isExecutingMacro()) {
|
if (!isExecutingMacro()) {
|
||||||
game.fireSelectTargetEvent(getId(), new MessageToClient(target.getMessage(), getRelatedObjectName(sourceId, game)), targetIds, required, getOptions(target, options));
|
game.fireSelectTargetEvent(getId(), new MessageToClient(target.getMessage(), getRelatedObjectName(source.getSourceId(), game)), targetIds, required, getOptions(target, options));
|
||||||
}
|
}
|
||||||
waitForResponse(game);
|
waitForResponse(game);
|
||||||
|
|
||||||
|
@ -554,14 +554,14 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target instanceof TargetPermanent) {
|
if (target instanceof TargetPermanent) {
|
||||||
if (((TargetPermanent) target).canTarget(abilityControllerId, responseId, sourceId, game, false)) {
|
if (((TargetPermanent) target).canTarget(abilityControllerId, responseId, source, game, false)) {
|
||||||
target.add(responseId, game);
|
target.add(responseId, game);
|
||||||
if (target.doneChosing()) {
|
if (target.doneChosing()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
MageObject object = game.getObject(sourceId);
|
MageObject object = game.getObject(source);
|
||||||
if (object instanceof Ability) {
|
if (object instanceof Ability) {
|
||||||
if (target.canTarget(responseId, (Ability) object, game)) {
|
if (target.canTarget(responseId, (Ability) object, game)) {
|
||||||
if (target.getTargets().contains(responseId)) { // if already included remove it with
|
if (target.getTargets().contains(responseId)) { // if already included remove it with
|
||||||
|
@ -617,7 +617,7 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
Map<String, Serializable> options = new HashMap<>();
|
Map<String, Serializable> options = new HashMap<>();
|
||||||
|
|
||||||
while (canRespond()) {
|
while (canRespond()) {
|
||||||
Set<UUID> possibleTargets = target.possibleTargets(source == null ? null : source.getSourceId(), abilityControllerId, game);
|
Set<UUID> possibleTargets = target.possibleTargets(abilityControllerId, source, game);
|
||||||
boolean required = target.isRequired(source != null ? source.getSourceId() : null, game);
|
boolean required = target.isRequired(source != null ? source.getSourceId() : null, game);
|
||||||
if (possibleTargets.isEmpty()
|
if (possibleTargets.isEmpty()
|
||||||
|| target.getTargets().size() >= target.getNumberOfTargets()) {
|
|| target.getTargets().size() >= target.getNumberOfTargets()) {
|
||||||
|
@ -845,7 +845,7 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
|
|
||||||
// 1. Select targets
|
// 1. Select targets
|
||||||
while (canRespond()) {
|
while (canRespond()) {
|
||||||
Set<UUID> possibleTargets = target.possibleTargets(source == null ? null : source.getSourceId(), abilityControllerId, game);
|
Set<UUID> possibleTargets = target.possibleTargets(abilityControllerId, source, game);
|
||||||
boolean required = target.isRequired(source != null ? source.getSourceId() : null, game);
|
boolean required = target.isRequired(source != null ? source.getSourceId() : null, game);
|
||||||
if (possibleTargets.isEmpty()
|
if (possibleTargets.isEmpty()
|
||||||
|| target.getSize() >= target.getNumberOfTargets()) {
|
|| target.getSize() >= target.getNumberOfTargets()) {
|
||||||
|
@ -979,7 +979,7 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
FilterCreatureForCombatBlock filter = filterCreatureForCombatBlock.copy();
|
FilterCreatureForCombatBlock filter = filterCreatureForCombatBlock.copy();
|
||||||
filter.add(new ControllerIdPredicate(playerId));
|
filter.add(new ControllerIdPredicate(playerId));
|
||||||
// stop skip on any/zero permanents available
|
// stop skip on any/zero permanents available
|
||||||
int possibleBlockersCount = game.getBattlefield().count(filter, null, playerId, game);
|
int possibleBlockersCount = game.getBattlefield().count(filter, playerId, null, game);
|
||||||
boolean canStopOnAny = possibleBlockersCount != 0 && getControllingPlayersUserData(game).getUserSkipPrioritySteps().isStopOnDeclareBlockersWithAnyPermanents();
|
boolean canStopOnAny = possibleBlockersCount != 0 && getControllingPlayersUserData(game).getUserSkipPrioritySteps().isStopOnDeclareBlockersWithAnyPermanents();
|
||||||
boolean canStopOnZero = possibleBlockersCount == 0 && getControllingPlayersUserData(game).getUserSkipPrioritySteps().isStopOnDeclareBlockersWithZeroPermanents();
|
boolean canStopOnZero = possibleBlockersCount == 0 && getControllingPlayersUserData(game).getUserSkipPrioritySteps().isStopOnDeclareBlockersWithZeroPermanents();
|
||||||
quickStop = canStopOnAny || canStopOnZero;
|
quickStop = canStopOnAny || canStopOnZero;
|
||||||
|
@ -1605,9 +1605,9 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
} else if (responseId != null) {
|
} else if (responseId != null) {
|
||||||
Permanent attacker = game.getPermanent(responseId);
|
Permanent attacker = game.getPermanent(responseId);
|
||||||
if (attacker != null) {
|
if (attacker != null) {
|
||||||
if (filterCreatureForCombat.match(attacker, null, playerId, game)) {
|
if (filterCreatureForCombat.match(attacker, playerId, null, game)) {
|
||||||
selectDefender(game.getCombat().getDefenders(), attacker.getId(), game);
|
selectDefender(game.getCombat().getDefenders(), attacker.getId(), game);
|
||||||
} else if (filterAttack.match(attacker, null, playerId, game) && game.getStack().isEmpty()) {
|
} else if (filterAttack.match(attacker, playerId, null, game) && game.getStack().isEmpty()) {
|
||||||
removeAttackerIfPossible(game, attacker);
|
removeAttackerIfPossible(game, attacker);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1772,7 +1772,7 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
filter.add(new ControllerIdPredicate(defendingPlayerId));
|
filter.add(new ControllerIdPredicate(defendingPlayerId));
|
||||||
|
|
||||||
// stop skip on any/zero permanents available
|
// stop skip on any/zero permanents available
|
||||||
int possibleBlockersCount = game.getBattlefield().count(filter, null, playerId, game);
|
int possibleBlockersCount = game.getBattlefield().count(filter, playerId, source, game);
|
||||||
boolean canStopOnAny = possibleBlockersCount != 0 && getControllingPlayersUserData(game).getUserSkipPrioritySteps().isStopOnDeclareBlockersWithAnyPermanents();
|
boolean canStopOnAny = possibleBlockersCount != 0 && getControllingPlayersUserData(game).getUserSkipPrioritySteps().isStopOnDeclareBlockersWithAnyPermanents();
|
||||||
boolean canStopOnZero = possibleBlockersCount == 0 && getControllingPlayersUserData(game).getUserSkipPrioritySteps().isStopOnDeclareBlockersWithZeroPermanents();
|
boolean canStopOnZero = possibleBlockersCount == 0 && getControllingPlayersUserData(game).getUserSkipPrioritySteps().isStopOnDeclareBlockersWithZeroPermanents();
|
||||||
|
|
||||||
|
@ -1810,9 +1810,9 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
if (blocker != null) {
|
if (blocker != null) {
|
||||||
boolean removeBlocker = false;
|
boolean removeBlocker = false;
|
||||||
// does not block yet and can block or can block more attackers
|
// does not block yet and can block or can block more attackers
|
||||||
if (filter.match(blocker, null, playerId, game)) {
|
if (filter.match(blocker, playerId, source, game)) {
|
||||||
selectCombatGroup(defendingPlayerId, blocker.getId(), game);
|
selectCombatGroup(defendingPlayerId, blocker.getId(), game);
|
||||||
} else if (filterBlock.match(blocker, null, playerId, game)
|
} else if (filterBlock.match(blocker, playerId, source, game)
|
||||||
&& game.getStack().isEmpty()) {
|
&& game.getStack().isEmpty()) {
|
||||||
removeBlocker = true;
|
removeBlocker = true;
|
||||||
}
|
}
|
||||||
|
@ -1892,7 +1892,7 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
prepareForResponse(game);
|
prepareForResponse(game);
|
||||||
if (!isExecutingMacro()) {
|
if (!isExecutingMacro()) {
|
||||||
// possible attackers to block
|
// possible attackers to block
|
||||||
Set<UUID> attackers = target.possibleTargets(null, playerId, game);
|
Set<UUID> attackers = target.possibleTargets(playerId, null, game);
|
||||||
Permanent blocker = game.getPermanent(blockerId);
|
Permanent blocker = game.getPermanent(blockerId);
|
||||||
Set<UUID> possibleTargets = new HashSet<>();
|
Set<UUID> possibleTargets = new HashSet<>();
|
||||||
for (UUID attackerId : attackers) {
|
for (UUID attackerId : attackers) {
|
||||||
|
@ -1932,7 +1932,7 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
if (singleTargetName != null) {
|
if (singleTargetName != null) {
|
||||||
target.setTargetName(singleTargetName);
|
target.setTargetName(singleTargetName);
|
||||||
}
|
}
|
||||||
choose(Outcome.Damage, target, source.getSourceId(), game);
|
choose(Outcome.Damage, target, source, game);
|
||||||
if (targets.isEmpty() || targets.contains(target.getFirstTarget())) {
|
if (targets.isEmpty() || targets.contains(target.getFirstTarget())) {
|
||||||
int damageAmount = getAmount(0, remainingDamage, "Select amount", game);
|
int damageAmount = getAmount(0, remainingDamage, "Select amount", game);
|
||||||
Permanent permanent = game.getPermanent(target.getFirstTarget());
|
Permanent permanent = game.getPermanent(target.getFirstTarget());
|
||||||
|
@ -2222,7 +2222,7 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
if (modes.size() > 1) {
|
if (modes.size() > 1) {
|
||||||
// done option for up to choices
|
// done option for up to choices
|
||||||
boolean canEndChoice = modes.getSelectedModes().size() >= modes.getMinModes() || modes.isMayChooseNone();
|
boolean canEndChoice = modes.getSelectedModes().size() >= modes.getMinModes() || modes.isMayChooseNone();
|
||||||
MageObject obj = game.getObject(source.getSourceId());
|
MageObject obj = game.getObject(source);
|
||||||
Map<UUID, String> modeMap = new LinkedHashMap<>();
|
Map<UUID, String> modeMap = new LinkedHashMap<>();
|
||||||
int modeIndex = 0;
|
int modeIndex = 0;
|
||||||
AvailableModes:
|
AvailableModes:
|
||||||
|
@ -2242,7 +2242,7 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mode.getTargets().canChoose(source.getSourceId(), source.getControllerId(), game)) { // and needed targets have to be available
|
if (mode.getTargets().canChoose(source.getControllerId(), source, game)) { // and needed targets have to be available
|
||||||
String modeText = mode.getEffects().getText(mode);
|
String modeText = mode.getEffects().getText(mode);
|
||||||
if (obj != null) {
|
if (obj != null) {
|
||||||
modeText = modeText.replace("{this}", obj.getName());
|
modeText = modeText.replace("{this}", obj.getName());
|
||||||
|
|
|
@ -68,7 +68,7 @@ class AbeyanceEffect extends ContinuousRuleModifyingEffectImpl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getInfoMessage(Ability source, GameEvent event, Game game) {
|
public String getInfoMessage(Ability source, GameEvent event, Game game) {
|
||||||
MageObject mageObject = game.getObject(source.getSourceId());
|
MageObject mageObject = game.getObject(source);
|
||||||
if (mageObject != null) {
|
if (mageObject != null) {
|
||||||
return "You can't cast instant or sorcery spells or activate abilities "
|
return "You can't cast instant or sorcery spells or activate abilities "
|
||||||
+ "that aren't mana abilities this turn (" + mageObject.getIdName() + ").";
|
+ "that aren't mana abilities this turn (" + mageObject.getIdName() + ").";
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
|
|
||||||
package mage.cards.a;
|
package mage.cards.a;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.common.DiesSourceTriggeredAbility;
|
import mage.abilities.common.DiesSourceTriggeredAbility;
|
||||||
import mage.abilities.effects.common.DestroyAllEffect;
|
import mage.abilities.effects.common.DestroyAllEffect;
|
||||||
|
@ -9,28 +7,31 @@ import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.SubType;
|
import mage.constants.SubType;
|
||||||
|
import mage.filter.FilterPermanent;
|
||||||
import mage.filter.common.FilterCreaturePermanent;
|
import mage.filter.common.FilterCreaturePermanent;
|
||||||
import mage.filter.predicate.Predicates;
|
import mage.filter.predicate.permanent.BlockingOrBlockedBySourcePredicate;
|
||||||
import mage.filter.predicate.permanent.BlockedByIdPredicate;
|
|
||||||
import mage.filter.predicate.permanent.BlockingAttackerIdPredicate;
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author MarcoMarin
|
* @author MarcoMarin
|
||||||
*/
|
*/
|
||||||
public final class AbuJafar extends CardImpl {
|
public final class AbuJafar extends CardImpl {
|
||||||
|
|
||||||
|
private static final FilterPermanent filter
|
||||||
|
= new FilterCreaturePermanent("creatures blocking or blocked by it");
|
||||||
|
|
||||||
|
static {
|
||||||
|
filter.add(BlockingOrBlockedBySourcePredicate.EITHER);
|
||||||
|
}
|
||||||
|
|
||||||
public AbuJafar(UUID ownerId, CardSetInfo setInfo) {
|
public AbuJafar(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{W}");
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}");
|
||||||
this.subtype.add(SubType.HUMAN);
|
this.subtype.add(SubType.HUMAN);
|
||||||
this.power = new MageInt(0);
|
this.power = new MageInt(0);
|
||||||
this.toughness = new MageInt(1);
|
this.toughness = new MageInt(1);
|
||||||
|
|
||||||
FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures blocking or blocked by it");
|
// When Abu Ja'far dies, destroy all creatures blocking or blocked by it. They can't be regenerated.
|
||||||
filter.add(Predicates.or(new BlockedByIdPredicate(this.getId()),
|
|
||||||
new BlockingAttackerIdPredicate(this.getId())));
|
|
||||||
|
|
||||||
// When Abu Ja'far dies, destroy all creatures blocking or blocked by it. They can't be regenerated.
|
|
||||||
this.addAbility(new DiesSourceTriggeredAbility(new DestroyAllEffect(filter, true), false));
|
this.addAbility(new DiesSourceTriggeredAbility(new DestroyAllEffect(filter, true), false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,7 @@ class AbundanceReplacementEffect extends ReplacementEffectImpl {
|
||||||
@Override
|
@Override
|
||||||
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
|
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
|
||||||
Player controller = game.getPlayer(event.getPlayerId());
|
Player controller = game.getPlayer(event.getPlayerId());
|
||||||
MageObject sourceObject = game.getObject(source.getSourceId());
|
MageObject sourceObject = game.getObject(source);
|
||||||
if (controller != null && sourceObject != null) {
|
if (controller != null && sourceObject != null) {
|
||||||
FilterCard filter = new FilterCard();
|
FilterCard filter = new FilterCard();
|
||||||
if (controller.chooseUse(Outcome.Detriment, "Choose card type:",
|
if (controller.chooseUse(Outcome.Detriment, "Choose card type:",
|
||||||
|
@ -79,7 +79,7 @@ class AbundanceReplacementEffect extends ReplacementEffectImpl {
|
||||||
Card selectedCard = null;
|
Card selectedCard = null;
|
||||||
for (Card card : controller.getLibrary().getCards(game)) {
|
for (Card card : controller.getLibrary().getCards(game)) {
|
||||||
toReveal.add(card);
|
toReveal.add(card);
|
||||||
if (filter.match(card, source.getSourceId(), source.getControllerId(), game)) {
|
if (filter.match(card, source.getControllerId(), source, game)) {
|
||||||
selectedCard = card;
|
selectedCard = card;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,7 +73,7 @@ class AcademyResearchersEffect extends OneShotEffect {
|
||||||
if (controller != null && academyResearchers != null) {
|
if (controller != null && academyResearchers != null) {
|
||||||
filterCardInHand.add(new AuraCardCanAttachToPermanentId(academyResearchers.getId()));
|
filterCardInHand.add(new AuraCardCanAttachToPermanentId(academyResearchers.getId()));
|
||||||
TargetCardInHand target = new TargetCardInHand(0, 1, filterCardInHand);
|
TargetCardInHand target = new TargetCardInHand(0, 1, filterCardInHand);
|
||||||
if (controller.choose(Outcome.PutCardInPlay, target, source.getSourceId(), game)) {
|
if (controller.choose(Outcome.PutCardInPlay, target, source, game)) {
|
||||||
Card auraInHand = game.getCard(target.getFirstTarget());
|
Card auraInHand = game.getCard(target.getFirstTarget());
|
||||||
if (auraInHand != null) {
|
if (auraInHand != null) {
|
||||||
game.getState().setValue("attachTo:" + auraInHand.getId(), academyResearchers);
|
game.getState().setValue("attachTo:" + auraInHand.getId(), academyResearchers);
|
||||||
|
|
|
@ -103,7 +103,7 @@ class AcererakTheArchlichEffect extends OneShotEffect {
|
||||||
}
|
}
|
||||||
TargetPermanent target = new TargetControlledCreaturePermanent(0, 1);
|
TargetPermanent target = new TargetControlledCreaturePermanent(0, 1);
|
||||||
target.setNotTarget(true);
|
target.setNotTarget(true);
|
||||||
player.choose(Outcome.Sacrifice, target, source.getSourceId(), game);
|
player.choose(Outcome.Sacrifice, target, source, game);
|
||||||
Permanent permanent = game.getPermanent(target.getFirstTarget());
|
Permanent permanent = game.getPermanent(target.getFirstTarget());
|
||||||
if (permanent != null && permanent.sacrifice(source, game)) {
|
if (permanent != null && permanent.sacrifice(source, game)) {
|
||||||
tokens--;
|
tokens--;
|
||||||
|
|
|
@ -50,7 +50,7 @@ class AcidicSoilEffect extends OneShotEffect {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
List<Permanent> permanents = game.getBattlefield().getActivePermanents(StaticFilters.FILTER_LAND, source.getControllerId(), source.getSourceId(), game);
|
List<Permanent> permanents = game.getBattlefield().getActivePermanents(StaticFilters.FILTER_LAND, source.getControllerId(), source, game);
|
||||||
for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) {
|
for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) {
|
||||||
Player player = game.getPlayer(playerId);
|
Player player = game.getPlayer(playerId);
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
|
|
|
@ -73,7 +73,7 @@ class AcolyteOfAfflictionEffect extends OneShotEffect {
|
||||||
}
|
}
|
||||||
player.moveCards(player.getLibrary().getTopCards(game, 2), Zone.GRAVEYARD, source, game);
|
player.moveCards(player.getLibrary().getTopCards(game, 2), Zone.GRAVEYARD, source, game);
|
||||||
TargetCard target = new TargetCardInYourGraveyard(0, 1, filter, true);
|
TargetCard target = new TargetCardInYourGraveyard(0, 1, filter, true);
|
||||||
if (!player.choose(Outcome.ReturnToHand, target, source.getSourceId(), game)) {
|
if (!player.choose(Outcome.ReturnToHand, target, source, game)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
Card card = game.getCard(target.getFirstTarget());
|
Card card = game.getCard(target.getFirstTarget());
|
||||||
|
|
|
@ -63,7 +63,7 @@ class AdviceFromTheFaeEffect extends OneShotEffect {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
Player controller = game.getPlayer(source.getControllerId());
|
Player controller = game.getPlayer(source.getControllerId());
|
||||||
MageObject mageObject = game.getObject(source.getSourceId());
|
MageObject mageObject = game.getObject(source);
|
||||||
if (controller != null && mageObject != null) {
|
if (controller != null && mageObject != null) {
|
||||||
Set<Card> topCards = controller.getLibrary().getTopCards(game, 5);
|
Set<Card> topCards = controller.getLibrary().getTopCards(game, 5);
|
||||||
Cards cardsFromLibrary = new CardsImpl();
|
Cards cardsFromLibrary = new CardsImpl();
|
||||||
|
|
|
@ -79,10 +79,10 @@ enum AerialSurveyorCondition implements Condition {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
return game.getBattlefield().count(
|
return game.getBattlefield().count(
|
||||||
filter, source.getSourceId(), source.getControllerId(), game
|
filter, source.getControllerId(), source, game
|
||||||
) > game.getBattlefield().count(
|
) > game.getBattlefield().count(
|
||||||
StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND,
|
StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND,
|
||||||
source.getSourceId(), source.getControllerId(), game
|
source.getControllerId(), source, game
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,7 +96,7 @@ enum AerialSurveyorHint implements Hint {
|
||||||
.getActivePermanents(
|
.getActivePermanents(
|
||||||
StaticFilters.FILTER_LAND,
|
StaticFilters.FILTER_LAND,
|
||||||
ability.getControllerId(),
|
ability.getControllerId(),
|
||||||
ability.getSourceId(), game
|
ability, game
|
||||||
).stream()
|
).stream()
|
||||||
.map(Controllable::getControllerId)
|
.map(Controllable::getControllerId)
|
||||||
.filter(game.getOpponents(ability.getControllerId())::contains)
|
.filter(game.getOpponents(ability.getControllerId())::contains)
|
||||||
|
|
|
@ -90,7 +90,7 @@ class AetherVialEffect extends OneShotEffect {
|
||||||
}
|
}
|
||||||
|
|
||||||
TargetCardInHand target = new TargetCardInHand(filter);
|
TargetCardInHand target = new TargetCardInHand(filter);
|
||||||
if (controller.choose(this.outcome, target, source.getSourceId(), game)) {
|
if (controller.choose(this.outcome, target, source, game)) {
|
||||||
Card card = game.getCard(target.getFirstTarget());
|
Card card = game.getCard(target.getFirstTarget());
|
||||||
if (card != null) {
|
if (card != null) {
|
||||||
return controller.moveCards(card, Zone.BATTLEFIELD, source, game);
|
return controller.moveCards(card, Zone.BATTLEFIELD, source, game);
|
||||||
|
|
|
@ -78,12 +78,12 @@ class AetherbornMarauderEffect extends OneShotEffect {
|
||||||
filter.add(AnotherPredicate.instance);
|
filter.add(AnotherPredicate.instance);
|
||||||
filter.add(CounterType.P1P1.getPredicate());
|
filter.add(CounterType.P1P1.getPredicate());
|
||||||
boolean firstRun = true;
|
boolean firstRun = true;
|
||||||
while (game.getBattlefield().count(filter, source.getSourceId(), source.getControllerId(), game) > 0) {
|
while (game.getBattlefield().count(filter, source.getControllerId(), source, game) > 0) {
|
||||||
if (controller.chooseUse(outcome, "Move " + (firstRun ? "any" : "more") + " +1/+1 counters from other permanents you control to " + sourceObject.getLogName() + '?', source, game)) {
|
if (controller.chooseUse(outcome, "Move " + (firstRun ? "any" : "more") + " +1/+1 counters from other permanents you control to " + sourceObject.getLogName() + '?', source, game)) {
|
||||||
firstRun = false;
|
firstRun = false;
|
||||||
TargetControlledPermanent target = new TargetControlledPermanent(filter);
|
TargetControlledPermanent target = new TargetControlledPermanent(filter);
|
||||||
target.setNotTarget(true);
|
target.setNotTarget(true);
|
||||||
if (target.choose(Outcome.Neutral, source.getControllerId(), source.getSourceId(), game)) {
|
if (target.choose(Outcome.Neutral, source.getControllerId(), source.getSourceId(), source, game)) {
|
||||||
Permanent fromPermanent = game.getPermanent(target.getFirstTarget());
|
Permanent fromPermanent = game.getPermanent(target.getFirstTarget());
|
||||||
if (fromPermanent != null) {
|
if (fromPermanent != null) {
|
||||||
int numberOfCounters = fromPermanent.getCounters(game).getCount(CounterType.P1P1);
|
int numberOfCounters = fromPermanent.getCounters(game).getCount(CounterType.P1P1);
|
||||||
|
|
|
@ -60,7 +60,7 @@ class AethermagesTouchEffect extends OneShotEffect {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
Player controller = game.getPlayer(source.getControllerId());
|
Player controller = game.getPlayer(source.getControllerId());
|
||||||
MageObject sourceObject = game.getObject(source.getSourceId());
|
MageObject sourceObject = game.getObject(source);
|
||||||
if (controller != null && sourceObject != null) {
|
if (controller != null && sourceObject != null) {
|
||||||
Cards cards = new CardsImpl(controller.getLibrary().getTopCards(game, 4));
|
Cards cards = new CardsImpl(controller.getLibrary().getTopCards(game, 4));
|
||||||
if (!cards.isEmpty()) {
|
if (!cards.isEmpty()) {
|
||||||
|
|
|
@ -67,7 +67,7 @@ class AetherplasmEffect extends OneShotEffect {
|
||||||
}
|
}
|
||||||
if (player.chooseUse(Outcome.PutCardInPlay, "Put a creature card from your hand onto the battlefield?", source, game)) {
|
if (player.chooseUse(Outcome.PutCardInPlay, "Put a creature card from your hand onto the battlefield?", source, game)) {
|
||||||
TargetCardInHand target = new TargetCardInHand(StaticFilters.FILTER_CARD_CREATURE_A);
|
TargetCardInHand target = new TargetCardInHand(StaticFilters.FILTER_CARD_CREATURE_A);
|
||||||
if (player.choose(Outcome.PutCardInPlay, target, source.getSourceId(), game)) {
|
if (player.choose(Outcome.PutCardInPlay, target, source, game)) {
|
||||||
Card card = game.getCard(target.getFirstTarget());
|
Card card = game.getCard(target.getFirstTarget());
|
||||||
if (card != null) {
|
if (card != null) {
|
||||||
Permanent blockedCreature = game.getPermanent(getTargetPointer().getFirst(game, source));
|
Permanent blockedCreature = game.getPermanent(getTargetPointer().getFirst(game, source));
|
||||||
|
|
|
@ -81,7 +81,7 @@ class AetherspoutsEffect extends OneShotEffect {
|
||||||
do {
|
do {
|
||||||
List<Permanent> permanentsToTop = new ArrayList<>();
|
List<Permanent> permanentsToTop = new ArrayList<>();
|
||||||
List<Permanent> permanentsToBottom = new ArrayList<>();
|
List<Permanent> permanentsToBottom = new ArrayList<>();
|
||||||
for (Permanent permanent : game.getState().getBattlefield().getActivePermanents(new FilterAttackingCreature(), player.getId(), source.getSourceId(), game)) {
|
for (Permanent permanent : game.getState().getBattlefield().getActivePermanents(new FilterAttackingCreature(), player.getId(), source, game)) {
|
||||||
if (permanent.isOwnedBy(player.getId())) {
|
if (permanent.isOwnedBy(player.getId())) {
|
||||||
if (player.chooseUse(outcome, "Put " + permanent.getLogName() + " to the top? (else it goes to bottom)", source, game)) {
|
if (player.chooseUse(outcome, "Put " + permanent.getLogName() + " to the top? (else it goes to bottom)", source, game)) {
|
||||||
permanentsToTop.add(permanent);
|
permanentsToTop.add(permanent);
|
||||||
|
|
|
@ -81,8 +81,8 @@ class AgadeemOccultistEffect extends OneShotEffect {
|
||||||
TargetCardInOpponentsGraveyard target = new TargetCardInOpponentsGraveyard(1, 1, filter);
|
TargetCardInOpponentsGraveyard target = new TargetCardInOpponentsGraveyard(1, 1, filter);
|
||||||
|
|
||||||
if (controller != null) {
|
if (controller != null) {
|
||||||
if (target.canChoose(source.getSourceId(), source.getControllerId(), game)
|
if (target.canChoose(source.getControllerId(), source, game)
|
||||||
&& controller.choose(Outcome.GainControl, target, source.getSourceId(), game)) {
|
&& controller.choose(Outcome.GainControl, target, source, game)) {
|
||||||
if (!target.getTargets().isEmpty()) {
|
if (!target.getTargets().isEmpty()) {
|
||||||
Card card = game.getCard(target.getFirstTarget());
|
Card card = game.getCard(target.getFirstTarget());
|
||||||
if (card != null) {
|
if (card != null) {
|
||||||
|
|
|
@ -100,8 +100,8 @@ class AgadeemsAwakeningTarget extends TargetCardInYourGraveyard {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<UUID> possibleTargets(UUID sourceId, UUID sourceControllerId, Game game) {
|
public Set<UUID> possibleTargets(UUID sourceControllerId, Ability source, Game game) {
|
||||||
Set<UUID> possibleTargets = super.possibleTargets(sourceId, sourceControllerId, game);
|
Set<UUID> possibleTargets = super.possibleTargets(sourceControllerId, source, game);
|
||||||
Set<Integer> cmcs = this.getTargets()
|
Set<Integer> cmcs = this.getTargets()
|
||||||
.stream()
|
.stream()
|
||||||
.map(game::getCard)
|
.map(game::getCard)
|
||||||
|
|
|
@ -86,7 +86,7 @@ class AgitatorAntEffect extends OneShotEffect {
|
||||||
}
|
}
|
||||||
TargetPermanent targetPermanent = new TargetControlledCreaturePermanent(0, 1);
|
TargetPermanent targetPermanent = new TargetControlledCreaturePermanent(0, 1);
|
||||||
targetPermanent.setNotTarget(true);
|
targetPermanent.setNotTarget(true);
|
||||||
player.choose(Outcome.BoostCreature, targetPermanent, source.getSourceId(), game);
|
player.choose(Outcome.BoostCreature, targetPermanent, source, game);
|
||||||
Permanent permanent = game.getPermanent(targetPermanent.getFirstTarget());
|
Permanent permanent = game.getPermanent(targetPermanent.getFirstTarget());
|
||||||
if (permanent == null || !permanent.addCounters(CounterType.P1P1.createInstance(2), player.getId(), source, game)) {
|
if (permanent == null || !permanent.addCounters(CounterType.P1P1.createInstance(2), player.getId(), source, game)) {
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -65,7 +65,7 @@ class AidFromTheCowlEffect extends OneShotEffect {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
Player controller = game.getPlayer(source.getControllerId());
|
Player controller = game.getPlayer(source.getControllerId());
|
||||||
MageObject sourceObject = game.getObject(source.getSourceId());
|
MageObject sourceObject = game.getObject(source);
|
||||||
if (controller == null || sourceObject == null) {
|
if (controller == null || sourceObject == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -142,11 +142,11 @@ class AkiriFearlessVoyagerEffect extends OneShotEffect {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
TargetPermanent target = new TargetPermanent(1, 1, filter, true);
|
TargetPermanent target = new TargetPermanent(1, 1, filter, true);
|
||||||
if (!target.canChoose(source.getSourceId(), source.getControllerId(), game)
|
if (!target.canChoose(source.getControllerId(), source, game)
|
||||||
|| !player.chooseUse(outcome, "Unnattach an equipment from a creature you control?", source, game)) {
|
|| !player.chooseUse(outcome, "Unnattach an equipment from a creature you control?", source, game)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
player.choose(outcome, target, source.getSourceId(), game);
|
player.choose(outcome, target, source, game);
|
||||||
Permanent equipment = game.getPermanent(target.getFirstTarget());
|
Permanent equipment = game.getPermanent(target.getFirstTarget());
|
||||||
if (equipment == null) {
|
if (equipment == null) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -104,7 +104,7 @@ class AkromaVisionOfIxidorEffect extends OneShotEffect {
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
for (Permanent permanent : game.getBattlefield().getActivePermanents(
|
for (Permanent permanent : game.getBattlefield().getActivePermanents(
|
||||||
StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE,
|
StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE,
|
||||||
source.getControllerId(), source.getSourceId(), game
|
source.getControllerId(), source, game
|
||||||
)) {
|
)) {
|
||||||
Abilities<Ability> abilities = permanent.getAbilities(game);
|
Abilities<Ability> abilities = permanent.getAbilities(game);
|
||||||
int count = classes
|
int count = classes
|
||||||
|
|
|
@ -138,7 +138,7 @@ class AlhammarretHighArbiterCantCastEffect extends ContinuousRuleModifyingEffect
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getInfoMessage(Ability source, GameEvent event, Game game) {
|
public String getInfoMessage(Ability source, GameEvent event, Game game) {
|
||||||
MageObject mageObject = game.getObject(source.getSourceId());
|
MageObject mageObject = game.getObject(source);
|
||||||
if (mageObject != null) {
|
if (mageObject != null) {
|
||||||
return "You may not cast a card named " + cardName + " (" + mageObject.getIdName() + ").";
|
return "You may not cast a card named " + cardName + " (" + mageObject.getIdName() + ").";
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,7 +91,7 @@ class AlibouAncientWitnessEffect extends OneShotEffect {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
int xValue = game.getBattlefield().count(filter, source.getSourceId(), source.getControllerId(), game);
|
int xValue = game.getBattlefield().count(filter, source.getControllerId(), source, game);
|
||||||
if (xValue < 1) {
|
if (xValue < 1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,7 +77,7 @@ class AlignedHedronNetworkExileEffect extends OneShotEffect {
|
||||||
|
|
||||||
// If Whale leaves the battlefield before its triggered ability resolves,
|
// If Whale leaves the battlefield before its triggered ability resolves,
|
||||||
// the target creature won't be exiled.
|
// the target creature won't be exiled.
|
||||||
Set<Card> toExile = new LinkedHashSet<>(game.getBattlefield().getActivePermanents(filter, controller.getId(), source.getSourceId(), game));
|
Set<Card> toExile = new LinkedHashSet<>(game.getBattlefield().getActivePermanents(filter, controller.getId(), source, game));
|
||||||
if (toExile.isEmpty()) { return false; }
|
if (toExile.isEmpty()) { return false; }
|
||||||
|
|
||||||
controller.moveCardsToExile(toExile, source, game, true, CardUtil.getCardExileZoneId(game, source), permanent.getIdName());
|
controller.moveCardsToExile(toExile, source, game, true, CardUtil.getCardExileZoneId(game, source), permanent.getIdName());
|
||||||
|
|
|
@ -66,7 +66,7 @@ class WellEffect extends OneShotEffect {
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
Player player = game.getPlayer(source.getControllerId());
|
Player player = game.getPlayer(source.getControllerId());
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
int life = 2 * game.getBattlefield().count(filter, source.getSourceId(), source.getControllerId(), game);
|
int life = 2 * game.getBattlefield().count(filter, source.getControllerId(), source, game);
|
||||||
player.gainLife(life, game, source);
|
player.gainLife(life, game, source);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -69,7 +69,7 @@ class AllureOfTheUnknownEffect extends OneShotEffect {
|
||||||
return player.moveCards(cards, Zone.HAND, source, game);
|
return player.moveCards(cards, Zone.HAND, source, game);
|
||||||
}
|
}
|
||||||
TargetOpponent targetOpponent = new TargetOpponent(true);
|
TargetOpponent targetOpponent = new TargetOpponent(true);
|
||||||
if (!player.choose(outcome, targetOpponent, source.getSourceId(), game)) {
|
if (!player.choose(outcome, targetOpponent, source, game)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Player opponent = game.getPlayer(targetOpponent.getFirstTarget());
|
Player opponent = game.getPlayer(targetOpponent.getFirstTarget());
|
||||||
|
|
|
@ -105,7 +105,7 @@ class AminatouPlusEffect extends OneShotEffect {
|
||||||
|
|
||||||
private boolean putOnLibrary(Player player, Ability source, Game game) {
|
private boolean putOnLibrary(Player player, Ability source, Game game) {
|
||||||
TargetCardInHand target = new TargetCardInHand();
|
TargetCardInHand target = new TargetCardInHand();
|
||||||
if (target.canChoose(source.getSourceId(), player.getId(), game)) {
|
if (target.canChoose(player.getId(), source, game)) {
|
||||||
player.chooseTarget(Outcome.ReturnToHand, target, source, game);
|
player.chooseTarget(Outcome.ReturnToHand, target, source, game);
|
||||||
Card card = player.getHand().get(target.getFirstTarget(), game);
|
Card card = player.getHand().get(target.getFirstTarget(), game);
|
||||||
if (card != null) {
|
if (card != null) {
|
||||||
|
|
|
@ -82,7 +82,7 @@ class AmuletOfSafekeepingTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
public boolean checkTrigger(GameEvent event, Game game) {
|
public boolean checkTrigger(GameEvent event, Game game) {
|
||||||
StackObject stackObject = game.getStack().getStackObject(event.getSourceId());
|
StackObject stackObject = game.getStack().getStackObject(event.getSourceId());
|
||||||
if (event.getTargetId().equals(getControllerId())
|
if (event.getTargetId().equals(getControllerId())
|
||||||
&& filter.match(stackObject, getSourceId(), getControllerId(), game)) {
|
&& filter.match(stackObject, getControllerId(), this, game)) {
|
||||||
for (Effect effect : this.getEffects()) {
|
for (Effect effect : this.getEffects()) {
|
||||||
effect.setTargetPointer(new FixedTarget(stackObject.getId(), game));
|
effect.setTargetPointer(new FixedTarget(stackObject.getId(), game));
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,7 +68,7 @@ class AnHavvaConstableEffect extends ContinuousEffectImpl {
|
||||||
|
|
||||||
FilterCreaturePermanent filter = new FilterCreaturePermanent("green creatures");
|
FilterCreaturePermanent filter = new FilterCreaturePermanent("green creatures");
|
||||||
filter.add(new ColorPredicate(ObjectColor.GREEN));
|
filter.add(new ColorPredicate(ObjectColor.GREEN));
|
||||||
int numberOfGreenCreatures = game.getBattlefield().count(filter, source.getSourceId(), source.getControllerId(), game);
|
int numberOfGreenCreatures = game.getBattlefield().count(filter, source.getSourceId(), source, game);
|
||||||
|
|
||||||
mageObject.getToughness().setValue(1 + numberOfGreenCreatures);
|
mageObject.getToughness().setValue(1 + numberOfGreenCreatures);
|
||||||
|
|
||||||
|
|
|
@ -59,7 +59,7 @@ class AnHavvaInnEffect extends OneShotEffect {
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
FilterCreaturePermanent filter = new FilterCreaturePermanent("green creatures");
|
FilterCreaturePermanent filter = new FilterCreaturePermanent("green creatures");
|
||||||
filter.add(new ColorPredicate(ObjectColor.GREEN));
|
filter.add(new ColorPredicate(ObjectColor.GREEN));
|
||||||
int greenCreatures = game.getBattlefield().count(filter, source.getSourceId(), source.getControllerId(), game);
|
int greenCreatures = game.getBattlefield().count(filter, source.getControllerId(), source, game);
|
||||||
player.gainLife(greenCreatures+1, game, source);
|
player.gainLife(greenCreatures+1, game, source);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -63,8 +63,8 @@ enum AnathemancerCount implements DynamicValue {
|
||||||
}
|
}
|
||||||
return game.getBattlefield().count(
|
return game.getBattlefield().count(
|
||||||
StaticFilters.FILTER_LANDS_NONBASIC,
|
StaticFilters.FILTER_LANDS_NONBASIC,
|
||||||
sourceAbility.getFirstTarget(),
|
sourceAbility.getControllerId(),
|
||||||
sourceAbility.getControllerId(), game
|
sourceAbility, game
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@ class AngelOfGlorysRiseEffect extends OneShotEffect {
|
||||||
Player controller = game.getPlayer(source.getControllerId());
|
Player controller = game.getPlayer(source.getControllerId());
|
||||||
if (controller != null) {
|
if (controller != null) {
|
||||||
Set<Card> toExile = new HashSet<>(game.getBattlefield()
|
Set<Card> toExile = new HashSet<>(game.getBattlefield()
|
||||||
.getActivePermanents(new FilterCreaturePermanent(SubType.ZOMBIE, "Zombie"), source.getControllerId(), source.getSourceId(), game));
|
.getActivePermanents(new FilterCreaturePermanent(SubType.ZOMBIE, "Zombie"), source.getControllerId(), source, game));
|
||||||
controller.moveCards(toExile, Zone.EXILED, source, game);
|
controller.moveCards(toExile, Zone.EXILED, source, game);
|
||||||
FilterCreatureCard filterHuman = new FilterCreatureCard();
|
FilterCreatureCard filterHuman = new FilterCreatureCard();
|
||||||
filterHuman.add(SubType.HUMAN.getPredicate());
|
filterHuman.add(SubType.HUMAN.getPredicate());
|
||||||
|
|
|
@ -57,7 +57,7 @@ class AnimalMagnetismEffect extends OneShotEffect {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
Player controller = game.getPlayer(source.getControllerId());
|
Player controller = game.getPlayer(source.getControllerId());
|
||||||
MageObject sourceObject = game.getObject(source.getSourceId());
|
MageObject sourceObject = game.getObject(source);
|
||||||
if (sourceObject != null && controller != null) {
|
if (sourceObject != null && controller != null) {
|
||||||
Cards cards = new CardsImpl(controller.getLibrary().getTopCards(game, 5));
|
Cards cards = new CardsImpl(controller.getLibrary().getTopCards(game, 5));
|
||||||
if (!cards.isEmpty()) {
|
if (!cards.isEmpty()) {
|
||||||
|
|
|
@ -56,7 +56,7 @@ class AnimistsAwakeningEffect extends OneShotEffect {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
Player controller = game.getPlayer(source.getControllerId());
|
Player controller = game.getPlayer(source.getControllerId());
|
||||||
MageObject sourceObject = game.getObject(source.getSourceId());
|
MageObject sourceObject = game.getObject(source);
|
||||||
if (controller == null || sourceObject == null) {
|
if (controller == null || sourceObject == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,7 @@ class AnimistsAwakeningEffect extends OneShotEffect {
|
||||||
if (!cards.isEmpty()) {
|
if (!cards.isEmpty()) {
|
||||||
controller.revealCards(sourceObject.getIdName(), cards, game);
|
controller.revealCards(sourceObject.getIdName(), cards, game);
|
||||||
Set<Card> toBattlefield = new LinkedHashSet<>();
|
Set<Card> toBattlefield = new LinkedHashSet<>();
|
||||||
for (Card card : cards.getCards(new FilterLandCard(), source.getSourceId(), source.getControllerId(), game)) {
|
for (Card card : cards.getCards(new FilterLandCard(), source.getControllerId(), source, game)) {
|
||||||
cards.remove(card);
|
cards.remove(card);
|
||||||
toBattlefield.add(card);
|
toBattlefield.add(card);
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,7 +69,7 @@ class AnuridScavengerCost extends CostImpl {
|
||||||
public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) {
|
public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) {
|
||||||
Player controller = game.getPlayer(controllerId);
|
Player controller = game.getPlayer(controllerId);
|
||||||
if (controller != null) {
|
if (controller != null) {
|
||||||
if (targets.choose(Outcome.Removal, controllerId, source.getSourceId(), game)) {
|
if (targets.choose(Outcome.Removal, controllerId, source.getSourceId(), source, game)) {
|
||||||
for (UUID targetId: targets.get(0).getTargets()) {
|
for (UUID targetId: targets.get(0).getTargets()) {
|
||||||
Card card = game.getCard(targetId);
|
Card card = game.getCard(targetId);
|
||||||
if (card == null || game.getState().getZone(targetId) != Zone.GRAVEYARD) {
|
if (card == null || game.getState().getZone(targetId) != Zone.GRAVEYARD) {
|
||||||
|
@ -85,7 +85,7 @@ class AnuridScavengerCost extends CostImpl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) {
|
public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) {
|
||||||
return targets.canChoose(source.getSourceId(), controllerId, game);
|
return targets.canChoose(controllerId, source, game);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -82,7 +82,7 @@ class ArashinWarBeastTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
((DamagedEvent) event).isCombatDamage() &&
|
((DamagedEvent) event).isCombatDamage() &&
|
||||||
!usedForCombatDamageStep) {
|
!usedForCombatDamageStep) {
|
||||||
Permanent creature = game.getPermanentOrLKIBattlefield(event.getTargetId());
|
Permanent creature = game.getPermanentOrLKIBattlefield(event.getTargetId());
|
||||||
if (creature == null || !filter.match(creature, getSourceId(), getControllerId(), game)) {
|
if (creature == null || !filter.match(creature, getControllerId(), this, game)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// trigger only once per combat damage step
|
// trigger only once per combat damage step
|
||||||
|
|
|
@ -96,7 +96,7 @@ class AraumiOfTheDeadTideCost extends CostImpl {
|
||||||
int oppCount = game.getOpponents(controllerId).size();
|
int oppCount = game.getOpponents(controllerId).size();
|
||||||
TargetCard target = new TargetCardInYourGraveyard(oppCount, StaticFilters.FILTER_CARD);
|
TargetCard target = new TargetCardInYourGraveyard(oppCount, StaticFilters.FILTER_CARD);
|
||||||
target.setNotTarget(true);
|
target.setNotTarget(true);
|
||||||
player.choose(Outcome.Exile, target, source.getSourceId(), game);
|
player.choose(Outcome.Exile, target, source, game);
|
||||||
Cards cards = new CardsImpl(target.getTargets());
|
Cards cards = new CardsImpl(target.getTargets());
|
||||||
if (cards.size() < oppCount) {
|
if (cards.size() < oppCount) {
|
||||||
return paid;
|
return paid;
|
||||||
|
|
|
@ -130,7 +130,7 @@ class ArcbondEffect extends OneShotEffect {
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
int damage = (Integer) this.getValue("damage");
|
int damage = (Integer) this.getValue("damage");
|
||||||
UUID sourceId = (UUID) this.getValue("sourceId");
|
UUID sourceId = (UUID) this.getValue("sourceId");
|
||||||
MageObject sourceObject = game.getObject(source.getSourceId());
|
MageObject sourceObject = game.getObject(source);
|
||||||
if (sourceObject != null && damage > 0 && sourceId != null) {
|
if (sourceObject != null && damage > 0 && sourceId != null) {
|
||||||
Permanent targetObject = game.getPermanentOrLKIBattlefield(sourceId);
|
Permanent targetObject = game.getPermanentOrLKIBattlefield(sourceId);
|
||||||
if (targetObject != null) {
|
if (targetObject != null) {
|
||||||
|
|
|
@ -72,10 +72,10 @@ enum ArchaeomancersMapCondition implements Condition {
|
||||||
UUID playerId = (UUID) source.getEffects().get(0).getValue("permanentEnteringControllerId");
|
UUID playerId = (UUID) source.getEffects().get(0).getValue("permanentEnteringControllerId");
|
||||||
return playerId != null && game.getBattlefield().count(
|
return playerId != null && game.getBattlefield().count(
|
||||||
StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND,
|
StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND,
|
||||||
source.getSourceId(), playerId, game
|
playerId, source, game
|
||||||
) > game.getBattlefield().count(
|
) > game.getBattlefield().count(
|
||||||
StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND,
|
StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND,
|
||||||
source.getSourceId(), source.getControllerId(), game
|
source.getControllerId(), source, game
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,8 +84,8 @@ public final class ArchdemonOfGreed extends CardImpl {
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
TargetControlledPermanent target = new TargetControlledPermanent(1, 1, filter, false);
|
TargetControlledPermanent target = new TargetControlledPermanent(1, 1, filter, false);
|
||||||
// if they can pay the cost, then they must pay
|
// if they can pay the cost, then they must pay
|
||||||
if (target.canChoose(source.getSourceId(), player.getId(), game)) {
|
if (target.canChoose(player.getId(), source, game)) {
|
||||||
player.choose(Outcome.Sacrifice, target, source.getSourceId(), game);
|
player.choose(Outcome.Sacrifice, target, source, game);
|
||||||
Permanent humanSacrifice = game.getPermanent(target.getFirstTarget());
|
Permanent humanSacrifice = game.getPermanent(target.getFirstTarget());
|
||||||
if (humanSacrifice != null) {
|
if (humanSacrifice != null) {
|
||||||
// sacrifice the chosen card
|
// sacrifice the chosen card
|
||||||
|
|
|
@ -73,7 +73,7 @@ class ArchfiendOfDepravityEffect extends OneShotEffect {
|
||||||
List<Permanent> creaturesToSacrifice = new ArrayList<>();
|
List<Permanent> creaturesToSacrifice = new ArrayList<>();
|
||||||
TargetControlledPermanent target = new TargetControlledPermanent(0, 2, new FilterControlledCreaturePermanent("creatures to keep"), true);
|
TargetControlledPermanent target = new TargetControlledPermanent(0, 2, new FilterControlledCreaturePermanent("creatures to keep"), true);
|
||||||
if (opponent.chooseTarget(outcome, target, source, game)) {
|
if (opponent.chooseTarget(outcome, target, source, game)) {
|
||||||
for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterControlledCreaturePermanent(), opponent.getId(), source.getSourceId(), game)) {
|
for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterControlledCreaturePermanent(), opponent.getId(), source, game)) {
|
||||||
if (permanent != null && !target.getTargets().contains(permanent.getId())) {
|
if (permanent != null && !target.getTargets().contains(permanent.getId())) {
|
||||||
creaturesToSacrifice.add(permanent);
|
creaturesToSacrifice.add(permanent);
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,6 +68,6 @@ enum ArcticFoxesCondition implements Condition {
|
||||||
if (defenderId == null) {
|
if (defenderId == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return game.getBattlefield().contains(filter, source.getSourceId(), defenderId, game, 1);
|
return game.getBattlefield().contains(filter, source.getSourceId(), defenderId, source, game, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -88,7 +88,7 @@ class ArdennIntrepidArchaeologistEffect extends OneShotEffect {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
TargetPermanent target = new TargetPermanent(0, Integer.MAX_VALUE, filter, true);
|
TargetPermanent target = new TargetPermanent(0, Integer.MAX_VALUE, filter, true);
|
||||||
controller.choose(outcome, target, source.getSourceId(), game);
|
controller.choose(outcome, target, source, game);
|
||||||
for (UUID targetId : target.getTargets()) {
|
for (UUID targetId : target.getTargets()) {
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
player.addAttachment(targetId, source, game);
|
player.addAttachment(targetId, source, game);
|
||||||
|
|
|
@ -79,7 +79,7 @@ class ArdentDustspeakerCost extends CostImpl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) {
|
public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) {
|
||||||
return targets.canChoose(source.getSourceId(), controllerId, game);
|
return targets.canChoose(controllerId, source, game);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -108,12 +108,12 @@ class ArmedAndArmoredEquipEffect extends OneShotEffect {
|
||||||
if (!dwarves.isEmpty() && !equipment.isEmpty()) {
|
if (!dwarves.isEmpty() && !equipment.isEmpty()) {
|
||||||
TargetPermanent target = new TargetPermanent(0, 1, dwarfFilter, true);
|
TargetPermanent target = new TargetPermanent(0, 1, dwarfFilter, true);
|
||||||
target.withChooseHint("dwarf to be equipped");
|
target.withChooseHint("dwarf to be equipped");
|
||||||
controller.choose(outcome, target, source.getId(), game);
|
controller.choose(outcome, target, source, game);
|
||||||
Permanent dwarf = game.getPermanent(target.getFirstTarget());
|
Permanent dwarf = game.getPermanent(target.getFirstTarget());
|
||||||
if (dwarf != null) {
|
if (dwarf != null) {
|
||||||
target = new TargetPermanent(0, Integer.MAX_VALUE, equipmentFilter, true);
|
target = new TargetPermanent(0, Integer.MAX_VALUE, equipmentFilter, true);
|
||||||
target.withChooseHint("equip to " + dwarf.getLogName());
|
target.withChooseHint("equip to " + dwarf.getLogName());
|
||||||
controller.choose(outcome, target, source.getId(), game);
|
controller.choose(outcome, target, source, game);
|
||||||
for (UUID targetId : target.getTargets()) {
|
for (UUID targetId : target.getTargets()) {
|
||||||
dwarf.addAttachment(targetId, source, game);
|
dwarf.addAttachment(targetId, source, game);
|
||||||
game.informPlayers(game.getPermanent(targetId).getLogName() + " was attached to " + dwarf.getLogName());
|
game.informPlayers(game.getPermanent(targetId).getLogName() + " was attached to " + dwarf.getLogName());
|
||||||
|
|
|
@ -100,7 +100,7 @@ class ArmoredSkyhunterEffect extends OneShotEffect {
|
||||||
}
|
}
|
||||||
TargetPermanent targetPermanent = new TargetControlledCreaturePermanent(0, 1);
|
TargetPermanent targetPermanent = new TargetControlledCreaturePermanent(0, 1);
|
||||||
targetCard.setNotTarget(true);
|
targetCard.setNotTarget(true);
|
||||||
player.choose(outcome, targetPermanent, source.getSourceId(), game);
|
player.choose(outcome, targetPermanent, source, game);
|
||||||
Permanent permanent = game.getPermanent(targetPermanent.getFirstTarget());
|
Permanent permanent = game.getPermanent(targetPermanent.getFirstTarget());
|
||||||
if (permanent != null) {
|
if (permanent != null) {
|
||||||
permanent.addAttachment(equipment.getId(), source, game);
|
permanent.addAttachment(equipment.getId(), source, game);
|
||||||
|
|
|
@ -88,7 +88,7 @@ class ArmoryAutomatonEffect extends OneShotEffect {
|
||||||
while (player.canRespond() && countBattlefield > 0 && player.chooseUse(Outcome.Benefit, "Select and attach a target Equipment?", source, game)) {
|
while (player.canRespond() && countBattlefield > 0 && player.chooseUse(Outcome.Benefit, "Select and attach a target Equipment?", source, game)) {
|
||||||
Target targetEquipment = new TargetPermanent(currentFilter);
|
Target targetEquipment = new TargetPermanent(currentFilter);
|
||||||
targetEquipment.setRequired(false);
|
targetEquipment.setRequired(false);
|
||||||
if (player.choose(Outcome.Benefit, targetEquipment, source.getSourceId(), game) && targetEquipment.getFirstTarget() != null) {
|
if (player.choose(Outcome.Benefit, targetEquipment, source, game) && targetEquipment.getFirstTarget() != null) {
|
||||||
currentFilter.add(Predicates.not(new PermanentIdPredicate(targetEquipment.getFirstTarget()))); // exclude selected for next time
|
currentFilter.add(Predicates.not(new PermanentIdPredicate(targetEquipment.getFirstTarget()))); // exclude selected for next time
|
||||||
|
|
||||||
Permanent aura = game.getPermanent(targetEquipment.getFirstTarget());
|
Permanent aura = game.getPermanent(targetEquipment.getFirstTarget());
|
||||||
|
|
|
@ -69,7 +69,7 @@ class ArniBrokenbrowEffect extends OneShotEffect {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
Player controller = game.getPlayer(source.getControllerId());
|
Player controller = game.getPlayer(source.getControllerId());
|
||||||
MageObject mageObject = game.getObject(source.getSourceId());
|
MageObject mageObject = game.getObject(source);
|
||||||
if (controller == null || mageObject == null) {
|
if (controller == null || mageObject == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ import mage.constants.Outcome;
|
||||||
import mage.constants.SubType;
|
import mage.constants.SubType;
|
||||||
import mage.counters.CounterType;
|
import mage.counters.CounterType;
|
||||||
import mage.filter.common.FilterArtifactCard;
|
import mage.filter.common.FilterArtifactCard;
|
||||||
import mage.filter.predicate.mageobject.AnotherCardPredicate;
|
import mage.filter.predicate.mageobject.AnotherPredicate;
|
||||||
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;
|
||||||
|
@ -75,12 +75,12 @@ class ArsenalThresherEffect extends OneShotEffect {
|
||||||
}
|
}
|
||||||
Permanent arsenalThresher = game.getPermanentEntering(source.getSourceId());
|
Permanent arsenalThresher = game.getPermanentEntering(source.getSourceId());
|
||||||
FilterArtifactCard filter = new FilterArtifactCard();
|
FilterArtifactCard filter = new FilterArtifactCard();
|
||||||
filter.add(new AnotherCardPredicate());
|
filter.add(AnotherPredicate.instance);
|
||||||
if (controller.chooseUse(Outcome.Benefit, "Reveal other artifacts in your hand?", source, game)) {
|
if (controller.chooseUse(Outcome.Benefit, "Reveal other artifacts in your hand?", source, game)) {
|
||||||
Cards cards = new CardsImpl();
|
Cards cards = new CardsImpl();
|
||||||
if (controller.getHand().count(filter, source.getSourceId(), source.getControllerId(), game) > 0) {
|
if (controller.getHand().count(filter, source.getControllerId(), source, game) > 0) {
|
||||||
TargetCardInHand target = new TargetCardInHand(0, Integer.MAX_VALUE, filter);
|
TargetCardInHand target = new TargetCardInHand(0, Integer.MAX_VALUE, filter);
|
||||||
if (controller.choose(Outcome.Benefit, target, source.getSourceId(), game)) {
|
if (controller.choose(Outcome.Benefit, target, source, game)) {
|
||||||
for (UUID uuid : target.getTargets()) {
|
for (UUID uuid : target.getTargets()) {
|
||||||
cards.add(controller.getHand().get(uuid, game));
|
cards.add(controller.getHand().get(uuid, game));
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,7 +74,7 @@ class ArterialAlchemyEffect extends ContinuousEffectImpl {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
|
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
|
||||||
for (Permanent permanent : game.getBattlefield().getActivePermanents(
|
for (Permanent permanent : game.getBattlefield().getActivePermanents(
|
||||||
filter, source.getControllerId(), source.getSourceId(), game
|
filter, source.getControllerId(), source, game
|
||||||
)) {
|
)) {
|
||||||
switch (layer) {
|
switch (layer) {
|
||||||
case TypeChangingEffects_4:
|
case TypeChangingEffects_4:
|
||||||
|
|
|
@ -95,7 +95,7 @@ class AryelTapXTargetCost extends VariableCostImpl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMaxValue(Ability source, Game game) {
|
public int getMaxValue(Ability source, Game game) {
|
||||||
return game.getBattlefield().count(filter, source.getSourceId(), source.getControllerId(), game);
|
return game.getBattlefield().count(filter, source.getControllerId(), source, game);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -69,7 +69,7 @@ class SpellWithManaCostLessThanOrEqualToCondition implements Condition {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
MageObject object = game.getObject(source.getSourceId());
|
MageObject object = game.getObject(source);
|
||||||
return object != null
|
return object != null
|
||||||
&& !object.isLand(game)
|
&& !object.isLand(game)
|
||||||
&& object.getManaValue() <= counters;
|
&& object.getManaValue() <= counters;
|
||||||
|
|
|
@ -71,7 +71,7 @@ enum AscendantAcolyteValue implements DynamicValue {
|
||||||
.getActivePermanents(
|
.getActivePermanents(
|
||||||
StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE,
|
StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE,
|
||||||
sourceAbility.getControllerId(),
|
sourceAbility.getControllerId(),
|
||||||
sourceAbility.getSourceId(), game
|
sourceAbility, game
|
||||||
).stream()
|
).stream()
|
||||||
.mapToInt(permanent -> permanent.getCounters(game).getCount(CounterType.P1P1))
|
.mapToInt(permanent -> permanent.getCounters(game).getCount(CounterType.P1P1))
|
||||||
.sum();
|
.sum();
|
||||||
|
|
|
@ -87,10 +87,10 @@ class AscentOfTheWorthyEffect extends OneShotEffect {
|
||||||
}
|
}
|
||||||
TargetPermanent target = new TargetControlledCreaturePermanent();
|
TargetPermanent target = new TargetControlledCreaturePermanent();
|
||||||
target.setNotTarget(true);
|
target.setNotTarget(true);
|
||||||
if (!target.canChoose(source.getSourceId(), source.getControllerId(), game)) {
|
if (!target.canChoose(source.getControllerId(), source, game)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
player.choose(outcome, target, source.getControllerId(), game);
|
player.choose(outcome, target, source, game);
|
||||||
Permanent permanent = game.getPermanent(target.getFirstTarget());
|
Permanent permanent = game.getPermanent(target.getFirstTarget());
|
||||||
if (permanent == null) {
|
if (permanent == null) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -77,7 +77,7 @@ class AshayaSoulOfTheWildEffect extends ContinuousEffectImpl {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
for (Permanent permanent : game.getBattlefield().getActivePermanents(
|
for (Permanent permanent : game.getBattlefield().getActivePermanents(
|
||||||
filter, source.getControllerId(), source.getSourceId(), game
|
filter, source.getControllerId(), source, game
|
||||||
)) {
|
)) {
|
||||||
if (!permanent.isLand(game)) {
|
if (!permanent.isLand(game)) {
|
||||||
permanent.addCardType(game, CardType.LAND);
|
permanent.addCardType(game, CardType.LAND);
|
||||||
|
|
|
@ -73,7 +73,7 @@ class AshiokDreamRenderEffect extends ContinuousRuleModifyingEffectImpl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getInfoMessage(Ability source, GameEvent event, Game game) {
|
public String getInfoMessage(Ability source, GameEvent event, Game game) {
|
||||||
MageObject mageObject = game.getObject(source.getSourceId());
|
MageObject mageObject = game.getObject(source);
|
||||||
if (mageObject != null) {
|
if (mageObject != null) {
|
||||||
return "You can't search libraries (" + mageObject.getLogName() + " in play).";
|
return "You can't search libraries (" + mageObject.getLogName() + " in play).";
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,7 +120,7 @@ class AshiokNightmareWeaverPutIntoPlayEffect extends OneShotEffect {
|
||||||
|
|
||||||
Target target = new TargetCardInExile(filter, CardUtil.getExileZoneId(game, source));
|
Target target = new TargetCardInExile(filter, CardUtil.getExileZoneId(game, source));
|
||||||
|
|
||||||
if (!target.canChoose(source.getSourceId(), controller.getId(), game)) {
|
if (!target.canChoose(controller.getId(), source, game)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
controller.chooseTarget(Outcome.PutCreatureInPlay, target, source, game);
|
controller.chooseTarget(Outcome.PutCreatureInPlay, target, source, game);
|
||||||
|
|
|
@ -66,7 +66,7 @@ enum AspectOfWolfValue implements DynamicValue {
|
||||||
@Override
|
@Override
|
||||||
public int calculate(Game game, Ability sourceAbility, Effect effect) {
|
public int calculate(Game game, Ability sourceAbility, Effect effect) {
|
||||||
int forestCount = game.getBattlefield().count(
|
int forestCount = game.getBattlefield().count(
|
||||||
filter, sourceAbility.getSourceId(), sourceAbility.getControllerId(), game
|
filter, sourceAbility.getControllerId(), sourceAbility, game
|
||||||
);
|
);
|
||||||
return forestCount / 2 + (up ? forestCount % 2 : 0);
|
return forestCount / 2 + (up ? forestCount % 2 : 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,7 @@ class AssemblyHallEffect extends OneShotEffect {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
Player controller = game.getPlayer(source.getControllerId());
|
Player controller = game.getPlayer(source.getControllerId());
|
||||||
MageObject sourceObject = game.getObject(source.getSourceId());
|
MageObject sourceObject = game.getObject(source);
|
||||||
if (controller == null || controller.getHand().isEmpty() || sourceObject == null) {
|
if (controller == null || controller.getHand().isEmpty() || sourceObject == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,7 +82,7 @@ class AtarkaWorldRenderEffect extends TriggeredAbilityImpl {
|
||||||
public boolean checkTrigger(GameEvent event, Game game) {
|
public boolean checkTrigger(GameEvent event, Game game) {
|
||||||
Permanent attacker = game.getPermanent(event.getSourceId());
|
Permanent attacker = game.getPermanent(event.getSourceId());
|
||||||
if (attacker != null
|
if (attacker != null
|
||||||
&& filter.match(attacker, sourceId, controllerId, game)) {
|
&& filter.match(attacker, controllerId, this, game)) {
|
||||||
for (Effect effect : this.getEffects()) {
|
for (Effect effect : this.getEffects()) {
|
||||||
effect.setTargetPointer(new FixedTarget(attacker.getId(), game));
|
effect.setTargetPointer(new FixedTarget(attacker.getId(), game));
|
||||||
}
|
}
|
||||||
|
|
|
@ -144,7 +144,7 @@ class AthreosDiesCreatureTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
if (!zEvent.isDiesEvent()) {
|
if (!zEvent.isDiesEvent()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (zEvent.getTarget() == null || !filter.match(zEvent.getTarget(), sourceId, controllerId, game)) {
|
if (zEvent.getTarget() == null || !filter.match(zEvent.getTarget(), controllerId, this, game)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (Effect effect : this.getEffects()) {
|
for (Effect effect : this.getEffects()) {
|
||||||
|
|
|
@ -72,18 +72,18 @@ class AugurOfBolasEffect extends OneShotEffect {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
Player controller = game.getPlayer(source.getControllerId());
|
Player controller = game.getPlayer(source.getControllerId());
|
||||||
MageObject sourceObject = game.getObject(source.getSourceId());
|
MageObject sourceObject = game.getObject(source);
|
||||||
if (controller != null && sourceObject != null) {
|
if (controller != null && sourceObject != null) {
|
||||||
Cards topCards = new CardsImpl();
|
Cards topCards = new CardsImpl();
|
||||||
topCards.addAll(controller.getLibrary().getTopCards(game, 3));
|
topCards.addAll(controller.getLibrary().getTopCards(game, 3));
|
||||||
if (!topCards.isEmpty()) {
|
if (!topCards.isEmpty()) {
|
||||||
controller.lookAtCards(sourceObject.getIdName(), topCards, game);
|
controller.lookAtCards(sourceObject.getIdName(), topCards, game);
|
||||||
int number = topCards.count(new FilterInstantOrSorceryCard(), source.getSourceId(), source.getControllerId(), game);
|
int number = topCards.count(new FilterInstantOrSorceryCard(), source.getControllerId(), source, game);
|
||||||
if (number > 0) {
|
if (number > 0) {
|
||||||
if (controller.chooseUse(outcome, "Reveal an instant or sorcery card from the looked at cards and put it into your hand?", source, game)) {
|
if (controller.chooseUse(outcome, "Reveal an instant or sorcery card from the looked at cards and put it into your hand?", source, game)) {
|
||||||
Card card = null;
|
Card card = null;
|
||||||
if (number == 1) {
|
if (number == 1) {
|
||||||
Set<Card> cards = topCards.getCards(new FilterInstantOrSorceryCard(), source.getSourceId(), source.getControllerId(), game);
|
Set<Card> cards = topCards.getCards(new FilterInstantOrSorceryCard(), source.getControllerId(), source, game);
|
||||||
if (!cards.isEmpty()) {
|
if (!cards.isEmpty()) {
|
||||||
card = cards.iterator().next();
|
card = cards.iterator().next();
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,6 @@ import mage.filter.predicate.Predicates;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.events.DamagedPlayerEvent;
|
import mage.game.events.DamagedPlayerEvent;
|
||||||
import mage.game.events.GameEvent;
|
import mage.game.events.GameEvent;
|
||||||
import mage.game.events.GameEvent.EventType;
|
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -83,7 +82,7 @@ class AuntiesSnitchTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
public boolean checkTrigger(GameEvent event, Game game) {
|
public boolean checkTrigger(GameEvent event, Game game) {
|
||||||
DamagedPlayerEvent damageEvent = (DamagedPlayerEvent)event;
|
DamagedPlayerEvent damageEvent = (DamagedPlayerEvent)event;
|
||||||
Permanent p = game.getPermanent(event.getSourceId());
|
Permanent p = game.getPermanent(event.getSourceId());
|
||||||
return damageEvent.isCombatDamage() && filter.match(p, getSourceId(), getControllerId(), game);
|
return damageEvent.isCombatDamage() && filter.match(p, getControllerId(), this, game);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -54,7 +54,7 @@ public final class AuraBarbs extends CardImpl {
|
||||||
FilterPermanent filterEnchantments = new FilterPermanent();
|
FilterPermanent filterEnchantments = new FilterPermanent();
|
||||||
filterEnchantments.add(CardType.ENCHANTMENT.getPredicate());
|
filterEnchantments.add(CardType.ENCHANTMENT.getPredicate());
|
||||||
|
|
||||||
for (Permanent permanent : game.getBattlefield().getActivePermanents(filterEnchantments, source.getControllerId(), source.getSourceId(), game)) {
|
for (Permanent permanent : game.getBattlefield().getActivePermanents(filterEnchantments, source.getControllerId(), source, game)) {
|
||||||
Player controller = game.getPlayer(permanent.getControllerId());
|
Player controller = game.getPlayer(permanent.getControllerId());
|
||||||
if (controller != null) {
|
if (controller != null) {
|
||||||
controller.damage(2, permanent.getId(), source, game);
|
controller.damage(2, permanent.getId(), source, game);
|
||||||
|
@ -63,7 +63,7 @@ public final class AuraBarbs extends CardImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
filterEnchantments.add(SubType.AURA.getPredicate());
|
filterEnchantments.add(SubType.AURA.getPredicate());
|
||||||
for (Permanent auraEnchantment : game.getBattlefield().getActivePermanents(filterEnchantments, source.getControllerId(), source.getSourceId(), game)) {
|
for (Permanent auraEnchantment : game.getBattlefield().getActivePermanents(filterEnchantments, source.getControllerId(), source, game)) {
|
||||||
if (auraEnchantment.getAttachedTo() != null) {
|
if (auraEnchantment.getAttachedTo() != null) {
|
||||||
Permanent attachedToCreature = game.getPermanent(auraEnchantment.getAttachedTo());
|
Permanent attachedToCreature = game.getPermanent(auraEnchantment.getAttachedTo());
|
||||||
if (attachedToCreature != null && attachedToCreature.isCreature(game)) {
|
if (attachedToCreature != null && attachedToCreature.isCreature(game)) {
|
||||||
|
|
|
@ -123,8 +123,8 @@ class MoveTargetAuraEffect extends OneShotEffect {
|
||||||
filter.add(new PermanentCanBeAttachedToPredicate(enchantment));
|
filter.add(new PermanentCanBeAttachedToPredicate(enchantment));
|
||||||
Target target = new TargetPermanent(filter);
|
Target target = new TargetPermanent(filter);
|
||||||
target.setNotTarget(true);
|
target.setNotTarget(true);
|
||||||
if (target.canChoose(oldAttachment.getId(), controller.getId(), game)
|
if (target.canChoose(controller.getId(), source, game)
|
||||||
&& controller.choose(outcome, target, oldAttachment.getId(), game)) {
|
&& controller.choose(outcome, target, source, game)) {
|
||||||
Permanent newAttachment = game.getPermanent(target.getFirstTarget());
|
Permanent newAttachment = game.getPermanent(target.getFirstTarget());
|
||||||
if (newAttachment != null
|
if (newAttachment != null
|
||||||
&& oldAttachment.removeAttachment(enchantment.getId(), source, game)) {
|
&& oldAttachment.removeAttachment(enchantment.getId(), source, game)) {
|
||||||
|
|
|
@ -71,7 +71,7 @@ class AuraThiefDiesTriggeredEffect extends OneShotEffect {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
boolean ret = false;
|
boolean ret = false;
|
||||||
for(Permanent enchantment : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_ENCHANTMENT, source.getControllerId(), source.getControllerId(), game)) {
|
for(Permanent enchantment : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_ENCHANTMENT, source.getControllerId(), source, game)) {
|
||||||
ContinuousEffect gainControl = new GainControlTargetEffect(Duration.EndOfGame);
|
ContinuousEffect gainControl = new GainControlTargetEffect(Duration.EndOfGame);
|
||||||
gainControl.setTargetPointer(new FixedTarget(enchantment.getId(), game));
|
gainControl.setTargetPointer(new FixedTarget(enchantment.getId(), game));
|
||||||
game.addEffect(gainControl, source);
|
game.addEffect(gainControl, source);
|
||||||
|
|
|
@ -140,7 +140,7 @@ class AureliasFuryCantCastEffect extends ContinuousRuleModifyingEffectImpl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getInfoMessage(Ability source, GameEvent event, Game game) {
|
public String getInfoMessage(Ability source, GameEvent event, Game game) {
|
||||||
MageObject mageObject = game.getObject(source.getSourceId());
|
MageObject mageObject = game.getObject(source);
|
||||||
if (mageObject != null) {
|
if (mageObject != null) {
|
||||||
return "You can't cast noncreature spells this turn (you were dealt damage by " + mageObject.getLogName() + ')';
|
return "You can't cast noncreature spells this turn (you were dealt damage by " + mageObject.getLogName() + ')';
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,7 +111,7 @@ class SacrificeAllEffect extends OneShotEffect {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
List<Permanent> permanents = game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), source.getId(), game);
|
List<Permanent> permanents = game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), source, game);
|
||||||
for (Permanent p : permanents) {
|
for (Permanent p : permanents) {
|
||||||
p.sacrifice(source, game);
|
p.sacrifice(source, game);
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,7 +90,7 @@ class AvenShrineEffect extends OneShotEffect {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
MageObject mageObject = game.getObject(source.getSourceId());
|
MageObject mageObject = game.getObject(source);
|
||||||
if(mageObject != null) {
|
if(mageObject != null) {
|
||||||
Spell spell = (Spell) game.getState().getValue("avenShrine" + mageObject);
|
Spell spell = (Spell) game.getState().getValue("avenShrine" + mageObject);
|
||||||
if (spell != null) {
|
if (spell != null) {
|
||||||
|
|
|
@ -81,7 +81,7 @@ class AvenSoulgazerLookFaceDownEffect extends OneShotEffect {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
Player player = game.getPlayer(source.getControllerId());
|
Player player = game.getPlayer(source.getControllerId());
|
||||||
MageObject mageObject = game.getObject(source.getSourceId());
|
MageObject mageObject = game.getObject(source);
|
||||||
if (player == null || mageObject == null) {
|
if (player == null || mageObject == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,7 +113,7 @@ class AzorTheLawbringerCantCastEffect extends ContinuousRuleModifyingEffectImpl
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getInfoMessage(Ability source, GameEvent event, Game game) {
|
public String getInfoMessage(Ability source, GameEvent event, Game game) {
|
||||||
MageObject mageObject = game.getObject(source.getSourceId());
|
MageObject mageObject = game.getObject(source);
|
||||||
if (mageObject != null) {
|
if (mageObject != null) {
|
||||||
return "You can't cast instant or sorcery spells this turn (" + mageObject.getIdName() + ").";
|
return "You can't cast instant or sorcery spells this turn (" + mageObject.getIdName() + ").";
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,7 +80,7 @@ class AzoriusAEthermageAbility extends TriggeredAbilityImpl {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return StaticFilters.FILTER_PERMANENT_CREATURE.match(permanentThatMoved, sourceId, controllerId, game);
|
return StaticFilters.FILTER_PERMANENT_CREATURE.match(permanentThatMoved, controllerId, this, game);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -87,7 +87,7 @@ class AzorsGatewayEffect extends OneShotEffect {
|
||||||
|
|
||||||
controller.drawCards(1, source, game);
|
controller.drawCards(1, source, game);
|
||||||
TargetCardInHand target = new TargetCardInHand();
|
TargetCardInHand target = new TargetCardInHand();
|
||||||
controller.choose(outcome, target, source.getSourceId(), game);
|
controller.choose(outcome, target, source, game);
|
||||||
Card cardToExile = game.getCard(target.getFirstTarget());
|
Card cardToExile = game.getCard(target.getFirstTarget());
|
||||||
if (cardToExile != null) {
|
if (cardToExile != null) {
|
||||||
controller.moveCardsToExile(cardToExile, source, game, true, exileId, sourceObject.getIdName());
|
controller.moveCardsToExile(cardToExile, source, game, true, exileId, sourceObject.getIdName());
|
||||||
|
|
|
@ -75,7 +75,7 @@ class AzraBladeseekerEffect extends OneShotEffect {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Target target = new TargetDiscard(playerId);
|
Target target = new TargetDiscard(playerId);
|
||||||
if (target.choose(Outcome.DrawCard, playerId, source.getSourceId(), game)) {
|
if (target.choose(Outcome.DrawCard, playerId, source.getSourceId(), source, game)) {
|
||||||
Card card = game.getCard(target.getFirstTarget());
|
Card card = game.getCard(target.getFirstTarget());
|
||||||
if (card != null) {
|
if (card != null) {
|
||||||
playerCardList.add(new PlayerCard(player, card));
|
playerCardList.add(new PlayerCard(player, card));
|
||||||
|
|
|
@ -82,7 +82,7 @@ class AzraOddsmakerEffect extends OneShotEffect {
|
||||||
Permanent permanent = null;
|
Permanent permanent = null;
|
||||||
TargetCreaturePermanent target = new TargetCreaturePermanent();
|
TargetCreaturePermanent target = new TargetCreaturePermanent();
|
||||||
target.setNotTarget(true);
|
target.setNotTarget(true);
|
||||||
if (player.choose(Outcome.DrawCard, target, source.getSourceId(), game)) {
|
if (player.choose(Outcome.DrawCard, target, source, game)) {
|
||||||
permanent = game.getPermanent(target.getFirstTarget());
|
permanent = game.getPermanent(target.getFirstTarget());
|
||||||
}
|
}
|
||||||
if (permanent == null) {
|
if (permanent == null) {
|
||||||
|
|
|
@ -83,7 +83,7 @@ class BingoEffect extends OneShotEffect {
|
||||||
if (spell.getManaValue() > 9) {
|
if (spell.getManaValue() > 9) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
MageObject mageObject = game.getObject(source.getSourceId());
|
MageObject mageObject = game.getObject(source);
|
||||||
if (mageObject != null) {
|
if (mageObject != null) {
|
||||||
Map<Integer, Integer> chipCounters = new HashMap<>(); // Map<number, amount of counters>
|
Map<Integer, Integer> chipCounters = new HashMap<>(); // Map<number, amount of counters>
|
||||||
if (game.getState().getValue(mageObject.getId() + "_chip") != null) {
|
if (game.getState().getValue(mageObject.getId() + "_chip") != null) {
|
||||||
|
|
|
@ -67,12 +67,12 @@ class BackFromTheBrinkCost extends CostImpl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) {
|
public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) {
|
||||||
return targets.canChoose(source.getSourceId(), controllerId, game);
|
return targets.canChoose(controllerId, source, game);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) {
|
public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) {
|
||||||
if (targets.choose(Outcome.Exile, controllerId, source.getSourceId(), game)) {
|
if (targets.choose(Outcome.Exile, controllerId, source.getSourceId(), source, game)) {
|
||||||
Player controller = game.getPlayer(controllerId);
|
Player controller = game.getPlayer(controllerId);
|
||||||
if (controller != null) {
|
if (controller != null) {
|
||||||
Card card = controller.getGraveyard().get(targets.getFirstTarget(), game);
|
Card card = controller.getGraveyard().get(targets.getFirstTarget(), game);
|
||||||
|
|
|
@ -113,7 +113,7 @@ class BagOfDevouringEffect extends OneShotEffect {
|
||||||
CardUtil.getExileZoneId(game, source)
|
CardUtil.getExileZoneId(game, source)
|
||||||
);
|
);
|
||||||
target.setNotTarget(true);
|
target.setNotTarget(true);
|
||||||
player.choose(outcome, target, source.getSourceId(), game);
|
player.choose(outcome, target, source, game);
|
||||||
player.moveCards(new CardsImpl(target.getTargets()), Zone.HAND, source, game);
|
player.moveCards(new CardsImpl(target.getTargets()), Zone.HAND, source, game);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,7 @@ class BakisCurseEffect extends OneShotEffect {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
for (Permanent creature : game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), source.getControllerId(), source.getSourceId(), game)) {
|
for (Permanent creature : game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), source.getControllerId(), source, game)) {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
List<UUID> attachments = creature.getAttachments();
|
List<UUID> attachments = creature.getAttachments();
|
||||||
for (UUID attachmentId : attachments) {
|
for (UUID attachmentId : attachments) {
|
||||||
|
|
|
@ -64,7 +64,7 @@ class BalancingActEffect extends OneShotEffect {
|
||||||
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
|
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
|
||||||
Player player = game.getPlayer(playerId);
|
Player player = game.getPlayer(playerId);
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
int count = game.getBattlefield().getActivePermanents(new FilterControlledPermanent(), player.getId(), source.getSourceId(), game).size();
|
int count = game.getBattlefield().getActivePermanents(new FilterControlledPermanent(), player.getId(), source, game).size();
|
||||||
if (count < minPermanent) {
|
if (count < minPermanent) {
|
||||||
minPermanent = count;
|
minPermanent = count;
|
||||||
}
|
}
|
||||||
|
@ -75,8 +75,8 @@ class BalancingActEffect extends OneShotEffect {
|
||||||
Player player = game.getPlayer(playerId);
|
Player player = game.getPlayer(playerId);
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
TargetControlledPermanent target = new TargetControlledPermanent(minPermanent, minPermanent, new FilterControlledPermanent(), true);
|
TargetControlledPermanent target = new TargetControlledPermanent(minPermanent, minPermanent, new FilterControlledPermanent(), true);
|
||||||
if (target.choose(Outcome.Benefit, player.getId(), source.getSourceId(), game)) {
|
if (target.choose(Outcome.Benefit, player.getId(), source.getSourceId(), source, game)) {
|
||||||
for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterControlledPermanent(), player.getId(), source.getSourceId(), game)) {
|
for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterControlledPermanent(), player.getId(), source, game)) {
|
||||||
if (permanent != null && !target.getTargets().contains(permanent.getId())) {
|
if (permanent != null && !target.getTargets().contains(permanent.getId())) {
|
||||||
permanent.sacrifice(source, game);
|
permanent.sacrifice(source, game);
|
||||||
}
|
}
|
||||||
|
@ -101,7 +101,7 @@ class BalancingActEffect extends OneShotEffect {
|
||||||
Player player = game.getPlayer(playerId);
|
Player player = game.getPlayer(playerId);
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
TargetCardInHand target = new TargetCardInHand(minCard, new FilterCard());
|
TargetCardInHand target = new TargetCardInHand(minCard, new FilterCard());
|
||||||
if (target.choose(Outcome.Benefit, player.getId(), source.getSourceId(), game)) {
|
if (target.choose(Outcome.Benefit, player.getId(), source.getSourceId(), source, game)) {
|
||||||
Cards cards = player.getHand().copy();
|
Cards cards = player.getHand().copy();
|
||||||
cards.removeIf(target.getTargets()::contains);
|
cards.removeIf(target.getTargets()::contains);
|
||||||
player.discard(cards, false, source, game);
|
player.discard(cards, false, source, game);
|
||||||
|
|
|
@ -115,8 +115,8 @@ class BalduvianWarlordUnblockEffect extends OneShotEffect {
|
||||||
FilterAttackingCreature filter = new FilterAttackingCreature("creature attacking " + targetsController.getLogName());
|
FilterAttackingCreature filter = new FilterAttackingCreature("creature attacking " + targetsController.getLogName());
|
||||||
filter.add(new PermanentInListPredicate(list));
|
filter.add(new PermanentInListPredicate(list));
|
||||||
TargetAttackingCreature target = new TargetAttackingCreature(1, 1, filter, true);
|
TargetAttackingCreature target = new TargetAttackingCreature(1, 1, filter, true);
|
||||||
if (target.canChoose(source.getSourceId(), controller.getId(), game)) {
|
if (target.canChoose(controller.getId(), source, game)) {
|
||||||
while (!target.isChosen() && target.canChoose(source.getSourceId(), controller.getId(), game) && controller.canRespond()) {
|
while (!target.isChosen() && target.canChoose(controller.getId(), source, game) && controller.canRespond()) {
|
||||||
controller.chooseTarget(outcome, target, source, game);
|
controller.chooseTarget(outcome, target, source, game);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -89,7 +89,7 @@ class BalthorTheDefiledEffect extends OneShotEffect {
|
||||||
for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) {
|
for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) {
|
||||||
Player player = game.getPlayer(playerId);
|
Player player = game.getPlayer(playerId);
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
cardsToReturn.addAll(player.getGraveyard().getCards(filter, source.getSourceId(), source.getControllerId(), game));
|
cardsToReturn.addAll(player.getGraveyard().getCards(filter, source.getControllerId(), source, game));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
controller.moveCards(cardsToReturn.getCards(game), Zone.BATTLEFIELD, source, game, false, false, true, null);
|
controller.moveCards(cardsToReturn.getCards(game), Zone.BATTLEFIELD, source, game, false, false, true, null);
|
||||||
|
|
|
@ -70,7 +70,7 @@ class BaneOfProgressEffect extends OneShotEffect {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
int destroyedPermanents = 0;
|
int destroyedPermanents = 0;
|
||||||
for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) {
|
for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source, game)) {
|
||||||
if (permanent.destroy(source, game, false)) {
|
if (permanent.destroy(source, game, false)) {
|
||||||
destroyedPermanents++;
|
destroyedPermanents++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package mage.cards.b;
|
package mage.cards.b;
|
||||||
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.MageObjectReference;
|
|
||||||
import mage.abilities.common.BecomesBlockedSourceTriggeredAbility;
|
import mage.abilities.common.BecomesBlockedSourceTriggeredAbility;
|
||||||
import mage.abilities.common.DiesCreatureTriggeredAbility;
|
import mage.abilities.common.DiesCreatureTriggeredAbility;
|
||||||
import mage.abilities.effects.common.LoseLifeTargetControllerEffect;
|
import mage.abilities.effects.common.LoseLifeTargetControllerEffect;
|
||||||
|
@ -12,18 +11,10 @@ import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.Duration;
|
import mage.constants.Duration;
|
||||||
import mage.constants.SubType;
|
import mage.constants.SubType;
|
||||||
import mage.constants.WatcherScope;
|
|
||||||
import mage.filter.FilterPermanent;
|
|
||||||
import mage.filter.common.FilterCreaturePermanent;
|
import mage.filter.common.FilterCreaturePermanent;
|
||||||
import mage.filter.predicate.ObjectSourcePlayer;
|
|
||||||
import mage.filter.predicate.ObjectSourcePlayerPredicate;
|
|
||||||
import mage.filter.predicate.permanent.BlockingOrBlockedBySourcePredicate;
|
import mage.filter.predicate.permanent.BlockingOrBlockedBySourcePredicate;
|
||||||
import mage.game.Game;
|
|
||||||
import mage.game.events.GameEvent;
|
|
||||||
import mage.game.permanent.Permanent;
|
|
||||||
import mage.watchers.Watcher;
|
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author TheElk801
|
* @author TheElk801
|
||||||
|
@ -31,11 +22,9 @@ import java.util.*;
|
||||||
public final class BaneclawMarauder extends CardImpl {
|
public final class BaneclawMarauder extends CardImpl {
|
||||||
|
|
||||||
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent();
|
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent();
|
||||||
private static final FilterPermanent filter2 = new FilterCreaturePermanent("a creature blocking {this}");
|
|
||||||
|
|
||||||
static {
|
static {
|
||||||
filter.add(BlockingOrBlockedBySourcePredicate.BLOCKING);
|
filter.add(BlockingOrBlockedBySourcePredicate.BLOCKING);
|
||||||
filter2.add(BaneclawMarauderPredicate.instance);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public BaneclawMarauder(UUID ownerId, CardSetInfo setInfo) {
|
public BaneclawMarauder(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
@ -56,8 +45,8 @@ public final class BaneclawMarauder extends CardImpl {
|
||||||
this.addAbility(new DiesCreatureTriggeredAbility(
|
this.addAbility(new DiesCreatureTriggeredAbility(
|
||||||
new LoseLifeTargetControllerEffect(1)
|
new LoseLifeTargetControllerEffect(1)
|
||||||
.setText("that creature's controller loses 1 life"),
|
.setText("that creature's controller loses 1 life"),
|
||||||
false, filter2, true
|
false, filter, true
|
||||||
), new BaneclawMarauderWatcher());
|
));
|
||||||
|
|
||||||
// Nightbound
|
// Nightbound
|
||||||
this.addAbility(new NightboundAbility());
|
this.addAbility(new NightboundAbility());
|
||||||
|
@ -72,55 +61,3 @@ public final class BaneclawMarauder extends CardImpl {
|
||||||
return new BaneclawMarauder(this);
|
return new BaneclawMarauder(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum BaneclawMarauderPredicate implements ObjectSourcePlayerPredicate<Permanent> {
|
|
||||||
instance;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean apply(ObjectSourcePlayer<Permanent> input, Game game) {
|
|
||||||
return BaneclawMarauderWatcher.check(input.getSourceId(), input.getObject(), game);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class BaneclawMarauderWatcher extends Watcher {
|
|
||||||
|
|
||||||
private final Map<MageObjectReference, Set<MageObjectReference>> blockerMap = new HashMap<>();
|
|
||||||
|
|
||||||
BaneclawMarauderWatcher() {
|
|
||||||
super(WatcherScope.GAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void watch(GameEvent event, Game game) {
|
|
||||||
switch (event.getType()) {
|
|
||||||
case BLOCKER_DECLARED:
|
|
||||||
blockerMap
|
|
||||||
.computeIfAbsent(new MageObjectReference(event.getTargetId(), game), x -> new HashSet<>())
|
|
||||||
.add(new MageObjectReference(event.getSourceId(), game));
|
|
||||||
return;
|
|
||||||
case END_COMBAT_STEP_POST:
|
|
||||||
blockerMap.clear();
|
|
||||||
return;
|
|
||||||
case REMOVED_FROM_COMBAT:
|
|
||||||
blockerMap
|
|
||||||
.values()
|
|
||||||
.stream()
|
|
||||||
.forEach(set -> set.removeIf(mor -> mor.refersTo(event.getTargetId(), game)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reset() {
|
|
||||||
super.reset();
|
|
||||||
blockerMap.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
static boolean check(UUID sourceId, Permanent blocker, Game game) {
|
|
||||||
return game.getState()
|
|
||||||
.getWatcher(BaneclawMarauderWatcher.class)
|
|
||||||
.blockerMap
|
|
||||||
.getOrDefault(new MageObjectReference(sourceId, game), Collections.emptySet())
|
|
||||||
.stream()
|
|
||||||
.anyMatch(mor -> mor.refersTo(blocker, game));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
|
|
||||||
package mage.cards.b;
|
package mage.cards.b;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.ObjectColor;
|
import mage.ObjectColor;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
|
@ -13,30 +11,37 @@ import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.Duration;
|
import mage.constants.Duration;
|
||||||
import mage.constants.SubType;
|
import mage.constants.SubType;
|
||||||
import mage.constants.Zone;
|
import mage.filter.FilterPermanent;
|
||||||
import mage.filter.common.FilterCreaturePermanent;
|
import mage.filter.common.FilterCreaturePermanent;
|
||||||
import mage.filter.predicate.mageobject.ColorPredicate;
|
import mage.filter.predicate.mageobject.ColorPredicate;
|
||||||
import mage.filter.predicate.permanent.BlockingAttackerIdPredicate;
|
import mage.filter.predicate.permanent.BlockingOrBlockedBySourcePredicate;
|
||||||
import mage.target.common.TargetCreaturePermanent;
|
import mage.target.TargetPermanent;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author LoneFox
|
* @author LoneFox
|
||||||
*/
|
*/
|
||||||
public final class BarbedBackWurm extends CardImpl {
|
public final class BarbedBackWurm extends CardImpl {
|
||||||
|
|
||||||
|
private static final FilterPermanent filter = new FilterCreaturePermanent("green creature blocking {this}");
|
||||||
|
|
||||||
|
static {
|
||||||
|
filter.add(new ColorPredicate(ObjectColor.GREEN));
|
||||||
|
filter.add(BlockingOrBlockedBySourcePredicate.BLOCKING);
|
||||||
|
}
|
||||||
|
|
||||||
public BarbedBackWurm(UUID ownerId, CardSetInfo setInfo) {
|
public BarbedBackWurm(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{B}");
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}");
|
||||||
this.subtype.add(SubType.WURM);
|
this.subtype.add(SubType.WURM);
|
||||||
this.power = new MageInt(4);
|
this.power = new MageInt(4);
|
||||||
this.toughness = new MageInt(3);
|
this.toughness = new MageInt(3);
|
||||||
|
|
||||||
// {B}: Target green creature blocking Barbed-Back Wurm gets -1/-1 until end of turn.
|
// {B}: Target green creature blocking Barbed-Back Wurm gets -1/-1 until end of turn.
|
||||||
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostTargetEffect(-1, -1, Duration.EndOfTurn), new ManaCostsImpl("{B}"));
|
Ability ability = new SimpleActivatedAbility(new BoostTargetEffect(
|
||||||
FilterCreaturePermanent filter = new FilterCreaturePermanent("green creature blocking {this}");
|
-1, -1, Duration.EndOfTurn
|
||||||
filter.add(new ColorPredicate(ObjectColor.GREEN));
|
), new ManaCostsImpl<>("{B}"));
|
||||||
filter.add(new BlockingAttackerIdPredicate(this.getId()));
|
ability.addTarget(new TargetPermanent(filter));
|
||||||
ability.addTarget(new TargetCreaturePermanent(filter));
|
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -76,7 +76,7 @@ class BaronVonCountPutCounterEffect extends OneShotEffect {
|
||||||
Player controller = game.getPlayer(source.getControllerId());
|
Player controller = game.getPlayer(source.getControllerId());
|
||||||
MageObject mageObject = game.getPermanentEntering(source.getSourceId());
|
MageObject mageObject = game.getPermanentEntering(source.getSourceId());
|
||||||
if (mageObject == null) {
|
if (mageObject == null) {
|
||||||
mageObject = game.getObject(source.getSourceId());
|
mageObject = game.getObject(source);
|
||||||
}
|
}
|
||||||
if (controller != null && mageObject != null) {
|
if (controller != null && mageObject != null) {
|
||||||
Integer doomNumber = 5;
|
Integer doomNumber = 5;
|
||||||
|
@ -172,7 +172,7 @@ class BaronVonCountMoveDoomCounterEffect extends OneShotEffect {
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
Player controller = game.getPlayer(source.getControllerId());
|
Player controller = game.getPlayer(source.getControllerId());
|
||||||
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
|
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
|
||||||
MageObject mageObject = game.getObject(source.getSourceId());
|
MageObject mageObject = game.getObject(source);
|
||||||
if (controller != null && sourcePermanent != null && mageObject != null) {
|
if (controller != null && sourcePermanent != null && mageObject != null) {
|
||||||
if (game.getState().getValue(mageObject.getId() + "_doom") == null) {
|
if (game.getState().getValue(mageObject.getId() + "_doom") == null) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -249,7 +249,7 @@ class BaronVonCountDestroyPlayerEffect extends OneShotEffect {
|
||||||
targetPlayer.lost(game); // double checks canLose, but seems more future-proof than lostForced
|
targetPlayer.lost(game); // double checks canLose, but seems more future-proof than lostForced
|
||||||
}
|
}
|
||||||
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
|
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
|
||||||
MageObject mageObject = game.getObject(source.getSourceId());
|
MageObject mageObject = game.getObject(source);
|
||||||
if (sourcePermanent != null && mageObject != null) {
|
if (sourcePermanent != null && mageObject != null) {
|
||||||
if (game.getState().getValue(mageObject.getId() + "_doom") == null) {
|
if (game.getState().getValue(mageObject.getId() + "_doom") == null) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -75,7 +75,7 @@ enum BaseCampCondition implements Condition {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
MageObject object = game.getObject(source.getSourceId());
|
MageObject object = game.getObject(source);
|
||||||
return object != null && (
|
return object != null && (
|
||||||
object.hasSubtype(SubType.CLERIC, game)
|
object.hasSubtype(SubType.CLERIC, game)
|
||||||
|| object.hasSubtype(SubType.ROGUE, game)
|
|| object.hasSubtype(SubType.ROGUE, game)
|
||||||
|
|
|
@ -87,7 +87,7 @@ class BatheInLightEffect extends OneShotEffect {
|
||||||
ContinuousEffect effect = new ProtectionChosenColorTargetEffect();
|
ContinuousEffect effect = new ProtectionChosenColorTargetEffect();
|
||||||
game.addEffect(effect, source);
|
game.addEffect(effect, source);
|
||||||
ObjectColor color = target.getColor(game);
|
ObjectColor color = target.getColor(game);
|
||||||
for (Permanent permanent : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), source.getSourceId(), game)) {
|
for (Permanent permanent : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), source, game)) {
|
||||||
if (!permanent.getId().equals(target.getId()) && permanent.getColor(game).shares(color)) {
|
if (!permanent.getId().equals(target.getId()) && permanent.getColor(game).shares(color)) {
|
||||||
game.getState().setValue(permanent.getId() + "_color", colorChoice.getColor());
|
game.getState().setValue(permanent.getId() + "_color", colorChoice.getColor());
|
||||||
effect.setTargetPointer(new FixedTarget(permanent, game));
|
effect.setTargetPointer(new FixedTarget(permanent, game));
|
||||||
|
|
|
@ -89,7 +89,7 @@ class BattleForBretagardEffect extends OneShotEffect {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
TargetPermanent target = new BattleForBretagardTarget();
|
TargetPermanent target = new BattleForBretagardTarget();
|
||||||
player.choose(outcome, target, source.getSourceId(), game);
|
player.choose(outcome, target, source, game);
|
||||||
for (UUID targetId : target.getTargets()) {
|
for (UUID targetId : target.getTargets()) {
|
||||||
new CreateTokenCopyTargetEffect()
|
new CreateTokenCopyTargetEffect()
|
||||||
.setTargetPointer(new FixedTarget(targetId, game))
|
.setTargetPointer(new FixedTarget(targetId, game))
|
||||||
|
@ -145,8 +145,8 @@ class BattleForBretagardTarget extends TargetPermanent {
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<UUID> possibleTargets(UUID sourceId, UUID sourceControllerId, Game game) {
|
public Set<UUID> possibleTargets(UUID sourceControllerId, Ability source, Game game) {
|
||||||
Set<UUID> possibleTargets = super.possibleTargets(sourceId, sourceControllerId, game);
|
Set<UUID> possibleTargets = super.possibleTargets(sourceControllerId, source, game);
|
||||||
Set<String> names = this.getTargets()
|
Set<String> names = this.getTargets()
|
||||||
.stream()
|
.stream()
|
||||||
.map(game::getPermanent)
|
.map(game::getPermanent)
|
||||||
|
|
|
@ -68,7 +68,7 @@ class BattlefieldScroungerCost extends CostImpl {
|
||||||
public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) {
|
public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) {
|
||||||
Player controller = game.getPlayer(controllerId);
|
Player controller = game.getPlayer(controllerId);
|
||||||
if (controller != null) {
|
if (controller != null) {
|
||||||
if (targets.choose(Outcome.Removal, controllerId, source.getSourceId(), game)) {
|
if (targets.choose(Outcome.Removal, controllerId, source.getSourceId(), source, game)) {
|
||||||
for (UUID targetId: targets.get(0).getTargets()) {
|
for (UUID targetId: targets.get(0).getTargets()) {
|
||||||
Card card = game.getCard(targetId);
|
Card card = game.getCard(targetId);
|
||||||
if (card == null || game.getState().getZone(targetId) != Zone.GRAVEYARD) {
|
if (card == null || game.getState().getZone(targetId) != Zone.GRAVEYARD) {
|
||||||
|
@ -84,7 +84,7 @@ class BattlefieldScroungerCost extends CostImpl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) {
|
public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) {
|
||||||
return targets.canChoose(source.getSourceId(), controllerId, game);
|
return targets.canChoose(controllerId, source, game);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -99,7 +99,7 @@ class BattlefieldThaumaturgeSpellsCostReductionEffect extends CostModificationEf
|
||||||
if (target.isNotTarget()) {
|
if (target.isNotTarget()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Set<UUID> possibleList = target.possibleTargets(ability.getSourceId(), ability.getControllerId(), game);
|
Set<UUID> possibleList = target.possibleTargets(ability.getControllerId(), ability, game);
|
||||||
possibleList.removeIf(id -> {
|
possibleList.removeIf(id -> {
|
||||||
Permanent permanent = game.getPermanent(id);
|
Permanent permanent = game.getPermanent(id);
|
||||||
return permanent == null || !permanent.isCreature(game);
|
return permanent == null || !permanent.isCreature(game);
|
||||||
|
|
|
@ -71,7 +71,7 @@ class BeaconOfDestinyEffect extends RedirectionEffect {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(Ability source, Game game) {
|
public void init(Ability source, Game game) {
|
||||||
this.damageSource.choose(Outcome.PreventDamage, source.getControllerId(), source.getSourceId(), game);
|
this.damageSource.choose(Outcome.PreventDamage, source.getControllerId(), source.getSourceId(), source, game);
|
||||||
super.init(source, game);
|
super.init(source, game);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -112,7 +112,7 @@ class BeamsplitterMageTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
return game.getBattlefield().getActivePermanents(
|
return game.getBattlefield().getActivePermanents(
|
||||||
StaticFilters.FILTER_CONTROLLED_CREATURE,
|
StaticFilters.FILTER_CONTROLLED_CREATURE,
|
||||||
getControllerId(), getSourceId(), game
|
getControllerId(), this, game
|
||||||
).stream()
|
).stream()
|
||||||
.filter(Objects::nonNull)
|
.filter(Objects::nonNull)
|
||||||
.filter(permanent -> permanent.isCreature(game))
|
.filter(permanent -> permanent.isCreature(game))
|
||||||
|
@ -165,7 +165,7 @@ class BeamsplitterMageEffect extends OneShotEffect {
|
||||||
filter.add(new BeamsplitterMagePredicate(spell));
|
filter.add(new BeamsplitterMagePredicate(spell));
|
||||||
TargetPermanent target = new TargetPermanent(filter);
|
TargetPermanent target = new TargetPermanent(filter);
|
||||||
target.setNotTarget(true);
|
target.setNotTarget(true);
|
||||||
player.choose(outcome, target, source.getSourceId(), game);
|
player.choose(outcome, target, source, game);
|
||||||
Permanent permanent = game.getPermanent(target.getFirstTarget());
|
Permanent permanent = game.getPermanent(target.getFirstTarget());
|
||||||
if (permanent == null) {
|
if (permanent == null) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -14,7 +14,6 @@ import mage.constants.SpellAbilityType;
|
||||||
import mage.filter.common.FilterCreaturePermanent;
|
import mage.filter.common.FilterCreaturePermanent;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.events.GameEvent;
|
import mage.game.events.GameEvent;
|
||||||
import mage.game.events.GameEvent.EventType;
|
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
import mage.game.permanent.token.BirdToken;
|
import mage.game.permanent.token.BirdToken;
|
||||||
|
|
||||||
|
@ -65,7 +64,7 @@ class BeckTriggeredAbility extends DelayedTriggeredAbility {
|
||||||
public boolean checkTrigger(GameEvent event, Game game) {
|
public boolean checkTrigger(GameEvent event, Game game) {
|
||||||
UUID targetId = event.getTargetId();
|
UUID targetId = event.getTargetId();
|
||||||
Permanent permanent = game.getPermanent(targetId);
|
Permanent permanent = game.getPermanent(targetId);
|
||||||
return filter.match(permanent, getSourceId(), getControllerId(), game);
|
return filter.match(permanent, getControllerId(), this, game);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -96,7 +96,7 @@ class BendOrBreakEffect extends OneShotEffect {
|
||||||
List<Permanent> secondPile = new ArrayList<>();
|
List<Permanent> secondPile = new ArrayList<>();
|
||||||
FilterControlledLandPermanent filter = new FilterControlledLandPermanent("lands you control to assign to the first pile (lands not chosen will be assigned to the second pile)");
|
FilterControlledLandPermanent filter = new FilterControlledLandPermanent("lands you control to assign to the first pile (lands not chosen will be assigned to the second pile)");
|
||||||
TargetPermanent target = new TargetControlledPermanent(0, Integer.MAX_VALUE, filter, true);
|
TargetPermanent target = new TargetControlledPermanent(0, Integer.MAX_VALUE, filter, true);
|
||||||
if (!target.canChoose(source.getSourceId(), currentPlayer.getId(), game)) { continue; }
|
if (!target.canChoose(currentPlayer.getId(), source, game)) { continue; }
|
||||||
|
|
||||||
// TODO: add support for AI (50/50), need AI hints mechanic here
|
// TODO: add support for AI (50/50), need AI hints mechanic here
|
||||||
currentPlayer.chooseTarget(Outcome.Neutral, target, source, game);
|
currentPlayer.chooseTarget(Outcome.Neutral, target, source, game);
|
||||||
|
|
|
@ -61,7 +61,7 @@ class BenefactionOfRhonasEffect extends OneShotEffect {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
Player controller = game.getPlayer(source.getControllerId());
|
Player controller = game.getPlayer(source.getControllerId());
|
||||||
MageObject sourceObject = game.getObject(source.getSourceId());
|
MageObject sourceObject = game.getObject(source);
|
||||||
if (sourceObject != null && controller != null) {
|
if (sourceObject != null && controller != null) {
|
||||||
Cards cards = new CardsImpl(controller.getLibrary().getTopCards(game, 5));
|
Cards cards = new CardsImpl(controller.getLibrary().getTopCards(game, 5));
|
||||||
boolean creatureCardFound = false;
|
boolean creatureCardFound = false;
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue