mirror of
https://github.com/correl/mage.git
synced 2024-12-24 11:50:45 +00:00
(WIP) Replacing blocking/blocked by predicates (#8729)
* replaced blocking/blocked by predicates * added test for knight of dusk (currently fails) * added source parameter to filters and everything else that needs it * some changes to various predicates * test fix * small changes to filter code * merge fix * fixed a test failure * small change to Karn, Scion of Urza * removed sourceId from filter methods and other similar places * added new getobject method to fix some test failures * a few more fixes * fixed merge conflicts * merge fix
This commit is contained in:
parent
53877424a0
commit
80e11b2052
1719 changed files with 3384 additions and 3325 deletions
|
@ -396,7 +396,7 @@ public class ComputerPlayer6 extends ComputerPlayer /*implements Player*/ {
|
|||
&& stackObject.getControllerId().equals(playerId)) {
|
||||
Target target = effect.getTarget();
|
||||
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();
|
||||
StackAbility newAbility = (StackAbility) stackObject.copy();
|
||||
SearchEffect newEffect = getSearchEffect(newAbility);
|
||||
|
|
|
@ -122,12 +122,12 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean choose(Outcome outcome, Target target, UUID sourceId, Game game) {
|
||||
return choose(outcome, target, sourceId, game, null);
|
||||
public boolean choose(Outcome outcome, Target target, Ability source, Game game) {
|
||||
return choose(outcome, target, source, game, null);
|
||||
}
|
||||
|
||||
@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()) {
|
||||
log.debug("choose: " + outcome.toString() + ':' + target.toString());
|
||||
|
@ -143,9 +143,10 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
&& target.getAbilityController() != null) {
|
||||
abilityControllerId = target.getAbilityController();
|
||||
}
|
||||
UUID sourceId = source != null ? source.getSourceId() : null;
|
||||
|
||||
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()) {
|
||||
required = false;
|
||||
}
|
||||
|
@ -160,7 +161,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
}
|
||||
|
||||
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) {
|
||||
|
@ -191,12 +192,12 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
if (target.getOriginalTarget() instanceof TargetControlledPermanent) {
|
||||
List<Permanent> targets;
|
||||
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()) {
|
||||
Collections.reverse(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);
|
||||
return true;
|
||||
}
|
||||
|
@ -217,18 +218,18 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
|
||||
List<Permanent> targets;
|
||||
if (outcome.isCanTargetAll()) {
|
||||
targets = threats(null, sourceId, filter, game, target.getTargets());
|
||||
targets = threats(null, source, filter, game, target.getTargets());
|
||||
} else {
|
||||
if (outcome.isGood()) {
|
||||
targets = threats(abilityControllerId, sourceId, filter, game, target.getTargets());
|
||||
targets = threats(abilityControllerId, source, filter, game, target.getTargets());
|
||||
} else {
|
||||
targets = threats(randomOpponentId, sourceId, filter, game, target.getTargets());
|
||||
targets = threats(randomOpponentId, source, filter, game, target.getTargets());
|
||||
}
|
||||
if (targets.isEmpty() && target.isRequired()) {
|
||||
if (!outcome.isGood()) {
|
||||
targets = threats(abilityControllerId, sourceId, filter, game, target.getTargets());
|
||||
targets = threats(abilityControllerId, source, filter, game, target.getTargets());
|
||||
} 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
|
||||
|| (target.getZone() == Zone.HAND && (target.getOriginalTarget() instanceof TargetCard))) {
|
||||
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);
|
||||
if (card != null) {
|
||||
cards.add(card);
|
||||
|
@ -278,9 +279,9 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
List<Permanent> targets;
|
||||
TargetAnyTarget origTarget = (TargetAnyTarget) target.getOriginalTarget();
|
||||
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 {
|
||||
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) {
|
||||
List<UUID> alreadyTargetted = target.getTargets();
|
||||
|
@ -309,9 +310,9 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
List<Permanent> targets;
|
||||
TargetCreatureOrPlayer origTarget = (TargetCreatureOrPlayer) target.getOriginalTarget();
|
||||
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 {
|
||||
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) {
|
||||
List<UUID> alreadyTargeted = target.getTargets();
|
||||
|
@ -339,8 +340,8 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
if (target.getOriginalTarget() instanceof TargetPermanentOrPlayer) {
|
||||
List<Permanent> targets;
|
||||
TargetPermanentOrPlayer origTarget = (TargetPermanentOrPlayer) target.getOriginalTarget();
|
||||
List<Permanent> ownedTargets = threats(abilityControllerId, sourceId, ((FilterPermanentOrPlayer) origTarget.getFilter()).getPermanentFilter(), game, target.getTargets());
|
||||
List<Permanent> opponentTargets = threats(randomOpponentId, 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, source, ((FilterPermanentOrPlayer) origTarget.getFilter()).getPermanentFilter(), game, target.getTargets());
|
||||
if (outcome.isGood()) {
|
||||
targets = ownedTargets;
|
||||
} else {
|
||||
|
@ -463,7 +464,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
|
||||
if (target.getOriginalTarget() instanceof TargetSource) {
|
||||
Set<UUID> targets;
|
||||
targets = target.possibleTargets(sourceId, abilityControllerId, game);
|
||||
targets = target.possibleTargets(abilityControllerId, source, game);
|
||||
for (UUID targetId : targets) {
|
||||
MageObject targetObject = game.getObject(targetId);
|
||||
if (targetObject != null) {
|
||||
|
@ -517,7 +518,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
}
|
||||
|
||||
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()) {
|
||||
required = false;
|
||||
}
|
||||
|
@ -537,7 +538,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
}
|
||||
|
||||
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
|
||||
|
@ -642,7 +643,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
if (target.getOriginalTarget() instanceof TargetControlledPermanent) {
|
||||
TargetControlledPermanent origTarget = (TargetControlledPermanent) target.getOriginalTarget();
|
||||
List<Permanent> targets;
|
||||
targets = threats(abilityControllerId, sourceId, origTarget.getFilter(), game, target.getTargets());
|
||||
targets = threats(abilityControllerId, source, origTarget.getFilter(), game, target.getTargets());
|
||||
if (!outcome.isGood()) {
|
||||
Collections.reverse(targets);
|
||||
}
|
||||
|
@ -671,7 +672,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
+ target.getOriginalTarget().getClass().getCanonicalName());
|
||||
}
|
||||
|
||||
findBestPermanentTargets(outcome, abilityControllerId, sourceId, filter,
|
||||
findBestPermanentTargets(outcome, abilityControllerId, sourceId, source, filter,
|
||||
game, target, goodList, badList, allList);
|
||||
|
||||
// use good list all the time and add maximum targets
|
||||
|
@ -700,9 +701,9 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
List<Permanent> targets;
|
||||
TargetCreatureOrPlayer origTarget = ((TargetCreatureOrPlayer) target.getOriginalTarget());
|
||||
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 {
|
||||
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()) {
|
||||
|
@ -742,9 +743,9 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
List<Permanent> targets;
|
||||
TargetAnyTarget origTarget = ((TargetAnyTarget) target.getOriginalTarget());
|
||||
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 {
|
||||
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()) {
|
||||
|
@ -785,9 +786,9 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
List<Permanent> targets;
|
||||
TargetPermanentOrPlayer origTarget = ((TargetPermanentOrPlayer) target.getOriginalTarget());
|
||||
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 {
|
||||
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()) {
|
||||
|
@ -823,9 +824,9 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
// normal cycle (good for you, bad for opponents)
|
||||
// possible good/bad permanents
|
||||
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 {
|
||||
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
|
||||
|
@ -930,12 +931,12 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
List<Permanent> targets;
|
||||
boolean outcomeTargets = true;
|
||||
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 {
|
||||
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) {
|
||||
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);
|
||||
outcomeTargets = false;
|
||||
}
|
||||
|
@ -1008,7 +1009,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
}
|
||||
|
||||
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);
|
||||
if (card != null && game.getState().getZone(card.getId()) == Zone.EXILED) {
|
||||
cards.add(card);
|
||||
|
@ -1026,7 +1027,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
|
||||
if (target.getOriginalTarget() instanceof TargetActivatedAbility) {
|
||||
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);
|
||||
if (stackObject != null) {
|
||||
stackObjects.add(stackObject);
|
||||
|
@ -1129,7 +1130,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
|
||||
// permanents kill
|
||||
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
|
||||
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
|
||||
for (UUID opponentId : opponents) {
|
||||
if (outcome.isGood()) {
|
||||
targets = threats(getId(), sourceId, StaticFilters.FILTER_PERMANENT, game, target.getTargets());
|
||||
targets = threats(getId(), source, StaticFilters.FILTER_PERMANENT, game, target.getTargets());
|
||||
} else {
|
||||
targets = threats(opponentId, sourceId, StaticFilters.FILTER_PERMANENT, game, target.getTargets());
|
||||
targets = threats(opponentId, source, StaticFilters.FILTER_PERMANENT, game, target.getTargets());
|
||||
}
|
||||
|
||||
// planeswalkers
|
||||
|
@ -1192,9 +1193,9 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
for (UUID opponentId : opponents) {
|
||||
if (!outcome.isGood()) {
|
||||
// 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 {
|
||||
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)
|
||||
|
@ -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
|
||||
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()) {
|
||||
Card card = pickTarget(abilityControllerId, cardChoices, outcome, target, source, game);
|
||||
if (card != null) {
|
||||
|
@ -2109,7 +2110,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
@ -2694,7 +2695,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
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) {
|
||||
// searching for most valuable/powerfull permanents
|
||||
goodList.clear();
|
||||
|
@ -2703,7 +2704,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
List<UUID> usedTargets = target.getTargets();
|
||||
|
||||
// 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())) {
|
||||
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) {
|
||||
return threats(playerId, sourceId, filter, game, targets, true);
|
||||
protected List<Permanent> threats(UUID playerId, Ability source, FilterPermanent filter, Game game, List<UUID> targets) {
|
||||
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
|
||||
List<Permanent> threats;
|
||||
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 {
|
||||
FilterPermanent filterCopy = filter.copy();
|
||||
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();
|
||||
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
|
||||
*/
|
||||
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;
|
||||
if (abilityControllerId == this.playerId) {
|
||||
// selects for itself
|
||||
|
@ -2915,6 +2916,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
return false;
|
||||
}
|
||||
|
||||
UUID sourceId = source != null ? source.getSourceId() : null;
|
||||
if (target.getOriginalTarget() instanceof TargetPlayer) {
|
||||
if (affectedOutcome.isGood()) {
|
||||
if (source == null) {
|
||||
|
|
|
@ -221,7 +221,7 @@ public class SimulatedPlayerMCTS extends MCTSPlayer {
|
|||
}
|
||||
|
||||
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()) {
|
||||
return false;
|
||||
}
|
||||
|
@ -245,19 +245,19 @@ public class SimulatedPlayerMCTS extends MCTSPlayer {
|
|||
}
|
||||
|
||||
@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()) {
|
||||
return chooseRandom(target, game);
|
||||
}
|
||||
return super.choose(outcome, target, sourceId, game);
|
||||
return super.choose(outcome, target, source, game);
|
||||
}
|
||||
|
||||
@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()) {
|
||||
return chooseRandom(target, game);
|
||||
}
|
||||
return super.choose(outcome, target, sourceId, game, options);
|
||||
return super.choose(outcome, target, source, game, options);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -302,7 +302,7 @@ public class SimulatedPlayerMCTS extends MCTSPlayer {
|
|||
|
||||
@Override
|
||||
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()) {
|
||||
return !target.isRequired(source);
|
||||
}
|
||||
|
|
|
@ -235,7 +235,7 @@ public class ComputerPlayer2 extends ComputerPlayer implements Player {
|
|||
if (effect != null && ability.getControllerId().equals(playerId)) {
|
||||
Target target = effect.getTarget();
|
||||
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();
|
||||
StackAbility newAbility = (StackAbility) ability.copy();
|
||||
SearchEffect newEffect = getSearchEffect((StackAbility) newAbility);
|
||||
|
|
|
@ -498,12 +498,12 @@ public class HumanPlayer extends PlayerImpl {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean choose(Outcome outcome, Target target, UUID sourceId, Game game) {
|
||||
return choose(outcome, target, sourceId, game, null);
|
||||
public boolean choose(Outcome outcome, Target target, Ability source, Game game) {
|
||||
return choose(outcome, target, source, game, null);
|
||||
}
|
||||
|
||||
@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)) {
|
||||
return true;
|
||||
}
|
||||
|
@ -519,12 +519,12 @@ public class HumanPlayer extends PlayerImpl {
|
|||
}
|
||||
|
||||
while (canRespond()) {
|
||||
Set<UUID> targetIds = target.possibleTargets(sourceId, abilityControllerId, game);
|
||||
Set<UUID> targetIds = target.possibleTargets(abilityControllerId, source, game);
|
||||
if (targetIds == null || targetIds.isEmpty()) {
|
||||
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()) {
|
||||
required = false;
|
||||
}
|
||||
|
@ -535,7 +535,7 @@ public class HumanPlayer extends PlayerImpl {
|
|||
updateGameStatePriority("choose(5)", game);
|
||||
prepareForResponse(game);
|
||||
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);
|
||||
|
||||
|
@ -554,14 +554,14 @@ public class HumanPlayer extends PlayerImpl {
|
|||
}
|
||||
|
||||
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);
|
||||
if (target.doneChosing()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
MageObject object = game.getObject(sourceId);
|
||||
MageObject object = game.getObject(source);
|
||||
if (object instanceof Ability) {
|
||||
if (target.canTarget(responseId, (Ability) object, game)) {
|
||||
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<>();
|
||||
|
||||
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);
|
||||
if (possibleTargets.isEmpty()
|
||||
|| target.getTargets().size() >= target.getNumberOfTargets()) {
|
||||
|
@ -845,7 +845,7 @@ public class HumanPlayer extends PlayerImpl {
|
|||
|
||||
// 1. Select targets
|
||||
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);
|
||||
if (possibleTargets.isEmpty()
|
||||
|| target.getSize() >= target.getNumberOfTargets()) {
|
||||
|
@ -979,7 +979,7 @@ public class HumanPlayer extends PlayerImpl {
|
|||
FilterCreatureForCombatBlock filter = filterCreatureForCombatBlock.copy();
|
||||
filter.add(new ControllerIdPredicate(playerId));
|
||||
// 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 canStopOnZero = possibleBlockersCount == 0 && getControllingPlayersUserData(game).getUserSkipPrioritySteps().isStopOnDeclareBlockersWithZeroPermanents();
|
||||
quickStop = canStopOnAny || canStopOnZero;
|
||||
|
@ -1605,9 +1605,9 @@ public class HumanPlayer extends PlayerImpl {
|
|||
} else if (responseId != null) {
|
||||
Permanent attacker = game.getPermanent(responseId);
|
||||
if (attacker != null) {
|
||||
if (filterCreatureForCombat.match(attacker, null, playerId, game)) {
|
||||
if (filterCreatureForCombat.match(attacker, playerId, null, 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);
|
||||
}
|
||||
}
|
||||
|
@ -1772,7 +1772,7 @@ public class HumanPlayer extends PlayerImpl {
|
|||
filter.add(new ControllerIdPredicate(defendingPlayerId));
|
||||
|
||||
// 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 canStopOnZero = possibleBlockersCount == 0 && getControllingPlayersUserData(game).getUserSkipPrioritySteps().isStopOnDeclareBlockersWithZeroPermanents();
|
||||
|
||||
|
@ -1810,9 +1810,9 @@ public class HumanPlayer extends PlayerImpl {
|
|||
if (blocker != null) {
|
||||
boolean removeBlocker = false;
|
||||
// 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);
|
||||
} else if (filterBlock.match(blocker, null, playerId, game)
|
||||
} else if (filterBlock.match(blocker, playerId, source, game)
|
||||
&& game.getStack().isEmpty()) {
|
||||
removeBlocker = true;
|
||||
}
|
||||
|
@ -1892,7 +1892,7 @@ public class HumanPlayer extends PlayerImpl {
|
|||
prepareForResponse(game);
|
||||
if (!isExecutingMacro()) {
|
||||
// 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);
|
||||
Set<UUID> possibleTargets = new HashSet<>();
|
||||
for (UUID attackerId : attackers) {
|
||||
|
@ -1932,7 +1932,7 @@ public class HumanPlayer extends PlayerImpl {
|
|||
if (singleTargetName != null) {
|
||||
target.setTargetName(singleTargetName);
|
||||
}
|
||||
choose(Outcome.Damage, target, source.getSourceId(), game);
|
||||
choose(Outcome.Damage, target, source, game);
|
||||
if (targets.isEmpty() || targets.contains(target.getFirstTarget())) {
|
||||
int damageAmount = getAmount(0, remainingDamage, "Select amount", game);
|
||||
Permanent permanent = game.getPermanent(target.getFirstTarget());
|
||||
|
@ -2222,7 +2222,7 @@ public class HumanPlayer extends PlayerImpl {
|
|||
if (modes.size() > 1) {
|
||||
// done option for up to choices
|
||||
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<>();
|
||||
int modeIndex = 0;
|
||||
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);
|
||||
if (obj != null) {
|
||||
modeText = modeText.replace("{this}", obj.getName());
|
||||
|
|
|
@ -68,7 +68,7 @@ class AbeyanceEffect extends ContinuousRuleModifyingEffectImpl {
|
|||
|
||||
@Override
|
||||
public String getInfoMessage(Ability source, GameEvent event, Game game) {
|
||||
MageObject mageObject = game.getObject(source.getSourceId());
|
||||
MageObject mageObject = game.getObject(source);
|
||||
if (mageObject != null) {
|
||||
return "You can't cast instant or sorcery spells or activate abilities "
|
||||
+ "that aren't mana abilities this turn (" + mageObject.getIdName() + ").";
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
|
||||
package mage.cards.a;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.common.DiesSourceTriggeredAbility;
|
||||
import mage.abilities.effects.common.DestroyAllEffect;
|
||||
|
@ -9,28 +7,31 @@ import mage.cards.CardImpl;
|
|||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.filter.predicate.permanent.BlockedByIdPredicate;
|
||||
import mage.filter.predicate.permanent.BlockingAttackerIdPredicate;
|
||||
import mage.filter.predicate.permanent.BlockingOrBlockedBySourcePredicate;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author MarcoMarin
|
||||
*/
|
||||
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) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{W}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}");
|
||||
this.subtype.add(SubType.HUMAN);
|
||||
this.power = new MageInt(0);
|
||||
this.toughness = new MageInt(1);
|
||||
|
||||
FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures blocking or blocked by it");
|
||||
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.
|
||||
// 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));
|
||||
}
|
||||
|
||||
|
|
|
@ -64,7 +64,7 @@ class AbundanceReplacementEffect extends ReplacementEffectImpl {
|
|||
@Override
|
||||
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
|
||||
Player controller = game.getPlayer(event.getPlayerId());
|
||||
MageObject sourceObject = game.getObject(source.getSourceId());
|
||||
MageObject sourceObject = game.getObject(source);
|
||||
if (controller != null && sourceObject != null) {
|
||||
FilterCard filter = new FilterCard();
|
||||
if (controller.chooseUse(Outcome.Detriment, "Choose card type:",
|
||||
|
@ -79,7 +79,7 @@ class AbundanceReplacementEffect extends ReplacementEffectImpl {
|
|||
Card selectedCard = null;
|
||||
for (Card card : controller.getLibrary().getCards(game)) {
|
||||
toReveal.add(card);
|
||||
if (filter.match(card, source.getSourceId(), source.getControllerId(), game)) {
|
||||
if (filter.match(card, source.getControllerId(), source, game)) {
|
||||
selectedCard = card;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -73,7 +73,7 @@ class AcademyResearchersEffect extends OneShotEffect {
|
|||
if (controller != null && academyResearchers != null) {
|
||||
filterCardInHand.add(new AuraCardCanAttachToPermanentId(academyResearchers.getId()));
|
||||
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());
|
||||
if (auraInHand != null) {
|
||||
game.getState().setValue("attachTo:" + auraInHand.getId(), academyResearchers);
|
||||
|
|
|
@ -103,7 +103,7 @@ class AcererakTheArchlichEffect extends OneShotEffect {
|
|||
}
|
||||
TargetPermanent target = new TargetControlledCreaturePermanent(0, 1);
|
||||
target.setNotTarget(true);
|
||||
player.choose(Outcome.Sacrifice, target, source.getSourceId(), game);
|
||||
player.choose(Outcome.Sacrifice, target, source, game);
|
||||
Permanent permanent = game.getPermanent(target.getFirstTarget());
|
||||
if (permanent != null && permanent.sacrifice(source, game)) {
|
||||
tokens--;
|
||||
|
|
|
@ -50,7 +50,7 @@ class AcidicSoilEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
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)) {
|
||||
Player player = game.getPlayer(playerId);
|
||||
if (player != null) {
|
||||
|
|
|
@ -73,7 +73,7 @@ class AcolyteOfAfflictionEffect extends OneShotEffect {
|
|||
}
|
||||
player.moveCards(player.getLibrary().getTopCards(game, 2), Zone.GRAVEYARD, source, game);
|
||||
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;
|
||||
}
|
||||
Card card = game.getCard(target.getFirstTarget());
|
||||
|
|
|
@ -63,7 +63,7 @@ class AdviceFromTheFaeEffect extends OneShotEffect {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
MageObject mageObject = game.getObject(source.getSourceId());
|
||||
MageObject mageObject = game.getObject(source);
|
||||
if (controller != null && mageObject != null) {
|
||||
Set<Card> topCards = controller.getLibrary().getTopCards(game, 5);
|
||||
Cards cardsFromLibrary = new CardsImpl();
|
||||
|
|
|
@ -79,10 +79,10 @@ enum AerialSurveyorCondition implements Condition {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
return game.getBattlefield().count(
|
||||
filter, source.getSourceId(), source.getControllerId(), game
|
||||
filter, source.getControllerId(), source, game
|
||||
) > game.getBattlefield().count(
|
||||
StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND,
|
||||
source.getSourceId(), source.getControllerId(), game
|
||||
source.getControllerId(), source, game
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ enum AerialSurveyorHint implements Hint {
|
|||
.getActivePermanents(
|
||||
StaticFilters.FILTER_LAND,
|
||||
ability.getControllerId(),
|
||||
ability.getSourceId(), game
|
||||
ability, game
|
||||
).stream()
|
||||
.map(Controllable::getControllerId)
|
||||
.filter(game.getOpponents(ability.getControllerId())::contains)
|
||||
|
|
|
@ -90,7 +90,7 @@ class AetherVialEffect extends OneShotEffect {
|
|||
}
|
||||
|
||||
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());
|
||||
if (card != null) {
|
||||
return controller.moveCards(card, Zone.BATTLEFIELD, source, game);
|
||||
|
|
|
@ -78,12 +78,12 @@ class AetherbornMarauderEffect extends OneShotEffect {
|
|||
filter.add(AnotherPredicate.instance);
|
||||
filter.add(CounterType.P1P1.getPredicate());
|
||||
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)) {
|
||||
firstRun = false;
|
||||
TargetControlledPermanent target = new TargetControlledPermanent(filter);
|
||||
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());
|
||||
if (fromPermanent != null) {
|
||||
int numberOfCounters = fromPermanent.getCounters(game).getCount(CounterType.P1P1);
|
||||
|
|
|
@ -60,7 +60,7 @@ class AethermagesTouchEffect extends OneShotEffect {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
MageObject sourceObject = game.getObject(source.getSourceId());
|
||||
MageObject sourceObject = game.getObject(source);
|
||||
if (controller != null && sourceObject != null) {
|
||||
Cards cards = new CardsImpl(controller.getLibrary().getTopCards(game, 4));
|
||||
if (!cards.isEmpty()) {
|
||||
|
|
|
@ -67,7 +67,7 @@ class AetherplasmEffect extends OneShotEffect {
|
|||
}
|
||||
if (player.chooseUse(Outcome.PutCardInPlay, "Put a creature card from your hand onto the battlefield?", source, game)) {
|
||||
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());
|
||||
if (card != null) {
|
||||
Permanent blockedCreature = game.getPermanent(getTargetPointer().getFirst(game, source));
|
||||
|
|
|
@ -81,7 +81,7 @@ class AetherspoutsEffect extends OneShotEffect {
|
|||
do {
|
||||
List<Permanent> permanentsToTop = 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 (player.chooseUse(outcome, "Put " + permanent.getLogName() + " to the top? (else it goes to bottom)", source, game)) {
|
||||
permanentsToTop.add(permanent);
|
||||
|
|
|
@ -81,8 +81,8 @@ class AgadeemOccultistEffect extends OneShotEffect {
|
|||
TargetCardInOpponentsGraveyard target = new TargetCardInOpponentsGraveyard(1, 1, filter);
|
||||
|
||||
if (controller != null) {
|
||||
if (target.canChoose(source.getSourceId(), source.getControllerId(), game)
|
||||
&& controller.choose(Outcome.GainControl, target, source.getSourceId(), game)) {
|
||||
if (target.canChoose(source.getControllerId(), source, game)
|
||||
&& controller.choose(Outcome.GainControl, target, source, game)) {
|
||||
if (!target.getTargets().isEmpty()) {
|
||||
Card card = game.getCard(target.getFirstTarget());
|
||||
if (card != null) {
|
||||
|
|
|
@ -100,8 +100,8 @@ class AgadeemsAwakeningTarget extends TargetCardInYourGraveyard {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Set<UUID> possibleTargets(UUID sourceId, UUID sourceControllerId, Game game) {
|
||||
Set<UUID> possibleTargets = super.possibleTargets(sourceId, sourceControllerId, game);
|
||||
public Set<UUID> possibleTargets(UUID sourceControllerId, Ability source, Game game) {
|
||||
Set<UUID> possibleTargets = super.possibleTargets(sourceControllerId, source, game);
|
||||
Set<Integer> cmcs = this.getTargets()
|
||||
.stream()
|
||||
.map(game::getCard)
|
||||
|
|
|
@ -86,7 +86,7 @@ class AgitatorAntEffect extends OneShotEffect {
|
|||
}
|
||||
TargetPermanent targetPermanent = new TargetControlledCreaturePermanent(0, 1);
|
||||
targetPermanent.setNotTarget(true);
|
||||
player.choose(Outcome.BoostCreature, targetPermanent, source.getSourceId(), game);
|
||||
player.choose(Outcome.BoostCreature, targetPermanent, source, game);
|
||||
Permanent permanent = game.getPermanent(targetPermanent.getFirstTarget());
|
||||
if (permanent == null || !permanent.addCounters(CounterType.P1P1.createInstance(2), player.getId(), source, game)) {
|
||||
continue;
|
||||
|
|
|
@ -65,7 +65,7 @@ class AidFromTheCowlEffect extends OneShotEffect {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
MageObject sourceObject = game.getObject(source.getSourceId());
|
||||
MageObject sourceObject = game.getObject(source);
|
||||
if (controller == null || sourceObject == null) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -142,11 +142,11 @@ class AkiriFearlessVoyagerEffect extends OneShotEffect {
|
|||
return false;
|
||||
}
|
||||
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)) {
|
||||
return false;
|
||||
}
|
||||
player.choose(outcome, target, source.getSourceId(), game);
|
||||
player.choose(outcome, target, source, game);
|
||||
Permanent equipment = game.getPermanent(target.getFirstTarget());
|
||||
if (equipment == null) {
|
||||
return false;
|
||||
|
|
|
@ -104,7 +104,7 @@ class AkromaVisionOfIxidorEffect extends OneShotEffect {
|
|||
public boolean apply(Game game, Ability source) {
|
||||
for (Permanent permanent : game.getBattlefield().getActivePermanents(
|
||||
StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE,
|
||||
source.getControllerId(), source.getSourceId(), game
|
||||
source.getControllerId(), source, game
|
||||
)) {
|
||||
Abilities<Ability> abilities = permanent.getAbilities(game);
|
||||
int count = classes
|
||||
|
|
|
@ -138,7 +138,7 @@ class AlhammarretHighArbiterCantCastEffect extends ContinuousRuleModifyingEffect
|
|||
|
||||
@Override
|
||||
public String getInfoMessage(Ability source, GameEvent event, Game game) {
|
||||
MageObject mageObject = game.getObject(source.getSourceId());
|
||||
MageObject mageObject = game.getObject(source);
|
||||
if (mageObject != null) {
|
||||
return "You may not cast a card named " + cardName + " (" + mageObject.getIdName() + ").";
|
||||
}
|
||||
|
|
|
@ -91,7 +91,7 @@ class AlibouAncientWitnessEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
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) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -77,7 +77,7 @@ class AlignedHedronNetworkExileEffect extends OneShotEffect {
|
|||
|
||||
// If Whale leaves the battlefield before its triggered ability resolves,
|
||||
// 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; }
|
||||
|
||||
controller.moveCardsToExile(toExile, source, game, true, CardUtil.getCardExileZoneId(game, source), permanent.getIdName());
|
||||
|
|
|
@ -66,7 +66,7 @@ class WellEffect extends OneShotEffect {
|
|||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
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);
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -69,7 +69,7 @@ class AllureOfTheUnknownEffect extends OneShotEffect {
|
|||
return player.moveCards(cards, Zone.HAND, source, game);
|
||||
}
|
||||
TargetOpponent targetOpponent = new TargetOpponent(true);
|
||||
if (!player.choose(outcome, targetOpponent, source.getSourceId(), game)) {
|
||||
if (!player.choose(outcome, targetOpponent, source, game)) {
|
||||
return false;
|
||||
}
|
||||
Player opponent = game.getPlayer(targetOpponent.getFirstTarget());
|
||||
|
|
|
@ -105,7 +105,7 @@ class AminatouPlusEffect extends OneShotEffect {
|
|||
|
||||
private boolean putOnLibrary(Player player, Ability source, Game game) {
|
||||
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);
|
||||
Card card = player.getHand().get(target.getFirstTarget(), game);
|
||||
if (card != null) {
|
||||
|
|
|
@ -82,7 +82,7 @@ class AmuletOfSafekeepingTriggeredAbility extends TriggeredAbilityImpl {
|
|||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
StackObject stackObject = game.getStack().getStackObject(event.getSourceId());
|
||||
if (event.getTargetId().equals(getControllerId())
|
||||
&& filter.match(stackObject, getSourceId(), getControllerId(), game)) {
|
||||
&& filter.match(stackObject, getControllerId(), this, game)) {
|
||||
for (Effect effect : this.getEffects()) {
|
||||
effect.setTargetPointer(new FixedTarget(stackObject.getId(), game));
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ class AnHavvaConstableEffect extends ContinuousEffectImpl {
|
|||
|
||||
FilterCreaturePermanent filter = new FilterCreaturePermanent("green creatures");
|
||||
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);
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ class AnHavvaInnEffect extends OneShotEffect {
|
|||
if (player != null) {
|
||||
FilterCreaturePermanent filter = new FilterCreaturePermanent("green creatures");
|
||||
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);
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -63,8 +63,8 @@ enum AnathemancerCount implements DynamicValue {
|
|||
}
|
||||
return game.getBattlefield().count(
|
||||
StaticFilters.FILTER_LANDS_NONBASIC,
|
||||
sourceAbility.getFirstTarget(),
|
||||
sourceAbility.getControllerId(), game
|
||||
sourceAbility.getControllerId(),
|
||||
sourceAbility, game
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ class AngelOfGlorysRiseEffect extends OneShotEffect {
|
|||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
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);
|
||||
FilterCreatureCard filterHuman = new FilterCreatureCard();
|
||||
filterHuman.add(SubType.HUMAN.getPredicate());
|
||||
|
|
|
@ -57,7 +57,7 @@ class AnimalMagnetismEffect extends OneShotEffect {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
MageObject sourceObject = game.getObject(source.getSourceId());
|
||||
MageObject sourceObject = game.getObject(source);
|
||||
if (sourceObject != null && controller != null) {
|
||||
Cards cards = new CardsImpl(controller.getLibrary().getTopCards(game, 5));
|
||||
if (!cards.isEmpty()) {
|
||||
|
|
|
@ -56,7 +56,7 @@ class AnimistsAwakeningEffect extends OneShotEffect {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
MageObject sourceObject = game.getObject(source.getSourceId());
|
||||
MageObject sourceObject = game.getObject(source);
|
||||
if (controller == null || sourceObject == null) {
|
||||
return false;
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ class AnimistsAwakeningEffect extends OneShotEffect {
|
|||
if (!cards.isEmpty()) {
|
||||
controller.revealCards(sourceObject.getIdName(), cards, game);
|
||||
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);
|
||||
toBattlefield.add(card);
|
||||
}
|
||||
|
|
|
@ -69,7 +69,7 @@ class AnuridScavengerCost extends CostImpl {
|
|||
public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) {
|
||||
Player controller = game.getPlayer(controllerId);
|
||||
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()) {
|
||||
Card card = game.getCard(targetId);
|
||||
if (card == null || game.getState().getZone(targetId) != Zone.GRAVEYARD) {
|
||||
|
@ -85,7 +85,7 @@ class AnuridScavengerCost extends CostImpl {
|
|||
|
||||
@Override
|
||||
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
|
||||
|
|
|
@ -82,7 +82,7 @@ class ArashinWarBeastTriggeredAbility extends TriggeredAbilityImpl {
|
|||
((DamagedEvent) event).isCombatDamage() &&
|
||||
!usedForCombatDamageStep) {
|
||||
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;
|
||||
}
|
||||
// trigger only once per combat damage step
|
||||
|
|
|
@ -96,7 +96,7 @@ class AraumiOfTheDeadTideCost extends CostImpl {
|
|||
int oppCount = game.getOpponents(controllerId).size();
|
||||
TargetCard target = new TargetCardInYourGraveyard(oppCount, StaticFilters.FILTER_CARD);
|
||||
target.setNotTarget(true);
|
||||
player.choose(Outcome.Exile, target, source.getSourceId(), game);
|
||||
player.choose(Outcome.Exile, target, source, game);
|
||||
Cards cards = new CardsImpl(target.getTargets());
|
||||
if (cards.size() < oppCount) {
|
||||
return paid;
|
||||
|
|
|
@ -130,7 +130,7 @@ class ArcbondEffect extends OneShotEffect {
|
|||
public boolean apply(Game game, Ability source) {
|
||||
int damage = (Integer) this.getValue("damage");
|
||||
UUID sourceId = (UUID) this.getValue("sourceId");
|
||||
MageObject sourceObject = game.getObject(source.getSourceId());
|
||||
MageObject sourceObject = game.getObject(source);
|
||||
if (sourceObject != null && damage > 0 && sourceId != null) {
|
||||
Permanent targetObject = game.getPermanentOrLKIBattlefield(sourceId);
|
||||
if (targetObject != null) {
|
||||
|
|
|
@ -72,10 +72,10 @@ enum ArchaeomancersMapCondition implements Condition {
|
|||
UUID playerId = (UUID) source.getEffects().get(0).getValue("permanentEnteringControllerId");
|
||||
return playerId != null && game.getBattlefield().count(
|
||||
StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND,
|
||||
source.getSourceId(), playerId, game
|
||||
playerId, source, game
|
||||
) > game.getBattlefield().count(
|
||||
StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND,
|
||||
source.getSourceId(), source.getControllerId(), game
|
||||
source.getControllerId(), source, game
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -84,8 +84,8 @@ public final class ArchdemonOfGreed extends CardImpl {
|
|||
if (player != null) {
|
||||
TargetControlledPermanent target = new TargetControlledPermanent(1, 1, filter, false);
|
||||
// if they can pay the cost, then they must pay
|
||||
if (target.canChoose(source.getSourceId(), player.getId(), game)) {
|
||||
player.choose(Outcome.Sacrifice, target, source.getSourceId(), game);
|
||||
if (target.canChoose(player.getId(), source, game)) {
|
||||
player.choose(Outcome.Sacrifice, target, source, game);
|
||||
Permanent humanSacrifice = game.getPermanent(target.getFirstTarget());
|
||||
if (humanSacrifice != null) {
|
||||
// sacrifice the chosen card
|
||||
|
|
|
@ -73,7 +73,7 @@ class ArchfiendOfDepravityEffect extends OneShotEffect {
|
|||
List<Permanent> creaturesToSacrifice = new ArrayList<>();
|
||||
TargetControlledPermanent target = new TargetControlledPermanent(0, 2, new FilterControlledCreaturePermanent("creatures to keep"), true);
|
||||
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())) {
|
||||
creaturesToSacrifice.add(permanent);
|
||||
}
|
||||
|
|
|
@ -68,6 +68,6 @@ enum ArcticFoxesCondition implements Condition {
|
|||
if (defenderId == null) {
|
||||
return false;
|
||||
}
|
||||
return game.getBattlefield().contains(filter, source.getSourceId(), defenderId, game, 1);
|
||||
return game.getBattlefield().contains(filter, source.getSourceId(), defenderId, source, game, 1);
|
||||
}
|
||||
}
|
|
@ -88,7 +88,7 @@ class ArdennIntrepidArchaeologistEffect extends OneShotEffect {
|
|||
return false;
|
||||
}
|
||||
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()) {
|
||||
if (player != null) {
|
||||
player.addAttachment(targetId, source, game);
|
||||
|
|
|
@ -79,7 +79,7 @@ class ArdentDustspeakerCost extends CostImpl {
|
|||
|
||||
@Override
|
||||
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
|
||||
|
|
|
@ -108,12 +108,12 @@ class ArmedAndArmoredEquipEffect extends OneShotEffect {
|
|||
if (!dwarves.isEmpty() && !equipment.isEmpty()) {
|
||||
TargetPermanent target = new TargetPermanent(0, 1, dwarfFilter, true);
|
||||
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());
|
||||
if (dwarf != null) {
|
||||
target = new TargetPermanent(0, Integer.MAX_VALUE, equipmentFilter, true);
|
||||
target.withChooseHint("equip to " + dwarf.getLogName());
|
||||
controller.choose(outcome, target, source.getId(), game);
|
||||
controller.choose(outcome, target, source, game);
|
||||
for (UUID targetId : target.getTargets()) {
|
||||
dwarf.addAttachment(targetId, source, game);
|
||||
game.informPlayers(game.getPermanent(targetId).getLogName() + " was attached to " + dwarf.getLogName());
|
||||
|
|
|
@ -100,7 +100,7 @@ class ArmoredSkyhunterEffect extends OneShotEffect {
|
|||
}
|
||||
TargetPermanent targetPermanent = new TargetControlledCreaturePermanent(0, 1);
|
||||
targetCard.setNotTarget(true);
|
||||
player.choose(outcome, targetPermanent, source.getSourceId(), game);
|
||||
player.choose(outcome, targetPermanent, source, game);
|
||||
Permanent permanent = game.getPermanent(targetPermanent.getFirstTarget());
|
||||
if (permanent != null) {
|
||||
permanent.addAttachment(equipment.getId(), source, game);
|
||||
|
|
|
@ -88,7 +88,7 @@ class ArmoryAutomatonEffect extends OneShotEffect {
|
|||
while (player.canRespond() && countBattlefield > 0 && player.chooseUse(Outcome.Benefit, "Select and attach a target Equipment?", source, game)) {
|
||||
Target targetEquipment = new TargetPermanent(currentFilter);
|
||||
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
|
||||
|
||||
Permanent aura = game.getPermanent(targetEquipment.getFirstTarget());
|
||||
|
|
|
@ -69,7 +69,7 @@ class ArniBrokenbrowEffect extends OneShotEffect {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
MageObject mageObject = game.getObject(source.getSourceId());
|
||||
MageObject mageObject = game.getObject(source);
|
||||
if (controller == null || mageObject == null) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ import mage.constants.Outcome;
|
|||
import mage.constants.SubType;
|
||||
import mage.counters.CounterType;
|
||||
import mage.filter.common.FilterArtifactCard;
|
||||
import mage.filter.predicate.mageobject.AnotherCardPredicate;
|
||||
import mage.filter.predicate.mageobject.AnotherPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
|
@ -75,12 +75,12 @@ class ArsenalThresherEffect extends OneShotEffect {
|
|||
}
|
||||
Permanent arsenalThresher = game.getPermanentEntering(source.getSourceId());
|
||||
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)) {
|
||||
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);
|
||||
if (controller.choose(Outcome.Benefit, target, source.getSourceId(), game)) {
|
||||
if (controller.choose(Outcome.Benefit, target, source, game)) {
|
||||
for (UUID uuid : target.getTargets()) {
|
||||
cards.add(controller.getHand().get(uuid, game));
|
||||
}
|
||||
|
|
|
@ -74,7 +74,7 @@ class ArterialAlchemyEffect extends ContinuousEffectImpl {
|
|||
@Override
|
||||
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
|
||||
for (Permanent permanent : game.getBattlefield().getActivePermanents(
|
||||
filter, source.getControllerId(), source.getSourceId(), game
|
||||
filter, source.getControllerId(), source, game
|
||||
)) {
|
||||
switch (layer) {
|
||||
case TypeChangingEffects_4:
|
||||
|
|
|
@ -95,7 +95,7 @@ class AryelTapXTargetCost extends VariableCostImpl {
|
|||
|
||||
@Override
|
||||
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
|
||||
|
|
|
@ -69,7 +69,7 @@ class SpellWithManaCostLessThanOrEqualToCondition implements Condition {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
MageObject object = game.getObject(source.getSourceId());
|
||||
MageObject object = game.getObject(source);
|
||||
return object != null
|
||||
&& !object.isLand(game)
|
||||
&& object.getManaValue() <= counters;
|
||||
|
|
|
@ -71,7 +71,7 @@ enum AscendantAcolyteValue implements DynamicValue {
|
|||
.getActivePermanents(
|
||||
StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE,
|
||||
sourceAbility.getControllerId(),
|
||||
sourceAbility.getSourceId(), game
|
||||
sourceAbility, game
|
||||
).stream()
|
||||
.mapToInt(permanent -> permanent.getCounters(game).getCount(CounterType.P1P1))
|
||||
.sum();
|
||||
|
|
|
@ -87,10 +87,10 @@ class AscentOfTheWorthyEffect extends OneShotEffect {
|
|||
}
|
||||
TargetPermanent target = new TargetControlledCreaturePermanent();
|
||||
target.setNotTarget(true);
|
||||
if (!target.canChoose(source.getSourceId(), source.getControllerId(), game)) {
|
||||
if (!target.canChoose(source.getControllerId(), source, game)) {
|
||||
return false;
|
||||
}
|
||||
player.choose(outcome, target, source.getControllerId(), game);
|
||||
player.choose(outcome, target, source, game);
|
||||
Permanent permanent = game.getPermanent(target.getFirstTarget());
|
||||
if (permanent == null) {
|
||||
return false;
|
||||
|
|
|
@ -77,7 +77,7 @@ class AshayaSoulOfTheWildEffect extends ContinuousEffectImpl {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
for (Permanent permanent : game.getBattlefield().getActivePermanents(
|
||||
filter, source.getControllerId(), source.getSourceId(), game
|
||||
filter, source.getControllerId(), source, game
|
||||
)) {
|
||||
if (!permanent.isLand(game)) {
|
||||
permanent.addCardType(game, CardType.LAND);
|
||||
|
|
|
@ -73,7 +73,7 @@ class AshiokDreamRenderEffect extends ContinuousRuleModifyingEffectImpl {
|
|||
|
||||
@Override
|
||||
public String getInfoMessage(Ability source, GameEvent event, Game game) {
|
||||
MageObject mageObject = game.getObject(source.getSourceId());
|
||||
MageObject mageObject = game.getObject(source);
|
||||
if (mageObject != null) {
|
||||
return "You can't search libraries (" + mageObject.getLogName() + " in play).";
|
||||
}
|
||||
|
|
|
@ -120,7 +120,7 @@ class AshiokNightmareWeaverPutIntoPlayEffect extends OneShotEffect {
|
|||
|
||||
Target target = new TargetCardInExile(filter, CardUtil.getExileZoneId(game, source));
|
||||
|
||||
if (!target.canChoose(source.getSourceId(), controller.getId(), game)) {
|
||||
if (!target.canChoose(controller.getId(), source, game)) {
|
||||
return false;
|
||||
}
|
||||
controller.chooseTarget(Outcome.PutCreatureInPlay, target, source, game);
|
||||
|
|
|
@ -66,7 +66,7 @@ enum AspectOfWolfValue implements DynamicValue {
|
|||
@Override
|
||||
public int calculate(Game game, Ability sourceAbility, Effect effect) {
|
||||
int forestCount = game.getBattlefield().count(
|
||||
filter, sourceAbility.getSourceId(), sourceAbility.getControllerId(), game
|
||||
filter, sourceAbility.getControllerId(), sourceAbility, game
|
||||
);
|
||||
return forestCount / 2 + (up ? forestCount % 2 : 0);
|
||||
}
|
||||
|
|
|
@ -70,7 +70,7 @@ class AssemblyHallEffect extends OneShotEffect {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
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) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -82,7 +82,7 @@ class AtarkaWorldRenderEffect extends TriggeredAbilityImpl {
|
|||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
Permanent attacker = game.getPermanent(event.getSourceId());
|
||||
if (attacker != null
|
||||
&& filter.match(attacker, sourceId, controllerId, game)) {
|
||||
&& filter.match(attacker, controllerId, this, game)) {
|
||||
for (Effect effect : this.getEffects()) {
|
||||
effect.setTargetPointer(new FixedTarget(attacker.getId(), game));
|
||||
}
|
||||
|
|
|
@ -144,7 +144,7 @@ class AthreosDiesCreatureTriggeredAbility extends TriggeredAbilityImpl {
|
|||
if (!zEvent.isDiesEvent()) {
|
||||
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;
|
||||
}
|
||||
for (Effect effect : this.getEffects()) {
|
||||
|
|
|
@ -72,18 +72,18 @@ class AugurOfBolasEffect extends OneShotEffect {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
MageObject sourceObject = game.getObject(source.getSourceId());
|
||||
MageObject sourceObject = game.getObject(source);
|
||||
if (controller != null && sourceObject != null) {
|
||||
Cards topCards = new CardsImpl();
|
||||
topCards.addAll(controller.getLibrary().getTopCards(game, 3));
|
||||
if (!topCards.isEmpty()) {
|
||||
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 (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;
|
||||
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()) {
|
||||
card = cards.iterator().next();
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@ import mage.filter.predicate.Predicates;
|
|||
import mage.game.Game;
|
||||
import mage.game.events.DamagedPlayerEvent;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.events.GameEvent.EventType;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
/**
|
||||
|
@ -83,7 +82,7 @@ class AuntiesSnitchTriggeredAbility extends TriggeredAbilityImpl {
|
|||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
DamagedPlayerEvent damageEvent = (DamagedPlayerEvent)event;
|
||||
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
|
||||
|
|
|
@ -54,7 +54,7 @@ public final class AuraBarbs extends CardImpl {
|
|||
FilterPermanent filterEnchantments = new FilterPermanent();
|
||||
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());
|
||||
if (controller != null) {
|
||||
controller.damage(2, permanent.getId(), source, game);
|
||||
|
@ -63,7 +63,7 @@ public final class AuraBarbs extends CardImpl {
|
|||
}
|
||||
|
||||
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) {
|
||||
Permanent attachedToCreature = game.getPermanent(auraEnchantment.getAttachedTo());
|
||||
if (attachedToCreature != null && attachedToCreature.isCreature(game)) {
|
||||
|
|
|
@ -123,8 +123,8 @@ class MoveTargetAuraEffect extends OneShotEffect {
|
|||
filter.add(new PermanentCanBeAttachedToPredicate(enchantment));
|
||||
Target target = new TargetPermanent(filter);
|
||||
target.setNotTarget(true);
|
||||
if (target.canChoose(oldAttachment.getId(), controller.getId(), game)
|
||||
&& controller.choose(outcome, target, oldAttachment.getId(), game)) {
|
||||
if (target.canChoose(controller.getId(), source, game)
|
||||
&& controller.choose(outcome, target, source, game)) {
|
||||
Permanent newAttachment = game.getPermanent(target.getFirstTarget());
|
||||
if (newAttachment != null
|
||||
&& oldAttachment.removeAttachment(enchantment.getId(), source, game)) {
|
||||
|
|
|
@ -71,7 +71,7 @@ class AuraThiefDiesTriggeredEffect extends OneShotEffect {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
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);
|
||||
gainControl.setTargetPointer(new FixedTarget(enchantment.getId(), game));
|
||||
game.addEffect(gainControl, source);
|
||||
|
|
|
@ -140,7 +140,7 @@ class AureliasFuryCantCastEffect extends ContinuousRuleModifyingEffectImpl {
|
|||
|
||||
@Override
|
||||
public String getInfoMessage(Ability source, GameEvent event, Game game) {
|
||||
MageObject mageObject = game.getObject(source.getSourceId());
|
||||
MageObject mageObject = game.getObject(source);
|
||||
if (mageObject != null) {
|
||||
return "You can't cast noncreature spells this turn (you were dealt damage by " + mageObject.getLogName() + ')';
|
||||
}
|
||||
|
|
|
@ -111,7 +111,7 @@ class SacrificeAllEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
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) {
|
||||
p.sacrifice(source, game);
|
||||
}
|
||||
|
|
|
@ -90,7 +90,7 @@ class AvenShrineEffect extends OneShotEffect {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
int count = 0;
|
||||
MageObject mageObject = game.getObject(source.getSourceId());
|
||||
MageObject mageObject = game.getObject(source);
|
||||
if(mageObject != null) {
|
||||
Spell spell = (Spell) game.getState().getValue("avenShrine" + mageObject);
|
||||
if (spell != null) {
|
||||
|
|
|
@ -81,7 +81,7 @@ class AvenSoulgazerLookFaceDownEffect extends OneShotEffect {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
MageObject mageObject = game.getObject(source.getSourceId());
|
||||
MageObject mageObject = game.getObject(source);
|
||||
if (player == null || mageObject == null) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -113,7 +113,7 @@ class AzorTheLawbringerCantCastEffect extends ContinuousRuleModifyingEffectImpl
|
|||
|
||||
@Override
|
||||
public String getInfoMessage(Ability source, GameEvent event, Game game) {
|
||||
MageObject mageObject = game.getObject(source.getSourceId());
|
||||
MageObject mageObject = game.getObject(source);
|
||||
if (mageObject != null) {
|
||||
return "You can't cast instant or sorcery spells this turn (" + mageObject.getIdName() + ").";
|
||||
}
|
||||
|
|
|
@ -80,7 +80,7 @@ class AzoriusAEthermageAbility extends TriggeredAbilityImpl {
|
|||
return false;
|
||||
}
|
||||
|
||||
return StaticFilters.FILTER_PERMANENT_CREATURE.match(permanentThatMoved, sourceId, controllerId, game);
|
||||
return StaticFilters.FILTER_PERMANENT_CREATURE.match(permanentThatMoved, controllerId, this, game);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -87,7 +87,7 @@ class AzorsGatewayEffect extends OneShotEffect {
|
|||
|
||||
controller.drawCards(1, source, game);
|
||||
TargetCardInHand target = new TargetCardInHand();
|
||||
controller.choose(outcome, target, source.getSourceId(), game);
|
||||
controller.choose(outcome, target, source, game);
|
||||
Card cardToExile = game.getCard(target.getFirstTarget());
|
||||
if (cardToExile != null) {
|
||||
controller.moveCardsToExile(cardToExile, source, game, true, exileId, sourceObject.getIdName());
|
||||
|
|
|
@ -75,7 +75,7 @@ class AzraBladeseekerEffect extends OneShotEffect {
|
|||
continue;
|
||||
}
|
||||
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());
|
||||
if (card != null) {
|
||||
playerCardList.add(new PlayerCard(player, card));
|
||||
|
|
|
@ -82,7 +82,7 @@ class AzraOddsmakerEffect extends OneShotEffect {
|
|||
Permanent permanent = null;
|
||||
TargetCreaturePermanent target = new TargetCreaturePermanent();
|
||||
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());
|
||||
}
|
||||
if (permanent == null) {
|
||||
|
|
|
@ -83,7 +83,7 @@ class BingoEffect extends OneShotEffect {
|
|||
if (spell.getManaValue() > 9) {
|
||||
return true;
|
||||
}
|
||||
MageObject mageObject = game.getObject(source.getSourceId());
|
||||
MageObject mageObject = game.getObject(source);
|
||||
if (mageObject != null) {
|
||||
Map<Integer, Integer> chipCounters = new HashMap<>(); // Map<number, amount of counters>
|
||||
if (game.getState().getValue(mageObject.getId() + "_chip") != null) {
|
||||
|
|
|
@ -67,12 +67,12 @@ class BackFromTheBrinkCost extends CostImpl {
|
|||
|
||||
@Override
|
||||
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
|
||||
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);
|
||||
if (controller != null) {
|
||||
Card card = controller.getGraveyard().get(targets.getFirstTarget(), game);
|
||||
|
|
|
@ -113,7 +113,7 @@ class BagOfDevouringEffect extends OneShotEffect {
|
|||
CardUtil.getExileZoneId(game, source)
|
||||
);
|
||||
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);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ class BakisCurseEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
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;
|
||||
List<UUID> attachments = creature.getAttachments();
|
||||
for (UUID attachmentId : attachments) {
|
||||
|
|
|
@ -64,7 +64,7 @@ class BalancingActEffect extends OneShotEffect {
|
|||
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
|
||||
Player player = game.getPlayer(playerId);
|
||||
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) {
|
||||
minPermanent = count;
|
||||
}
|
||||
|
@ -75,8 +75,8 @@ class BalancingActEffect extends OneShotEffect {
|
|||
Player player = game.getPlayer(playerId);
|
||||
if (player != null) {
|
||||
TargetControlledPermanent target = new TargetControlledPermanent(minPermanent, minPermanent, new FilterControlledPermanent(), true);
|
||||
if (target.choose(Outcome.Benefit, player.getId(), source.getSourceId(), game)) {
|
||||
for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterControlledPermanent(), 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, game)) {
|
||||
if (permanent != null && !target.getTargets().contains(permanent.getId())) {
|
||||
permanent.sacrifice(source, game);
|
||||
}
|
||||
|
@ -101,7 +101,7 @@ class BalancingActEffect extends OneShotEffect {
|
|||
Player player = game.getPlayer(playerId);
|
||||
if (player != null) {
|
||||
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.removeIf(target.getTargets()::contains);
|
||||
player.discard(cards, false, source, game);
|
||||
|
|
|
@ -115,8 +115,8 @@ class BalduvianWarlordUnblockEffect extends OneShotEffect {
|
|||
FilterAttackingCreature filter = new FilterAttackingCreature("creature attacking " + targetsController.getLogName());
|
||||
filter.add(new PermanentInListPredicate(list));
|
||||
TargetAttackingCreature target = new TargetAttackingCreature(1, 1, filter, true);
|
||||
if (target.canChoose(source.getSourceId(), controller.getId(), game)) {
|
||||
while (!target.isChosen() && target.canChoose(source.getSourceId(), controller.getId(), game) && controller.canRespond()) {
|
||||
if (target.canChoose(controller.getId(), source, game)) {
|
||||
while (!target.isChosen() && target.canChoose(controller.getId(), source, game) && controller.canRespond()) {
|
||||
controller.chooseTarget(outcome, target, source, game);
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -89,7 +89,7 @@ class BalthorTheDefiledEffect extends OneShotEffect {
|
|||
for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) {
|
||||
Player player = game.getPlayer(playerId);
|
||||
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);
|
||||
|
|
|
@ -70,7 +70,7 @@ class BaneOfProgressEffect extends OneShotEffect {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
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)) {
|
||||
destroyedPermanents++;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package mage.cards.b;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.MageObjectReference;
|
||||
import mage.abilities.common.BecomesBlockedSourceTriggeredAbility;
|
||||
import mage.abilities.common.DiesCreatureTriggeredAbility;
|
||||
import mage.abilities.effects.common.LoseLifeTargetControllerEffect;
|
||||
|
@ -12,18 +11,10 @@ import mage.cards.CardSetInfo;
|
|||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.WatcherScope;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.filter.predicate.ObjectSourcePlayer;
|
||||
import mage.filter.predicate.ObjectSourcePlayerPredicate;
|
||||
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
|
||||
|
@ -31,11 +22,9 @@ import java.util.*;
|
|||
public final class BaneclawMarauder extends CardImpl {
|
||||
|
||||
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent();
|
||||
private static final FilterPermanent filter2 = new FilterCreaturePermanent("a creature blocking {this}");
|
||||
|
||||
static {
|
||||
filter.add(BlockingOrBlockedBySourcePredicate.BLOCKING);
|
||||
filter2.add(BaneclawMarauderPredicate.instance);
|
||||
}
|
||||
|
||||
public BaneclawMarauder(UUID ownerId, CardSetInfo setInfo) {
|
||||
|
@ -56,8 +45,8 @@ public final class BaneclawMarauder extends CardImpl {
|
|||
this.addAbility(new DiesCreatureTriggeredAbility(
|
||||
new LoseLifeTargetControllerEffect(1)
|
||||
.setText("that creature's controller loses 1 life"),
|
||||
false, filter2, true
|
||||
), new BaneclawMarauderWatcher());
|
||||
false, filter, true
|
||||
));
|
||||
|
||||
// Nightbound
|
||||
this.addAbility(new NightboundAbility());
|
||||
|
@ -72,55 +61,3 @@ public final class BaneclawMarauder extends CardImpl {
|
|||
return new BaneclawMarauder(this);
|
||||
}
|
||||
}
|
||||
|
||||
enum BaneclawMarauderPredicate implements ObjectSourcePlayerPredicate<Permanent> {
|
||||
instance;
|
||||
|
||||
@Override
|
||||
public boolean apply(ObjectSourcePlayer<Permanent> input, Game game) {
|
||||
return BaneclawMarauderWatcher.check(input.getSourceId(), input.getObject(), game);
|
||||
}
|
||||
}
|
||||
|
||||
class BaneclawMarauderWatcher extends Watcher {
|
||||
|
||||
private final Map<MageObjectReference, Set<MageObjectReference>> blockerMap = new HashMap<>();
|
||||
|
||||
BaneclawMarauderWatcher() {
|
||||
super(WatcherScope.GAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void watch(GameEvent event, Game game) {
|
||||
switch (event.getType()) {
|
||||
case BLOCKER_DECLARED:
|
||||
blockerMap
|
||||
.computeIfAbsent(new MageObjectReference(event.getTargetId(), game), x -> new HashSet<>())
|
||||
.add(new MageObjectReference(event.getSourceId(), game));
|
||||
return;
|
||||
case END_COMBAT_STEP_POST:
|
||||
blockerMap.clear();
|
||||
return;
|
||||
case REMOVED_FROM_COMBAT:
|
||||
blockerMap
|
||||
.values()
|
||||
.stream()
|
||||
.forEach(set -> set.removeIf(mor -> mor.refersTo(event.getTargetId(), game)));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
super.reset();
|
||||
blockerMap.clear();
|
||||
}
|
||||
|
||||
static boolean check(UUID sourceId, Permanent blocker, Game game) {
|
||||
return game.getState()
|
||||
.getWatcher(BaneclawMarauderWatcher.class)
|
||||
.blockerMap
|
||||
.getOrDefault(new MageObjectReference(sourceId, game), Collections.emptySet())
|
||||
.stream()
|
||||
.anyMatch(mor -> mor.refersTo(blocker, game));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
|
||||
package mage.cards.b;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.ObjectColor;
|
||||
import mage.abilities.Ability;
|
||||
|
@ -13,30 +11,37 @@ import mage.cards.CardSetInfo;
|
|||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.filter.predicate.mageobject.ColorPredicate;
|
||||
import mage.filter.predicate.permanent.BlockingAttackerIdPredicate;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
import mage.filter.predicate.permanent.BlockingOrBlockedBySourcePredicate;
|
||||
import mage.target.TargetPermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LoneFox
|
||||
*/
|
||||
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) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{B}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}");
|
||||
this.subtype.add(SubType.WURM);
|
||||
this.power = new MageInt(4);
|
||||
this.toughness = new MageInt(3);
|
||||
|
||||
// {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}"));
|
||||
FilterCreaturePermanent filter = new FilterCreaturePermanent("green creature blocking {this}");
|
||||
filter.add(new ColorPredicate(ObjectColor.GREEN));
|
||||
filter.add(new BlockingAttackerIdPredicate(this.getId()));
|
||||
ability.addTarget(new TargetCreaturePermanent(filter));
|
||||
Ability ability = new SimpleActivatedAbility(new BoostTargetEffect(
|
||||
-1, -1, Duration.EndOfTurn
|
||||
), new ManaCostsImpl<>("{B}"));
|
||||
ability.addTarget(new TargetPermanent(filter));
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
|
|
|
@ -76,7 +76,7 @@ class BaronVonCountPutCounterEffect extends OneShotEffect {
|
|||
Player controller = game.getPlayer(source.getControllerId());
|
||||
MageObject mageObject = game.getPermanentEntering(source.getSourceId());
|
||||
if (mageObject == null) {
|
||||
mageObject = game.getObject(source.getSourceId());
|
||||
mageObject = game.getObject(source);
|
||||
}
|
||||
if (controller != null && mageObject != null) {
|
||||
Integer doomNumber = 5;
|
||||
|
@ -172,7 +172,7 @@ class BaronVonCountMoveDoomCounterEffect extends OneShotEffect {
|
|||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
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 (game.getState().getValue(mageObject.getId() + "_doom") == null) {
|
||||
return false;
|
||||
|
@ -249,7 +249,7 @@ class BaronVonCountDestroyPlayerEffect extends OneShotEffect {
|
|||
targetPlayer.lost(game); // double checks canLose, but seems more future-proof than lostForced
|
||||
}
|
||||
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
|
||||
MageObject mageObject = game.getObject(source.getSourceId());
|
||||
MageObject mageObject = game.getObject(source);
|
||||
if (sourcePermanent != null && mageObject != null) {
|
||||
if (game.getState().getValue(mageObject.getId() + "_doom") == null) {
|
||||
return false;
|
||||
|
|
|
@ -75,7 +75,7 @@ enum BaseCampCondition implements Condition {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
MageObject object = game.getObject(source.getSourceId());
|
||||
MageObject object = game.getObject(source);
|
||||
return object != null && (
|
||||
object.hasSubtype(SubType.CLERIC, game)
|
||||
|| object.hasSubtype(SubType.ROGUE, game)
|
||||
|
|
|
@ -87,7 +87,7 @@ class BatheInLightEffect extends OneShotEffect {
|
|||
ContinuousEffect effect = new ProtectionChosenColorTargetEffect();
|
||||
game.addEffect(effect, source);
|
||||
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)) {
|
||||
game.getState().setValue(permanent.getId() + "_color", colorChoice.getColor());
|
||||
effect.setTargetPointer(new FixedTarget(permanent, game));
|
||||
|
|
|
@ -89,7 +89,7 @@ class BattleForBretagardEffect extends OneShotEffect {
|
|||
return false;
|
||||
}
|
||||
TargetPermanent target = new BattleForBretagardTarget();
|
||||
player.choose(outcome, target, source.getSourceId(), game);
|
||||
player.choose(outcome, target, source, game);
|
||||
for (UUID targetId : target.getTargets()) {
|
||||
new CreateTokenCopyTargetEffect()
|
||||
.setTargetPointer(new FixedTarget(targetId, game))
|
||||
|
@ -145,8 +145,8 @@ class BattleForBretagardTarget extends TargetPermanent {
|
|||
|
||||
|
||||
@Override
|
||||
public Set<UUID> possibleTargets(UUID sourceId, UUID sourceControllerId, Game game) {
|
||||
Set<UUID> possibleTargets = super.possibleTargets(sourceId, sourceControllerId, game);
|
||||
public Set<UUID> possibleTargets(UUID sourceControllerId, Ability source, Game game) {
|
||||
Set<UUID> possibleTargets = super.possibleTargets(sourceControllerId, source, game);
|
||||
Set<String> names = this.getTargets()
|
||||
.stream()
|
||||
.map(game::getPermanent)
|
||||
|
|
|
@ -68,7 +68,7 @@ class BattlefieldScroungerCost extends CostImpl {
|
|||
public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) {
|
||||
Player controller = game.getPlayer(controllerId);
|
||||
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()) {
|
||||
Card card = game.getCard(targetId);
|
||||
if (card == null || game.getState().getZone(targetId) != Zone.GRAVEYARD) {
|
||||
|
@ -84,7 +84,7 @@ class BattlefieldScroungerCost extends CostImpl {
|
|||
|
||||
@Override
|
||||
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
|
||||
|
|
|
@ -99,7 +99,7 @@ class BattlefieldThaumaturgeSpellsCostReductionEffect extends CostModificationEf
|
|||
if (target.isNotTarget()) {
|
||||
continue;
|
||||
}
|
||||
Set<UUID> possibleList = target.possibleTargets(ability.getSourceId(), ability.getControllerId(), game);
|
||||
Set<UUID> possibleList = target.possibleTargets(ability.getControllerId(), ability, game);
|
||||
possibleList.removeIf(id -> {
|
||||
Permanent permanent = game.getPermanent(id);
|
||||
return permanent == null || !permanent.isCreature(game);
|
||||
|
|
|
@ -71,7 +71,7 @@ class BeaconOfDestinyEffect extends RedirectionEffect {
|
|||
|
||||
@Override
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -112,7 +112,7 @@ class BeamsplitterMageTriggeredAbility extends TriggeredAbilityImpl {
|
|||
}
|
||||
return game.getBattlefield().getActivePermanents(
|
||||
StaticFilters.FILTER_CONTROLLED_CREATURE,
|
||||
getControllerId(), getSourceId(), game
|
||||
getControllerId(), this, game
|
||||
).stream()
|
||||
.filter(Objects::nonNull)
|
||||
.filter(permanent -> permanent.isCreature(game))
|
||||
|
@ -165,7 +165,7 @@ class BeamsplitterMageEffect extends OneShotEffect {
|
|||
filter.add(new BeamsplitterMagePredicate(spell));
|
||||
TargetPermanent target = new TargetPermanent(filter);
|
||||
target.setNotTarget(true);
|
||||
player.choose(outcome, target, source.getSourceId(), game);
|
||||
player.choose(outcome, target, source, game);
|
||||
Permanent permanent = game.getPermanent(target.getFirstTarget());
|
||||
if (permanent == null) {
|
||||
return false;
|
||||
|
|
|
@ -14,7 +14,6 @@ import mage.constants.SpellAbilityType;
|
|||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.events.GameEvent.EventType;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.permanent.token.BirdToken;
|
||||
|
||||
|
@ -65,7 +64,7 @@ class BeckTriggeredAbility extends DelayedTriggeredAbility {
|
|||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
UUID targetId = event.getTargetId();
|
||||
Permanent permanent = game.getPermanent(targetId);
|
||||
return filter.match(permanent, getSourceId(), getControllerId(), game);
|
||||
return filter.match(permanent, getControllerId(), this, game);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -96,7 +96,7 @@ class BendOrBreakEffect extends OneShotEffect {
|
|||
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)");
|
||||
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
|
||||
currentPlayer.chooseTarget(Outcome.Neutral, target, source, game);
|
||||
|
|
|
@ -61,7 +61,7 @@ class BenefactionOfRhonasEffect extends OneShotEffect {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
MageObject sourceObject = game.getObject(source.getSourceId());
|
||||
MageObject sourceObject = game.getObject(source);
|
||||
if (sourceObject != null && controller != null) {
|
||||
Cards cards = new CardsImpl(controller.getLibrary().getTopCards(game, 5));
|
||||
boolean creatureCardFound = false;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue