Merge branch 'master' into add-minimum-rating-option

This commit is contained in:
Aaron Miller 2018-09-29 19:15:46 -07:00
commit 5cd57199c7
348 changed files with 1560 additions and 1096 deletions

View file

@ -9,7 +9,7 @@ import java.util.UUID;
import mage.abilities.Abilities;
import mage.abilities.AbilitiesImpl;
import mage.abilities.Ability;
import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility;
import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.costs.mana.ManaCost;
import mage.abilities.costs.mana.ManaCosts;
import mage.abilities.costs.mana.ManaCostsImpl;
@ -158,8 +158,8 @@ public abstract class MageObjectImpl implements MageObject {
@Override
public int getStartingLoyalty() {
for (Ability ab : getAbilities()) {
if (ab instanceof PlanswalkerEntersWithLoyalityCountersAbility) {
return ((PlanswalkerEntersWithLoyalityCountersAbility) ab).getStartingLoyalty();
if (ab instanceof PlaneswalkerEntersWithLoyaltyCountersAbility) {
return ((PlaneswalkerEntersWithLoyaltyCountersAbility) ab).getStartingLoyalty();
}
}
return 0;

View file

@ -10,7 +10,6 @@ import mage.constants.Zone;
import mage.game.Game;
/**
*
* @author LevelX2
*/
public class ActivateIfConditionActivatedAbility extends ActivatedAbilityImpl {
@ -37,15 +36,12 @@ public class ActivateIfConditionActivatedAbility extends ActivatedAbilityImpl {
} else {
sb.append(" Activate this ability only ");
}
if (condition.toString() != null) {
if (!condition.toString().startsWith("during")
&& !condition.toString().startsWith("before")) {
sb.append("if ");
}
sb.append(condition.toString()).append('.');
} else {
sb.append(" [Condition toString() == null] ");
if (!condition.toString().startsWith("during")
&& !condition.toString().startsWith("before")) {
sb.append("if ");
}
sb.append(condition.toString()).append('.');
return sb.toString();
}

View file

@ -62,41 +62,40 @@ public class DiesAttachedTriggeredAbility extends TriggeredAbilityImpl {
if (((ZoneChangeEvent) event).isDiesEvent()) {
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
boolean triggered = false;
if (zEvent != null) {
if (zEvent.getTarget() != null && zEvent.getTarget().getAttachments() != null && zEvent.getTarget().getAttachments().contains(this.getSourceId())) {
triggered = true;
} else {
// If both (attachment and attached went to graveyard at the same time, the attachemnets can be already removed from the attached object.)
// So check here with the LKI of the enchantment
Permanent attachment = game.getPermanentOrLKIBattlefield(getSourceId());
if (attachment != null
&& zEvent.getTargetId() != null && attachment.getAttachedTo() != null
&& zEvent.getTargetId().equals(attachment.getAttachedTo())) {
Permanent attachedTo = game.getPermanentOrLKIBattlefield(attachment.getAttachedTo());
if (attachedTo != null
&& attachment.getAttachedToZoneChangeCounter() == attachedTo.getZoneChangeCounter(game)) { // zoneChangeCounter is stored in Permanent
triggered = true;
if (zEvent.getTarget() != null && zEvent.getTarget().getAttachments() != null && zEvent.getTarget().getAttachments().contains(this.getSourceId())) {
triggered = true;
} else {
// If both (attachment and attached went to graveyard at the same time, the attachemnets can be already removed from the attached object.)
// So check here with the LKI of the enchantment
Permanent attachment = game.getPermanentOrLKIBattlefield(getSourceId());
if (attachment != null
&& zEvent.getTargetId() != null && attachment.getAttachedTo() != null
&& zEvent.getTargetId().equals(attachment.getAttachedTo())) {
Permanent attachedTo = game.getPermanentOrLKIBattlefield(attachment.getAttachedTo());
if (attachedTo != null
&& attachment.getAttachedToZoneChangeCounter() == attachedTo.getZoneChangeCounter(game)) { // zoneChangeCounter is stored in Permanent
triggered = true;
}
}
}
if (triggered) {
for (Effect effect : getEffects()) {
if (zEvent.getTarget() != null) {
effect.setValue("attachedTo", zEvent.getTarget());
if (setTargetPointer == SetTargetPointer.ATTACHED_TO_CONTROLLER) {
Permanent attachment = game.getPermanentOrLKIBattlefield(getSourceId());
if (attachment != null && attachment.getAttachedTo() != null) {
Permanent attachedTo = (Permanent) game.getLastKnownInformation(attachment.getAttachedTo(), Zone.BATTLEFIELD, attachment.getAttachedToZoneChangeCounter());
if (attachedTo != null) {
effect.setTargetPointer(new FixedTarget(attachedTo.getControllerId()));
}
}
}
}
}
if (triggered) {
for (Effect effect : getEffects()) {
if (zEvent.getTarget() != null) {
effect.setValue("attachedTo", zEvent.getTarget());
if (setTargetPointer == SetTargetPointer.ATTACHED_TO_CONTROLLER) {
Permanent attachment = game.getPermanentOrLKIBattlefield(getSourceId());
if (attachment != null && attachment.getAttachedTo() != null) {
Permanent attachedTo = (Permanent) game.getLastKnownInformation(attachment.getAttachedTo(), Zone.BATTLEFIELD, attachment.getAttachedToZoneChangeCounter());
if (attachedTo != null) {
effect.setTargetPointer(new FixedTarget(attachedTo.getControllerId()));
}
}
}
}
}
return true;
}
return true;
}
}
return false;
}

View file

@ -12,17 +12,17 @@ import mage.counters.CounterType;
*
* @author LevelX2
*/
public class PlanswalkerEntersWithLoyalityCountersAbility extends EntersBattlefieldAbility {
public class PlaneswalkerEntersWithLoyaltyCountersAbility extends EntersBattlefieldAbility {
private final int startingLoyalty;
public PlanswalkerEntersWithLoyalityCountersAbility(int loyalty) {
public PlaneswalkerEntersWithLoyaltyCountersAbility(int loyalty) {
super(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(loyalty)));
startingLoyalty = loyalty;
setRuleVisible(false);
}
public PlanswalkerEntersWithLoyalityCountersAbility(final PlanswalkerEntersWithLoyalityCountersAbility ability) {
public PlaneswalkerEntersWithLoyaltyCountersAbility(final PlaneswalkerEntersWithLoyaltyCountersAbility ability) {
super(ability);
startingLoyalty = ability.startingLoyalty;
}
@ -32,7 +32,7 @@ public class PlanswalkerEntersWithLoyalityCountersAbility extends EntersBattlefi
}
@Override
public PlanswalkerEntersWithLoyalityCountersAbility copy() {
return new PlanswalkerEntersWithLoyalityCountersAbility(this);
public PlaneswalkerEntersWithLoyaltyCountersAbility copy() {
return new PlaneswalkerEntersWithLoyaltyCountersAbility(this);
}
}

View file

@ -18,7 +18,7 @@ import mage.util.CardUtil;
*/
public class ChooseACardNameEffect extends OneShotEffect {
public static String INFO_KEY = "NAMED_CARD";
public static final String INFO_KEY = "NAMED_CARD";
public enum TypeOfName {

View file

@ -22,7 +22,7 @@ import mage.util.CardUtil;
*/
public class ChooseBasicLandTypeEffect extends OneShotEffect {
public static String VALUE_KEY = "BasicLandType";
public static final String VALUE_KEY = "BasicLandType";
public ChooseBasicLandTypeEffect(Outcome outcome) {
super(outcome);

View file

@ -62,7 +62,7 @@ public class ChooseCreatureTypeEffect extends OneShotEffect {
* @param game
* @return
*/
public static SubType getChoosenCreatureType(UUID objectId, Game game) {
public static SubType getChosenCreatureType(UUID objectId, Game game) {
SubType creatureType = null;
Object savedCreatureType = game.getState().getValue(objectId + "_type");
if (savedCreatureType != null) {

View file

@ -21,7 +21,7 @@ import mage.util.CardUtil;
*/
public class ChooseOpponentEffect extends OneShotEffect {
public static String VALUE_KEY = "_opponent";
public static final String VALUE_KEY = "_opponent";
public ChooseOpponentEffect(Outcome outcome) {
super(outcome);

View file

@ -39,7 +39,7 @@ public class EntersBattlefieldWithXCountersEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getSourceId());
if (permanent == null) {
if (permanent == null && source.getAbilityType() == AbilityType.STATIC) {
if (source.getAbilityType() == AbilityType.STATIC) {
permanent = game.getPermanentEntering(source.getSourceId());
}
}

View file

@ -6,6 +6,7 @@ import mage.constants.Duration;
import mage.abilities.Ability;
import mage.abilities.effects.PreventionEffectImpl;
import mage.filter.FilterInPlay;
import mage.filter.FilterPermanent;
import mage.game.Game;
import mage.game.events.DamageEvent;
import mage.game.events.GameEvent;
@ -18,9 +19,9 @@ import mage.players.Player;
*/
public class PreventAllNonCombatDamageToAllEffect extends PreventionEffectImpl {
protected FilterInPlay filter;
protected final FilterPermanent filter;
public PreventAllNonCombatDamageToAllEffect(Duration duration, FilterInPlay filter) {
public PreventAllNonCombatDamageToAllEffect(Duration duration, FilterPermanent filter) {
super(duration, Integer.MAX_VALUE, false);
this.filter = filter;
staticText = "Prevent all non combat damage that would be dealt to " + filter.getMessage() + ' ' + duration.toString();
@ -42,15 +43,7 @@ public class PreventAllNonCombatDamageToAllEffect extends PreventionEffectImpl {
&& !((DamageEvent) event).isCombatDamage()) {
Permanent permanent = game.getPermanent(event.getTargetId());
if (permanent != null) {
if (filter.match(permanent, source.getSourceId(), source.getControllerId(), game)) {
return true;
}
}
else {
Player player = game.getPlayer(event.getTargetId());
if (player != null && filter.match(player, source.getSourceId(), source.getControllerId(), game)) {
return true;
}
return filter.match(permanent, source.getSourceId(), source.getControllerId(), game);
}
}
return false;

View file

@ -76,7 +76,7 @@ public class RollPlanarDieEffect extends OneShotEffect {
for (int i = 0; i < chaosEffects.size(); i++) {
Effect effect = chaosEffects.get(i);
Target target = null;
if (chaosTargets != null && chaosTargets.size() > i) {
if (chaosTargets.size() > i) {
target = chaosTargets.get(i);
}
boolean done = false;

View file

@ -15,8 +15,8 @@ import mage.game.permanent.Permanent;
public class AddCardSubtypeAllEffect extends ContinuousEffectImpl {
private static FilterPermanent filter;
private static SubType addedSubtype;
private FilterPermanent filter;
private SubType addedSubtype;
public AddCardSubtypeAllEffect(FilterPermanent _filter, SubType _addedSubtype, DependencyType _dependency) {
super(Duration.WhileOnBattlefield, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Benefit);
@ -28,6 +28,8 @@ public class AddCardSubtypeAllEffect extends ContinuousEffectImpl {
public AddCardSubtypeAllEffect(final AddCardSubtypeAllEffect effect) {
super(effect);
filter = effect.filter.copy();
addedSubtype = effect.addedSubtype;
}
@Override

View file

@ -22,7 +22,7 @@ public class AddChosenSubtypeEffect extends ContinuousEffectImpl {
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getSourceId());
if (permanent != null) {
SubType subType = ChooseCreatureTypeEffect.getChoosenCreatureType(permanent.getId(), game);
SubType subType = ChooseCreatureTypeEffect.getChosenCreatureType(permanent.getId(), game);
if (subType != null && !permanent.hasSubtype(subType, game)) {
permanent.getSubtype(game).add(subType);
}

View file

@ -49,7 +49,7 @@ public class BoostAllOfChosenSubtypeEffect extends BoostAllEffect {
@Override
protected void setRuntimeData(Ability source, Game game) {
SubType subType = ChooseCreatureTypeEffect.getChoosenCreatureType(source.getSourceId(), game);
SubType subType = ChooseCreatureTypeEffect.getChosenCreatureType(source.getSourceId(), game);
if (subType != null) {
subtype = subType;
} else {

View file

@ -32,7 +32,7 @@ public class SwitchPowerToughnessTargetEffect extends ContinuousEffectImpl {
@Override
public boolean apply(Game game, Ability source) {
Permanent target = game.getPermanent(source.getFirstTarget());
Permanent target = game.getPermanent(this.getTargetPointer().getFirst(game, source));
if (target != null) {
int power = target.getPower().getValue();
target.getPower().setValue(target.getToughness().getValue());

View file

@ -37,7 +37,7 @@ public class SpellsCostReductionAllOfChosenSubtypeEffect extends SpellsCostReduc
@Override
protected boolean selectedByRuntimeData(Card card, Ability source, Game game) {
SubType subType = ChooseCreatureTypeEffect.getChoosenCreatureType(source.getSourceId(), game);
SubType subType = ChooseCreatureTypeEffect.getChosenCreatureType(source.getSourceId(), game);
if (subType != null) {
return card.hasSubtype(subType, game);
}

View file

@ -24,7 +24,7 @@ import mage.util.CardUtil;
public class FatesealEffect extends OneShotEffect {
protected static FilterCard filter1 = new FilterCard("card to put on the bottom of opponent's library");
protected static final FilterCard filter1 = new FilterCard("card to put on the bottom of opponent's library");
protected int fatesealNumber;

View file

@ -22,7 +22,7 @@ import mage.players.Player;
*/
public class AscendAbility extends SimpleStaticAbility {
public static String ASCEND_RULE = "Ascend <i>(If you control ten or more permanents, you get the city's blessing for the rest of the game.)</i>";
public static final String ASCEND_RULE = "Ascend <i>(If you control ten or more permanents, you get the city's blessing for the rest of the game.)</i>";
public AscendAbility() {
super(Zone.BATTLEFIELD, new AscendContinuousEffect());

View file

@ -1,4 +1,3 @@
package mage.abilities.keyword;
import java.util.UUID;
@ -158,7 +157,7 @@ public class FlashbackAbility extends SpellAbility {
}
/**
* Used for split card sin PlayerImpl method:
* Used for split card in PlayerImpl method:
* getOtherUseableActivatedAbilities
*
* @param abilityName

View file

@ -4,6 +4,7 @@ import mage.abilities.Ability;
import mage.abilities.SpellAbility;
import mage.abilities.costs.Cost;
import mage.abilities.costs.common.DiscardTargetCost;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.cards.Card;
import mage.constants.Duration;
@ -15,13 +16,25 @@ import mage.game.events.GameEvent;
import mage.game.events.ZoneChangeEvent;
import mage.players.Player;
import mage.target.common.TargetCardInHand;
import mage.target.targetpointer.FixedTarget;
/**
* Jump-start is found on instants and sorceries. You can cast a card with
* jump-start from your graveyard by paying all its regular costs and one
* additional cost: discarding a card from your hand. Casting a spell with
* jump-start follows all the normal timing rules, so sorceries with jump-start
* are still limited to your main phases. A spell with jump-start that was cast
* from your graveyard can still be countered, and if it has targets, it won't
* do anything if all its targets disappear or otherwise become illegal. After a
* spell with jump-start cast from your graveyard resolves, is countered, or
* leaves the stack in any way, it's exiled.
*
* @author TheElk801
*/
public class JumpStartAbility extends SpellAbility {
private boolean replacementEffectAdded = false;
public JumpStartAbility(Card card) {
super(card.getManaCost(), card.getName() + " with jump-start", Zone.GRAVEYARD, SpellAbilityType.BASE_ALTERNATE);
this.getCosts().addAll(card.getSpellAbility().getCosts().copy());
@ -29,7 +42,6 @@ public class JumpStartAbility extends SpellAbility {
cost.setText("");
this.addCost(cost);
this.getEffects().addAll(card.getSpellAbility().getEffects().copy());
this.addEffect(new JumpStartReplacementEffect());
this.getTargets().addAll(card.getSpellAbility().getTargets().copy());
this.spellAbilityType = SpellAbilityType.BASE_ALTERNATE;
this.timing = card.getSpellAbility().getTiming();
@ -38,6 +50,21 @@ public class JumpStartAbility extends SpellAbility {
public JumpStartAbility(final JumpStartAbility ability) {
super(ability);
this.replacementEffectAdded = ability.replacementEffectAdded;
}
@Override
public SpellAbility getSpellAbilityToResolve(Game game) {
Card card = game.getCard(getSourceId());
if (card != null) {
if (!replacementEffectAdded) {
replacementEffectAdded = true;
ContinuousEffect effect = new JumpStartReplacementEffect();
effect.setTargetPointer(new FixedTarget(getSourceId(), game.getState().getZoneChangeCounter(getSourceId())));
game.addEffect(effect, this);
}
}
return this;
}
@Override
@ -105,7 +132,7 @@ class JumpStartReplacementEffect extends ReplacementEffectImpl {
if (event.getTargetId().equals(source.getSourceId())
&& ((ZoneChangeEvent) event).getFromZone() == Zone.STACK
&& ((ZoneChangeEvent) event).getToZone() != Zone.EXILED) {
if (game.getState().getZoneChangeCounter(source.getSourceId()) == source.getSourceObjectZoneChangeCounter()) {
if (game.getState().getZoneChangeCounter(source.getSourceId()) == source.getSourceObjectZoneChangeCounter() + 1) {
return true;
}

View file

@ -71,7 +71,7 @@ public class MadnessAbility extends StaticAbility {
return new MadnessAbility(this);
}
public static Condition GetCondition() {
public static Condition getCondition() {
return MadnessCondition.instance;
}

View file

@ -185,7 +185,7 @@ public abstract class ExpansionSet implements Serializable {
return theBooster;
}
protected int AddMissingPartner(List<Card> booster, boolean partnerAllowed, int max, int i) {
protected int addMissingPartner(List<Card> booster, boolean partnerAllowed, int max, int i) {
for (Ability ability : booster.get(booster.size() - 1).getAbilities()) {
//Check if fetched card has the PartnerWithAbility
@ -328,7 +328,7 @@ public abstract class ExpansionSet implements Serializable {
for (int i = 0; i < numBoosterUncommon; i++) {
while (true) {
addToBooster(booster, uncommons);
int check = AddMissingPartner(booster, partnerAllowed, numBoosterUncommon - 1, i);
int check = addMissingPartner(booster, partnerAllowed, numBoosterUncommon - 1, i);
if (check == 1) {
break;
}
@ -358,7 +358,7 @@ public abstract class ExpansionSet implements Serializable {
if (ratioBoosterMythic > 0 && RandomUtil.nextInt(ratioBoosterMythic) == 0) {
while (true) {
addToBooster(booster, mythics);
int check = AddMissingPartner(booster, partnerAllowed, -1, 1);
int check = addMissingPartner(booster, partnerAllowed, -1, 1);
if (check == 1) {
break;
}
@ -370,7 +370,7 @@ public abstract class ExpansionSet implements Serializable {
} else {
while (true) {
addToBooster(booster, rares);
int check = AddMissingPartner(booster, partnerAllowed, -1, 1);
int check = addMissingPartner(booster, partnerAllowed, -1, 1);
if (check == 1) {
break;
}

View file

@ -135,7 +135,7 @@ public class Sets extends HashMap<String, ExpansionSet> {
if (onlyBasicLands) {
// lands is colorless
// discard not needed color by mana produce
Assert.assertEquals("only basic lands allow", 1, card.getMana().size());
Assert.assertEquals("only basic lands allow, but found " + card.getName(), 1, card.getMana().size());
for (Mana manaLand : card.getMana()) {
if (manaLand.getWhite() > 0 && !manaNeed.isWhite()) { cardManaOK = false; }
if (manaLand.getBlue() > 0 && !manaNeed.isBlue()) { cardManaOK = false; }

View file

@ -17,8 +17,8 @@ public class Constructed extends DeckValidator {
private static final Logger logger = Logger.getLogger(DeckValidator.class);
protected static List<String> anyNumberCardsAllowed = new ArrayList<>(Arrays.asList("Relentless Rats", "Shadowborn Apostle", "Rat Colony"));
protected static List<String> basicLandNames = new ArrayList<>(
protected static final List<String> anyNumberCardsAllowed = new ArrayList<>(Arrays.asList("Relentless Rats", "Shadowborn Apostle", "Rat Colony"));
protected static final List<String> basicLandNames = new ArrayList<>(
Arrays.asList("Forest", "Island", "Mountain", "Swamp", "Plains", "Wastes", "Snow-Covered Forest",
"Snow-Covered Island", "Snow-Covered Mountain", "Snow-Covered Swamp", "Snow-Covered Plains"));
protected List<String> banned = new ArrayList<>();

View file

@ -12,7 +12,7 @@ import mage.cards.decks.DeckCardLists;
*/
public final class DeckImporterUtil {
public static final String[] SIDEBOARD_MARKS = new String[]{"//sideboard", "sb: "};
private static final String[] SIDEBOARD_MARKS = new String[]{"//sideboard", "sb: "};
public static boolean haveSideboardSection(String file) {
// search for sideboard section:

View file

@ -16,9 +16,9 @@ import mage.cards.repository.CardRepository;
*/
public class TxtDeckImporter extends DeckImporter {
public static final String[] SET_VALUES = new String[]{"lands", "creatures", "planeswalkers", "other spells", "sideboard cards",
private static final String[] SET_VALUES = new String[]{"lands", "creatures", "planeswalkers", "other spells", "sideboard cards",
"Instant", "Land", "Enchantment", "Artifact", "Sorcery", "Planeswalker", "Creature"};
public static final Set<String> IGNORE_NAMES = new HashSet<>(Arrays.asList(SET_VALUES));
private static final Set<String> IGNORE_NAMES = new HashSet<>(Arrays.asList(SET_VALUES));
private boolean sideboard = false;
private boolean switchSideboardByEmptyLine = true; // all cards after first empty line will be sideboard (like mtgo format)

View file

@ -9,7 +9,7 @@ import java.util.stream.Collectors;
import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.SpellAbility;
import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility;
import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.cards.*;
import mage.cards.mock.MockCard;
import mage.cards.mock.MockSplitCard;
@ -181,8 +181,8 @@ public class CardInfo {
// Starting loyalty
if (card.isPlaneswalker()) {
for (Ability ab : card.getAbilities()) {
if (ab instanceof PlanswalkerEntersWithLoyalityCountersAbility) {
this.startingLoyalty = "" + ((PlanswalkerEntersWithLoyalityCountersAbility) ab).getStartingLoyalty();
if (ab instanceof PlaneswalkerEntersWithLoyaltyCountersAbility) {
this.startingLoyalty = "" + ((PlaneswalkerEntersWithLoyaltyCountersAbility) ab).getStartingLoyalty();
}
}
if (this.startingLoyalty == null) {

View file

@ -19,7 +19,7 @@ public class ChosenSubtypePredicate implements ObjectPlayerPredicate<ObjectSourc
@Override
public boolean apply(ObjectSourcePlayer<MageObject> input, Game game) {
SubType subType = ChooseCreatureTypeEffect.getChoosenCreatureType(input.getSourceId(), game);
SubType subType = ChooseCreatureTypeEffect.getChosenCreatureType(input.getSourceId(), game);
return input.getObject().hasSubtype(subType, game);
}

View file

@ -1191,7 +1191,7 @@ public abstract class GameImpl implements Game, Serializable {
player.shuffleLibrary(null, this);
int deduction = 1;
if (freeMulligans > 0) {
if (usedFreeMulligans != null && usedFreeMulligans.containsKey(player.getId())) {
if (usedFreeMulligans.containsKey(player.getId())) {
int used = usedFreeMulligans.get(player.getId());
if (used < freeMulligans) {
deduction = 0;
@ -1424,7 +1424,7 @@ public abstract class GameImpl implements Game, Serializable {
} else {
spellControllerId = spell.getControllerId(); // i.e. resolved spell is the target opponent's spell
}
if (commandedBy != null && spellControllerId != null) {
if (spellControllerId != null) {
Player turnController = getPlayer(commandedBy);
if (turnController != null) {
Player targetPlayer = getPlayer(spellControllerId);

View file

@ -10,6 +10,7 @@ import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.game.command.Commander;
import mage.game.events.ZoneChangeEvent;
import mage.game.events.ZoneChangeGroupEvent;
import mage.game.permanent.Permanent;
import mage.game.permanent.PermanentCard;
import mage.game.permanent.PermanentMeld;
@ -25,6 +26,12 @@ public final class ZonesHandler {
public static boolean cast(ZoneChangeInfo info, Game game) {
if (maybeRemoveFromSourceZone(info, game)) {
placeInDestinationZone(info, game);
// create a group zone change event if a card is moved to stack for casting (it's always only one card, but some effects check for group events (one or more xxx))
Set<Card> cards = new HashSet<>();
Card targetCard = getTargetCard(game, info.event.getTargetId());
cards.add(targetCard);
game.fireEvent(new ZoneChangeGroupEvent(cards, info.event.getSourceId(), info.event.getPlayerId(), info.event.getFromZone(), info.event.getToZone()));
// normal movement
game.fireEvent(info.event);
return true;
}

View file

@ -11,7 +11,7 @@ import mage.game.permanent.token.CatToken2;
*
* @author TheElk801
*/
public class AjaniAdversaryOfTyrantsEmblem extends Emblem {
public final class AjaniAdversaryOfTyrantsEmblem extends Emblem {
// 7: You get an emblem with "At the beginning of your end step, create three 1/1 white Cat creature tokens with lifelink."
public AjaniAdversaryOfTyrantsEmblem() {

View file

@ -15,7 +15,7 @@ import mage.game.permanent.Permanent;
*
* @author spjspj
*/
public class AjaniSteadfastEmblem extends Emblem {
public final class AjaniSteadfastEmblem extends Emblem {
public AjaniSteadfastEmblem() {
setName("Emblem Ajani");

View file

@ -21,7 +21,7 @@ import mage.target.common.TargetAnyTarget;
*
* @author spjspj
*/
public class ArlinnEmbracedByTheMoonEmblem extends Emblem {
public final class ArlinnEmbracedByTheMoonEmblem extends Emblem {
// "Creatures you control have haste and '{T}: This creature deals damage equal to its power to any target.'"
public ArlinnEmbracedByTheMoonEmblem() {

View file

@ -13,7 +13,7 @@ import mage.game.command.Emblem;
*
* @author spjspj
*/
public class AurraSingBaneOfJediEmblem extends Emblem {
public final class AurraSingBaneOfJediEmblem extends Emblem {
private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("a nontoken creature you control");

View file

@ -12,7 +12,7 @@ import mage.game.command.Emblem;
*
* @author spjspj
*/
public class ChandraRoaringFlameEmblem extends Emblem {
public final class ChandraRoaringFlameEmblem extends Emblem {
/**
* Emblem with "At the beginning of your upkeep, this emblem deals 3 damage

View file

@ -14,7 +14,7 @@ import mage.target.common.TargetAnyTarget;
*
* @author spjspj
*/
public class ChandraTorchOfDefianceEmblem extends Emblem {
public final class ChandraTorchOfDefianceEmblem extends Emblem {
// You get an emblem with "Whenever you cast a spell, this emblem deals 5 damage to any target."
public ChandraTorchOfDefianceEmblem() {

View file

@ -29,7 +29,7 @@ import mage.target.targetpointer.FixedTargets;
*
* @author spjspj
*/
public class DackFaydenEmblem extends Emblem {
public final class DackFaydenEmblem extends Emblem {
public DackFaydenEmblem() {
this.setName("Emblem Dack");

View file

@ -22,7 +22,7 @@ import mage.target.targetpointer.FixedTarget;
*
* @author spjspj
*/
public class DarettiScrapSavantEmblem extends Emblem {
public final class DarettiScrapSavantEmblem extends Emblem {
// You get an emblem with "Whenever an artifact is put into your graveyard from the battlefield, return that card to the battlefield at the beginning of the next end step."
public DarettiScrapSavantEmblem() {

View file

@ -18,7 +18,7 @@ import mage.game.command.Emblem;
*
* @author spjspj
*/
public class DomriRadeEmblem extends Emblem {
public final class DomriRadeEmblem extends Emblem {
// "Creatures you control have double strike, trample, hexproof and haste."
public DomriRadeEmblem() {

View file

@ -15,7 +15,7 @@ import mage.players.Player;
*
* @author spjspj
*/
public class DovinBaanEmblem extends Emblem {
public final class DovinBaanEmblem extends Emblem {
public DovinBaanEmblem() {
this.setName("Emblem Dovin");

View file

@ -17,7 +17,7 @@ import mage.game.command.Emblem;
*
* @author spjspj
*/
public class ElspethKnightErrantEmblem extends Emblem {
public final class ElspethKnightErrantEmblem extends Emblem {
public ElspethKnightErrantEmblem() {
this.setName("Emblem Elspeth");

View file

@ -14,7 +14,7 @@ import mage.game.command.Emblem;
*
* @author spjspj
*/
public class ElspethSunsChampionEmblem extends Emblem {
public final class ElspethSunsChampionEmblem extends Emblem {
// -7: You get an emblem with "Creatures you control get +2/+2 and have flying."
public ElspethSunsChampionEmblem() {

View file

@ -16,7 +16,7 @@ import mage.game.command.Emblem;
*
* @author spjspj
*/
public class GarrukApexPredatorEmblem extends Emblem {
public final class GarrukApexPredatorEmblem extends Emblem {
/**
* Emblem with "Whenever a creature attacks you, it gets +5/+5 and gains

View file

@ -16,7 +16,7 @@ import mage.target.common.TargetCardInLibrary;
*
* @author spjspj
*/
public class GarrukCallerOfBeastsEmblem extends Emblem {
public final class GarrukCallerOfBeastsEmblem extends Emblem {
/**
* Emblem: "Whenever you cast a creature spell, you may search your library

View file

@ -12,7 +12,7 @@ import mage.game.command.Emblem;
*
* @author spjspj
*/
public class GideonAllyOfZendikarEmblem extends Emblem {
public final class GideonAllyOfZendikarEmblem extends Emblem {
public GideonAllyOfZendikarEmblem() {
this.setName("Emblem Gideon");

View file

@ -18,7 +18,7 @@ import mage.game.events.GameEvent;
*
* @author spjspj
*/
public class GideonOfTheTrialsEmblem extends Emblem {
public final class GideonOfTheTrialsEmblem extends Emblem {
public GideonOfTheTrialsEmblem() {
this.setName("Emblem - Gideon");

View file

@ -12,7 +12,7 @@ import mage.game.command.Emblem;
*
* @author LevelX2
*/
public class HuatliRadiantChampionEmblem extends Emblem {
public final class HuatliRadiantChampionEmblem extends Emblem {
public HuatliRadiantChampionEmblem() {
this.setName("Emblem Huatli");

View file

@ -14,7 +14,7 @@ import mage.target.common.TargetOpponent;
*
* @author spjspj
*/
public class JaceTelepathUnboundEmblem extends Emblem {
public final class JaceTelepathUnboundEmblem extends Emblem {
// You get an emblem with "Whenever you cast a spell, target opponent puts the top five cards of their library into their graveyard".
public JaceTelepathUnboundEmblem() {

View file

@ -18,7 +18,7 @@ import mage.watchers.common.SpellsCastWatcher;
*
* @author spjspj
*/
public class JaceUnravelerOfSecretsEmblem extends Emblem {
public final class JaceUnravelerOfSecretsEmblem extends Emblem {
/**
* Emblem: "Whenever an opponent casts their first spell each turn,

View file

@ -28,7 +28,7 @@ import mage.watchers.common.CastFromGraveyardWatcher;
*
* @author LevelX2
*/
public class JayaBallardEmblem extends Emblem {
public final class JayaBallardEmblem extends Emblem {
// You get an emblem with "You may cast instant and sorcery cards from your graveyard. If a card cast this way would be put into your graveyard, exile it instead."
public JayaBallardEmblem() {

View file

@ -13,7 +13,7 @@ import mage.game.permanent.token.KioraKrakenToken;
*
* @author spjspj
*/
public class KioraEmblem extends Emblem {
public final class KioraEmblem extends Emblem {
/**
* Emblem: "At the beginning of your end step, create a 9/9 blue Kraken

View file

@ -17,7 +17,7 @@ import mage.target.common.TargetCreaturePermanent;
*
* @author spjspj
*/
public class KioraMasterOfTheDepthsEmblem extends Emblem {
public final class KioraMasterOfTheDepthsEmblem extends Emblem {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Creatures");

View file

@ -23,7 +23,7 @@ import mage.target.common.TargetAnyTarget;
*
* @author spjspj
*/
public class KothOfTheHammerEmblem extends Emblem {
public final class KothOfTheHammerEmblem extends Emblem {
// "Mountains you control have '{T}: This land deals 1 damage to any target.'"
public KothOfTheHammerEmblem() {

View file

@ -20,7 +20,7 @@ import mage.target.targetpointer.FixedTarget;
*
* @author spjspj
*/
public class LilianaDefiantNecromancerEmblem extends Emblem {
public final class LilianaDefiantNecromancerEmblem extends Emblem {
// You get an emblem with "Whenever a creature you control dies, return it to the battlefield under your control at the beginning of the next end step."
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("a creature");

View file

@ -18,7 +18,7 @@ import mage.game.command.Emblem;
*
* @author spjspj
*/
public class LilianaOfTheDarkRealmsEmblem extends Emblem {
public final class LilianaOfTheDarkRealmsEmblem extends Emblem {
private static final FilterLandPermanent filter = new FilterLandPermanent("Swamps");

View file

@ -19,7 +19,7 @@ import mage.game.permanent.token.ZombieToken;
*
* @author spjspj
*/
public class LilianaTheLastHopeEmblem extends Emblem {
public final class LilianaTheLastHopeEmblem extends Emblem {
// "At the beginning of your end step, create X 2/2 black Zombie creature tokens, where X is two plus the number of Zombies you control."
public LilianaTheLastHopeEmblem() {

View file

@ -20,7 +20,7 @@ import mage.players.Player;
*
* @author NinthWorld
*/
public class LukeSkywalkerEmblem extends Emblem {
public final class LukeSkywalkerEmblem extends Emblem {
// -6: You get an emblem with "Prevent all damage that would be dealt to you during combat." Exile Luke Skywalker, the Last Jedi.
public LukeSkywalkerEmblem() {

View file

@ -28,7 +28,7 @@ import mage.util.RandomUtil;
*
* @author spjspj
*/
public class MomirEmblem extends Emblem {
public final class MomirEmblem extends Emblem {
// Faking Vanguard as an Emblem; need to come back to this and add a new type of CommandObject
public MomirEmblem() {

View file

@ -18,7 +18,7 @@ import mage.players.Player;
*
* @author spjspj
*/
public class NarsetTranscendentEmblem extends Emblem {
public final class NarsetTranscendentEmblem extends Emblem {
// "Your opponents can't cast noncreature spells.
public NarsetTranscendentEmblem() {

View file

@ -12,7 +12,7 @@ import mage.game.command.Emblem;
*
* @author spjspj
*/
public class NissaVitalForceEmblem extends Emblem {
public final class NissaVitalForceEmblem extends Emblem {
// You get an emblem with "Whenever a land enters the battlefield under your control, you may draw a card."
public NissaVitalForceEmblem() {

View file

@ -19,7 +19,7 @@ import mage.target.common.TargetControlledCreaturePermanent;
*
* @author spjspj
*/
public class ObNixilisOfTheBlackOathEmblem extends Emblem {
public final class ObNixilisOfTheBlackOathEmblem extends Emblem {
// You get an emblem with "{1}{B}, Sacrifice a creature: You gain X life and draw X cards, where X is the sacrificed creature's power."
public ObNixilisOfTheBlackOathEmblem() {

View file

@ -14,7 +14,7 @@ import mage.game.events.GameEvent.EventType;
*
* @author spjspj
*/
public class ObNixilisReignitedEmblem extends Emblem {
public final class ObNixilisReignitedEmblem extends Emblem {
public ObNixilisReignitedEmblem() {
setName("Emblem Nixilis");

View file

@ -17,7 +17,7 @@ import mage.game.command.Emblem;
*
* @author spjspj
*/
public class ObiWanKenobiEmblem extends Emblem {
public final class ObiWanKenobiEmblem extends Emblem {
// Creatures you control get +1/+1 and have vigilance, first strike, and lifelink
public ObiWanKenobiEmblem() {

View file

@ -13,7 +13,7 @@ import mage.target.common.TargetAnyTarget;
*
* @author TheElk801
*/
public class RalIzzetViceroyEmblem extends Emblem {
public final class RalIzzetViceroyEmblem extends Emblem {
// You get an emblem with "Whenever you cast an instant or sorcery spell, this emblem deals 4 damage to any target and you draw two cards."
public RalIzzetViceroyEmblem() {

View file

@ -18,7 +18,7 @@ import mage.players.Player;
*
* @author TheElk801
*/
public class RowanKenrithEmblem extends Emblem {
public final class RowanKenrithEmblem extends Emblem {
// Target player gets an emblem with "Whenever you activate an ability that isn't a mana ability, copy it. You may choose new targets for the copy."
public RowanKenrithEmblem() {

View file

@ -13,7 +13,7 @@ import mage.game.command.Emblem;
*
* @author spjspj
*/
public class SarkhanTheDragonspeakerEmblem extends Emblem {
public final class SarkhanTheDragonspeakerEmblem extends Emblem {
public SarkhanTheDragonspeakerEmblem() {
setName("Emblem Sarkhan");

View file

@ -12,7 +12,7 @@ import mage.game.command.Emblem;
*
* @author spjspj
*/
public class SorinLordOfInnistradEmblem extends Emblem {
public final class SorinLordOfInnistradEmblem extends Emblem {
public SorinLordOfInnistradEmblem() {
this.setName("Emblem Sorin");

View file

@ -13,7 +13,7 @@ import mage.game.command.Emblem;
*
* @author spjspj
*/
public class SorinSolemnVisitorEmblem extends Emblem {
public final class SorinSolemnVisitorEmblem extends Emblem {
/**
* Emblem: "At the beginning of each opponent's upkeep, that player

View file

@ -10,7 +10,7 @@ import mage.game.command.Emblem;
*
* Author: spjspj
*/
public class TamiyoFieldResearcherEmblem extends Emblem {
public final class TamiyoFieldResearcherEmblem extends Emblem {
// You may cast nonland cards from your hand without paying their mana costs.
public TamiyoFieldResearcherEmblem() {

View file

@ -19,7 +19,7 @@ import mage.game.command.Emblem;
*
* @author spjspj
*/
public class TamiyoTheMoonSageEmblem extends Emblem {
public final class TamiyoTheMoonSageEmblem extends Emblem {
/**
* Emblem with "You have no maximum hand size" and "Whenever a card is put

View file

@ -19,7 +19,7 @@ import mage.target.TargetPermanent;
*
* @author LevelX2
*/
public class TeferiHeroOfDominariaEmblem extends Emblem {
public final class TeferiHeroOfDominariaEmblem extends Emblem {
// Whenever you draw a card, exile target permanent an opponent controls.
public TeferiHeroOfDominariaEmblem() {

View file

@ -11,7 +11,7 @@ import mage.game.command.Emblem;
*
* @author spjspj
*/
public class TeferiTemporalArchmageEmblem extends Emblem {
public final class TeferiTemporalArchmageEmblem extends Emblem {
// "You may activate loyalty abilities of planeswalkers you control on any player's turn any time you could cast an instant."
public TeferiTemporalArchmageEmblem() {

View file

@ -12,7 +12,7 @@ import mage.target.common.TargetCardInLibrary;
*
* @author TheElk801
*/
public class TezzeretArtificeMasterEmblem extends Emblem {
public final class TezzeretArtificeMasterEmblem extends Emblem {
// 9: You get an emblem with "At the beginning of your end step, search your library for a permanent card, put it into the battlefield, then shuffle your library."
public TezzeretArtificeMasterEmblem() {

View file

@ -18,7 +18,7 @@ import mage.target.TargetPermanent;
*
* @author spjspj
*/
public class TezzeretTheSchemerEmblem extends Emblem {
public final class TezzeretTheSchemerEmblem extends Emblem {
public TezzeretTheSchemerEmblem() {
this.setName("Emblem Tezzeret");

View file

@ -20,7 +20,7 @@ import mage.target.targetpointer.FixedTarget;
*
* @author spjspj
*/
public class VenserTheSojournerEmblem extends Emblem {
public final class VenserTheSojournerEmblem extends Emblem {
/**
* Emblem: "Whenever you cast a spell, exile target permanent."

View file

@ -16,7 +16,7 @@ import mage.game.command.Emblem;
*
* @author spjspj
*/
public class VivienReidEmblem extends Emblem {
public final class VivienReidEmblem extends Emblem {
// -8: You get an emblem with "Creatures you control get +2/+2 and have vigilance, trample, and indestructible.
public VivienReidEmblem() {

View file

@ -10,7 +10,7 @@ import mage.game.command.Emblem;
*
* @author TheElk801
*/
public class VraskaGolgariQueenEmblem extends Emblem {
public final class VraskaGolgariQueenEmblem extends Emblem {
// -9: You get an emblem with "Whenever a creature you control deals combat damage to a player, that player loses the game."
public VraskaGolgariQueenEmblem() {

View file

@ -11,7 +11,7 @@ import mage.game.command.Emblem;
*
* @author TheElk801
*/
public class WillKenrithEmblem extends Emblem {
public final class WillKenrithEmblem extends Emblem {
// Target player gets an emblem with "Whenever you cast an instant or sorcery spell, copy it. You may choose new targets for the copy."
public WillKenrithEmblem() {

View file

@ -16,7 +16,7 @@ import mage.game.command.Emblem;
*
* @author spjspj
*/
public class YodaEmblem extends Emblem {
public final class YodaEmblem extends Emblem {
// You get an emblem with "Hexproof, you and your creatures have."
public YodaEmblem() {

View file

@ -88,10 +88,8 @@ class DrawCardsActivePlayerEffect extends OneShotEffect {
if (cPlane == null) {
return false;
}
if (cPlane != null) {
if (!cPlane.getName().equalsIgnoreCase("Plane - Academy at Tolaria West")) {
return false;
}
if (!cPlane.getName().equalsIgnoreCase("Plane - Academy at Tolaria West")) {
return false;
}
Player player = game.getPlayer(game.getActivePlayerId());
if (player != null) {

View file

@ -81,10 +81,8 @@ class AstralArenaAttackRestrictionEffect extends RestrictionEffect {
if (cPlane == null) {
return false;
}
if (cPlane != null) {
if (!cPlane.getName().equalsIgnoreCase("Plane - Astral Arena")) {
return false;
}
if (!cPlane.getName().equalsIgnoreCase("Plane - Astral Arena")) {
return false;
}
return true;
@ -118,10 +116,8 @@ class AstralArenaBlockRestrictionEffect extends RestrictionEffect {
if (cPlane == null) {
return false;
}
if (cPlane != null) {
if (!cPlane.getName().equalsIgnoreCase("Plane - Astral Arena")) {
return false;
}
if (!cPlane.getName().equalsIgnoreCase("Plane - Astral Arena")) {
return false;
}
return true;
}

View file

@ -101,10 +101,8 @@ class EdgeOfMalacolEffect extends ContinuousRuleModifyingEffectImpl {
if (cPlane == null) {
return false;
}
if (cPlane != null) {
if (!cPlane.getName().equalsIgnoreCase("Plane - Edge of Malacol")) {
return false;
}
if (!cPlane.getName().equalsIgnoreCase("Plane - Edge of Malacol")) {
return false;
}
Permanent permanent = game.getPermanent(event.getTargetId());
if (permanent != null && filter.match(permanent, game) && Objects.equals(permanent.getControllerId(), game.getActivePlayerId())) {

View file

@ -79,7 +79,7 @@ class FeedingGroundsEffect extends CostModificationEffectImpl {
new ColorPredicate(ObjectColor.GREEN)));
}
private static final String rule = "Red spells cost {1} less to cast. Green spells cost {1} less to cast.";
private static final String rule = "Red spells cost {1} less to cast. Green spells cost {1} less to cast.";
private int amount = 1;
public FeedingGroundsEffect() {
@ -133,19 +133,17 @@ class FeedingGroundsEffect extends CostModificationEffectImpl {
if (cPlane == null) {
return false;
}
if (cPlane != null) {
if (!cPlane.getName().equalsIgnoreCase("Plane - Feeding Grounds")) {
return false;
}
if (!cPlane.getName().equalsIgnoreCase("Plane - Feeding Grounds")) {
return false;
}
Spell spell = (Spell) game.getStack().getStackObject(abilityToModify.getId());
if (spell != null) {
return this.filter.match(spell, game) && selectedByRuntimeData(spell, source, game);
return filter.match(spell, game) && selectedByRuntimeData(spell, source, game);
} else {
// used at least for flashback ability because Flashback ability doesn't use stack
Card sourceCard = game.getCard(abilityToModify.getSourceId());
return sourceCard != null && this.filter.match(sourceCard, game) && selectedByRuntimeData(sourceCard, source, game);
return sourceCard != null && filter.match(sourceCard, game) && selectedByRuntimeData(sourceCard, source, game);
}
}
return false;

View file

@ -95,10 +95,8 @@ class HedronFieldsOfAgadeemRestrictionEffect extends RestrictionEffect {
if (cPlane == null) {
return false;
}
if (cPlane != null) {
if (!cPlane.getName().equalsIgnoreCase("Plane - Hedron Fields of Agadeem")) {
return false;
}
if (!cPlane.getName().equalsIgnoreCase("Plane - Hedron Fields of Agadeem")) {
return false;
}
return filter.match(permanent, source.getSourceId(), source.getControllerId(), game);
}

View file

@ -65,7 +65,6 @@ class TazeemCantBlockAllEffect extends RestrictionEffect {
public TazeemCantBlockAllEffect() {
super(Duration.Custom);
this.filter = filter;
}
public TazeemCantBlockAllEffect(final TazeemCantBlockAllEffect effect) {

View file

@ -87,10 +87,8 @@ class TheEonFogSkipUntapStepEffect extends ContinuousRuleModifyingEffectImpl {
if (cPlane == null) {
return false;
}
if (cPlane != null) {
if (!cPlane.getName().equalsIgnoreCase("Plane - The Eon Fog")) {
return false;
}
if (!cPlane.getName().equalsIgnoreCase("Plane - The Eon Fog")) {
return false;
}
return event.getType() == GameEvent.EventType.UNTAP_STEP;
}

View file

@ -86,10 +86,8 @@ class TheGreatForestCombatDamageRuleEffect extends ContinuousEffectImpl {
if (cPlane == null) {
return false;
}
if (cPlane != null) {
if (!cPlane.getName().equalsIgnoreCase("Plane - The Great Forest")) {
return false;
}
if (!cPlane.getName().equalsIgnoreCase("Plane - The Great Forest")) {
return false;
}
// Change the rule

View file

@ -101,10 +101,8 @@ class TrailOfTheMageRingsReboundEffect extends ContinuousEffectImpl {
if (cPlane == null) {
return false;
}
if (cPlane != null) {
if (!cPlane.getName().equalsIgnoreCase("Plane - Trail of the Mage-Rings")) {
return false;
}
if (!cPlane.getName().equalsIgnoreCase("Plane - Trail of the Mage-Rings")) {
return false;
}
for (UUID playerId : game.getPlayers().keySet()) {

View file

@ -114,19 +114,17 @@ class TurriIslandEffect extends CostModificationEffectImpl {
if (cPlane == null) {
return false;
}
if (cPlane != null) {
if (!cPlane.getName().equalsIgnoreCase("Plane - Turri Island")) {
return false;
}
if (!cPlane.getName().equalsIgnoreCase("Plane - Turri Island")) {
return false;
}
Spell spell = (Spell) game.getStack().getStackObject(abilityToModify.getId());
if (spell != null) {
return this.filter.match(spell, game) && selectedByRuntimeData(spell, source, game);
return filter.match(spell, game) && selectedByRuntimeData(spell, source, game);
} else {
// used at least for flashback ability because Flashback ability doesn't use stack
Card sourceCard = game.getCard(abilityToModify.getSourceId());
return sourceCard != null && this.filter.match(sourceCard, game) && selectedByRuntimeData(sourceCard, source, game);
return sourceCard != null && filter.match(sourceCard, game) && selectedByRuntimeData(sourceCard, source, game);
}
}
return false;

View file

@ -96,10 +96,8 @@ class UndercityReachesTriggeredAbility extends TriggeredAbilityImpl {
if (cPlane == null) {
return false;
}
if (cPlane != null) {
if (!cPlane.getName().equalsIgnoreCase("Plane - Undercity Reaches")) {
return false;
}
if (!cPlane.getName().equalsIgnoreCase("Plane - Undercity Reaches")) {
return false;
}
if (((DamagedPlayerEvent) event).isCombatDamage()) {

View file

@ -476,7 +476,7 @@ public abstract class TournamentImpl implements Tournament {
@Override
public void cleanUpOnTournamentEnd() {
for (TournamentPlayer tournamentPlayer : players.values()) {
tournamentPlayer.CleanUpOnTournamentEnd();
tournamentPlayer.cleanUpOnTournamentEnd();
}
}

View file

@ -179,7 +179,7 @@ public class TournamentPlayer {
* Free resources no longer needed if tournament has ended
*
*/
public void CleanUpOnTournamentEnd() {
public void cleanUpOnTournamentEnd() {
this.deck = null;
}

View file

@ -1,22 +1,9 @@
package mage.players;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import mage.MageItem;
import mage.MageObject;
import mage.MageObjectReference;
import mage.abilities.Abilities;
import mage.abilities.Ability;
import mage.abilities.ActivatedAbility;
import mage.abilities.Mode;
import mage.abilities.Modes;
import mage.abilities.SpellAbility;
import mage.abilities.TriggeredAbility;
import mage.abilities.*;
import mage.abilities.costs.AlternativeSourceCosts;
import mage.abilities.costs.Cost;
import mage.abilities.costs.Costs;
@ -28,13 +15,7 @@ import mage.cards.Card;
import mage.cards.Cards;
import mage.cards.decks.Deck;
import mage.choices.Choice;
import mage.constants.AbilityType;
import mage.constants.ManaType;
import mage.constants.Outcome;
import mage.constants.PlanarDieRoll;
import mage.constants.PlayerAction;
import mage.constants.RangeOfInfluence;
import mage.constants.Zone;
import mage.constants.*;
import mage.counters.Counter;
import mage.counters.Counters;
import mage.designations.Designation;
@ -56,8 +37,10 @@ import mage.target.TargetCard;
import mage.target.common.TargetCardInLibrary;
import mage.util.Copyable;
import java.io.Serializable;
import java.util.*;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public interface Player extends MageItem, Copyable<Player> {
@ -91,8 +74,7 @@ public interface Player extends MageItem, Copyable<Player> {
void setLife(int life, Game game, UUID sourceId);
/**
*
* @param amount amount of life loss
* @param amount amount of life loss
* @param game
* @param atCombat was the source combat damage
* @return
@ -289,7 +271,7 @@ public interface Player extends MageItem, Copyable<Player> {
/**
* Returns false in case player don't control the game.
*
* <p>
* Note: For effects like "You control target player during that player's
* next turn".
*
@ -299,7 +281,7 @@ public interface Player extends MageItem, Copyable<Player> {
/**
* Returns false in case you don't control the game.
*
* <p>
* Note: For effects like "You control target player during that player's
* next turn".
*
@ -360,11 +342,10 @@ public interface Player extends MageItem, Copyable<Player> {
boolean searchLibrary(TargetCardInLibrary target, Game game, UUID targetPlayerId);
/**
*
* @param target
* @param game
* @param targetPlayerId player whose library will be searched
* @param triggerEvents whether searching will trigger any game events
* @param triggerEvents whether searching will trigger any game events
* @return true if search was successful
*/
boolean searchLibrary(TargetCardInLibrary target, Game game, UUID targetPlayerId, boolean triggerEvents);
@ -374,23 +355,22 @@ public interface Player extends MageItem, Copyable<Player> {
/**
* Plays a card if possible
*
* @param card the card that can be cast
* @param card the card that can be cast
* @param game
* @param noMana if it's a spell i can be cast without paying mana
* @param noMana if it's a spell i can be cast without paying mana
* @param ignoreTiming if it's cast during the resolution of another spell
* no sorcery or play land timing restriction are checked. For a land it has
* to be the turn of the player playing that card.
* no sorcery or play land timing restriction are checked. For a land it has
* to be the turn of the player playing that card.
* @return
*/
boolean playCard(Card card, Game game, boolean noMana, boolean ignoreTiming, MageObjectReference reference);
/**
*
* @param card the land card to play
* @param card the land card to play
* @param game
* @param ignoreTiming false - it won't be checked if the stack is empty and
* you are able to play a Sorcery. It's still checked, if you are able to
* play a land concerning the numner of lands you already played.
* you are able to play a Sorcery. It's still checked, if you are able to
* play a land concerning the numner of lands you already played.
* @return
*/
boolean playLand(Card card, Game game, boolean ignoreTiming);
@ -536,15 +516,17 @@ public interface Player extends MageItem, Copyable<Player> {
/**
* Moves the cards from cards to the bottom of the players library.
*
* @param cards - list of cards that have to be moved
* @param game - game
* @param cards - list of cards that have to be moved
* @param game - game
* @param anyOrder - true if player can determine the order of the cards
* else random order
* @param source - source ability
* else random order
* @param source - source ability
* @return
*/
boolean putCardsOnBottomOfLibrary(Cards cards, Game game, Ability source, boolean anyOrder);
boolean putCardsOnBottomOfLibrary(Card card, Game game, Ability source, boolean anyOrder);
/**
* Moves the card to the top x position of the library
*
@ -559,10 +541,10 @@ public interface Player extends MageItem, Copyable<Player> {
/**
* Moves the cards from cards to the top of players library.
*
* @param cards - list of cards that have to be moved
* @param game - game
* @param cards - list of cards that have to be moved
* @param game - game
* @param anyOrder - true if player can determine the order of the cards
* @param source - source ability
* @param source - source ability
* @return
*/
boolean putCardsOnTopOfLibrary(Cards cards, Game game, Ability source, boolean anyOrder);
@ -588,8 +570,8 @@ public interface Player extends MageItem, Copyable<Player> {
/**
* Choose the order in which blockers get damage assigned to
*
* @param blockers list of blockers where to choose the next one from
* @param combatGroup the concerning combat group
* @param blockers list of blockers where to choose the next one from
* @param combatGroup the concerning combat group
* @param blockerOrder the already set order of blockers
* @param game
* @return blocker next to add to the blocker order
@ -728,11 +710,11 @@ public interface Player extends MageItem, Copyable<Player> {
* @param toZone
* @param source
* @param game
* @param tapped the cards are tapped on the battlefield
* @param faceDown the cards are face down in the to zone
* @param byOwner the card is moved (or put onto battlefield) by the owner
* of the card and if target zone is battlefield controls the permanent
* (instead of the controller of the source)
* @param tapped the cards are tapped on the battlefield
* @param faceDown the cards are face down in the to zone
* @param byOwner the card is moved (or put onto battlefield) by the owner
* of the card and if target zone is battlefield controls the permanent
* (instead of the controller of the source)
* @param appliedEffects
* @return
*/
@ -759,7 +741,6 @@ public interface Player extends MageItem, Copyable<Player> {
* @param game
* @param withName show the card name in the log
* @return
*
*/
boolean moveCardToHandWithInfo(Card card, UUID sourceId, Game game, boolean withName);
@ -769,7 +750,7 @@ public interface Player extends MageItem, Copyable<Player> {
* list of applied effects is not saved
*
* @param card
* @param exileId exile zone id (optional)
* @param exileId exile zone id (optional)
* @param exileName name of exile zone (optional)
* @param sourceId
* @param game
@ -811,7 +792,7 @@ public interface Player extends MageItem, Copyable<Player> {
* @param sourceId
* @param game
* @param fromZone if null, this info isn't postet
* @param toTop to the top of the library else to the bottom
* @param toTop to the top of the library else to the bottom
* @param withName show the card name in the log
* @return
*/
@ -836,10 +817,10 @@ public interface Player extends MageItem, Copyable<Player> {
* without mana (null) or the mana set to manaCosts instead of its normal
* mana costs.
*
* @param sourceId the source that can be cast without mana
* @param sourceId the source that can be cast without mana
* @param manaCosts alternate ManaCost, null if it can be cast without mana
* cost
* @param costs alternate other costs you need to pay
* cost
* @param costs alternate other costs you need to pay
*/
void setCastSourceIdWithAlternateMana(UUID sourceId, ManaCosts<ManaCost> manaCosts, Costs<Cost> costs);

View file

@ -1,9 +1,5 @@
package mage.players;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Map.Entry;
import mage.ConditionalMana;
import mage.MageObject;
import mage.MageObjectReference;
@ -31,11 +27,6 @@ import mage.cards.SplitCard;
import mage.cards.decks.Deck;
import mage.choices.ChoiceImpl;
import mage.constants.*;
import static mage.constants.Zone.BATTLEFIELD;
import static mage.constants.Zone.EXILED;
import static mage.constants.Zone.GRAVEYARD;
import static mage.constants.Zone.HAND;
import static mage.constants.Zone.LIBRARY;
import mage.counters.Counter;
import mage.counters.CounterType;
import mage.counters.Counters;
@ -77,6 +68,11 @@ import mage.util.GameLog;
import mage.util.RandomUtil;
import org.apache.log4j.Logger;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Map.Entry;
public abstract class PlayerImpl implements Player, Serializable {
private static final Logger logger = Logger.getLogger(PlayerImpl.class);
@ -878,6 +874,11 @@ public abstract class PlayerImpl implements Player, Serializable {
return true;
}
@Override
public boolean putCardsOnBottomOfLibrary(Card card, Game game, Ability source, boolean anyOrder) {
return putCardsOnBottomOfLibrary(new CardsImpl(card), game, source, anyOrder);
}
@Override
public boolean putCardsOnBottomOfLibrary(Cards cardsToLibrary, Game game, Ability source, boolean anyOrder) {
if (!cardsToLibrary.isEmpty()) {
@ -2562,7 +2563,7 @@ public abstract class PlayerImpl implements Player, Serializable {
/**
* @param game
* @param appliedEffects
* @param numSides Number of sides the dice has
* @param numSides Number of sides the dice has
* @return the number that the player rolled
*/
@Override
@ -2596,10 +2597,10 @@ public abstract class PlayerImpl implements Player, Serializable {
/**
* @param game
* @param appliedEffects
* @param numberChaosSides The number of chaos sides the planar die
* currently has (normally 1 but can be 5)
* @param numberChaosSides The number of chaos sides the planar die
* currently has (normally 1 but can be 5)
* @param numberPlanarSides The number of chaos sides the planar die
* currently has (normally 1)
* currently has (normally 1)
* @return the outcome that the player rolled. Either ChaosRoll, PlanarRoll
* or NilRoll
*/
@ -2756,7 +2757,7 @@ public abstract class PlayerImpl implements Player, Serializable {
/**
* @param ability
* @param available if null, it won't be checked if enough mana is available
* @param available if null, it won't be checked if enough mana is available
* @param sourceObject
* @param game
* @return
@ -3308,7 +3309,7 @@ public abstract class PlayerImpl implements Player, Serializable {
@Override
public boolean canPaySacrificeCost(Permanent permanent, UUID sourceId,
UUID controllerId, Game game
UUID controllerId, Game game
) {
return sacrificeCostFilter == null || !sacrificeCostFilter.match(permanent, sourceId, controllerId, game);
}
@ -3456,8 +3457,8 @@ public abstract class PlayerImpl implements Player, Serializable {
@Override
public boolean moveCards(Card card, Zone toZone,
Ability source, Game game,
boolean tapped, boolean faceDown, boolean byOwner, List<UUID> appliedEffects
Ability source, Game game,
boolean tapped, boolean faceDown, boolean byOwner, List<UUID> appliedEffects
) {
Set<Card> cardList = new HashSet<>();
if (card != null) {
@ -3468,22 +3469,22 @@ public abstract class PlayerImpl implements Player, Serializable {
@Override
public boolean moveCards(Cards cards, Zone toZone,
Ability source, Game game
Ability source, Game game
) {
return moveCards(cards.getCards(game), toZone, source, game);
}
@Override
public boolean moveCards(Set<Card> cards, Zone toZone,
Ability source, Game game
Ability source, Game game
) {
return moveCards(cards, toZone, source, game, false, false, false, null);
}
@Override
public boolean moveCards(Set<Card> cards, Zone toZone,
Ability source, Game game,
boolean tapped, boolean faceDown, boolean byOwner, List<UUID> appliedEffects
Ability source, Game game,
boolean tapped, boolean faceDown, boolean byOwner, List<UUID> appliedEffects
) {
if (cards.isEmpty()) {
return true;
@ -3569,8 +3570,8 @@ public abstract class PlayerImpl implements Player, Serializable {
@Override
public boolean moveCardsToExile(Card card, Ability source,
Game game, boolean withName, UUID exileId,
String exileZoneName
Game game, boolean withName, UUID exileId,
String exileZoneName
) {
Set<Card> cards = new HashSet<>();
cards.add(card);
@ -3579,8 +3580,8 @@ public abstract class PlayerImpl implements Player, Serializable {
@Override
public boolean moveCardsToExile(Set<Card> cards, Ability source,
Game game, boolean withName, UUID exileId,
String exileZoneName
Game game, boolean withName, UUID exileId,
String exileZoneName
) {
if (cards.isEmpty()) {
return true;
@ -3595,14 +3596,14 @@ public abstract class PlayerImpl implements Player, Serializable {
@Override
public boolean moveCardToHandWithInfo(Card card, UUID sourceId,
Game game
Game game
) {
return this.moveCardToHandWithInfo(card, sourceId, game, true);
}
@Override
public boolean moveCardToHandWithInfo(Card card, UUID sourceId,
Game game, boolean withName
Game game, boolean withName
) {
boolean result = false;
Zone fromZone = game.getState().getZone(card.getId());
@ -3627,7 +3628,7 @@ public abstract class PlayerImpl implements Player, Serializable {
@Override
public Set<Card> moveCardsToGraveyardWithInfo(Set<Card> allCards, Ability source,
Game game, Zone fromZone
Game game, Zone fromZone
) {
UUID sourceId = source == null ? null : source.getSourceId();
Set<Card> movedCards = new LinkedHashSet<>();
@ -3635,7 +3636,7 @@ public abstract class PlayerImpl implements Player, Serializable {
// identify cards from one owner
Cards cards = new CardsImpl();
UUID ownerId = null;
for (Iterator<Card> it = allCards.iterator(); it.hasNext();) {
for (Iterator<Card> it = allCards.iterator(); it.hasNext(); ) {
Card card = it.next();
if (cards.isEmpty()) {
ownerId = card.getOwnerId();
@ -3696,7 +3697,7 @@ public abstract class PlayerImpl implements Player, Serializable {
@Override
public boolean moveCardToGraveyardWithInfo(Card card, UUID sourceId,
Game game, Zone fromZone
Game game, Zone fromZone
) {
if (card == null) {
return false;
@ -3725,8 +3726,8 @@ public abstract class PlayerImpl implements Player, Serializable {
@Override
public boolean moveCardToLibraryWithInfo(Card card, UUID sourceId,
Game game, Zone fromZone,
boolean toTop, boolean withName
Game game, Zone fromZone,
boolean toTop, boolean withName
) {
if (card == null) {
return false;
@ -3760,7 +3761,7 @@ public abstract class PlayerImpl implements Player, Serializable {
@Override
public boolean moveCardToExileWithInfo(Card card, UUID exileId, String exileName, UUID sourceId,
Game game, Zone fromZone, boolean withName) {
Game game, Zone fromZone, boolean withName) {
if (card == null) {
return false;
}

View file

@ -71,7 +71,7 @@ public class PermanentsEnteredBattlefieldWatcher extends Watcher {
return enteringBattlefield.get(playerId);
}
public boolean AnotherCreatureEnteredBattlefieldUnderPlayersControlLastTurn(Permanent sourcePermanent, Game game) {
public boolean anotherCreatureEnteredBattlefieldUnderPlayersControlLastTurn(Permanent sourcePermanent, Game game) {
if (enteringBattlefieldLastTurn.containsKey(sourcePermanent.getControllerId())) {
for (Permanent permanent : enteringBattlefieldLastTurn.get(sourcePermanent.getControllerId())) {
if (!permanent.getId().equals(sourcePermanent.getId())