1
0
Fork 0
mirror of https://github.com/correl/mage.git synced 2025-04-09 17:00:09 -09:00

(WIP) Replacing blocking/blocked by predicates ()

* 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:
Evan Kranzler 2022-03-23 18:45:02 -04:00 committed by GitHub
parent 53877424a0
commit 80e11b2052
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
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
b

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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() + ").";

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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() + ").";
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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:

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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() + ").";
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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