Merge branch 'master' into address_mage_stuff

This commit is contained in:
Zach Halpern 2019-01-10 21:35:12 -05:00
commit 1712b05c33
29 changed files with 1181 additions and 176 deletions

View file

@ -1,7 +1,6 @@
package mage.abilities.effects.common;
import java.util.UUID;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.SpellAbility;
@ -20,11 +19,13 @@ import mage.players.Player;
import mage.target.common.TargetControlledCreaturePermanent;
import mage.target.targetpointer.FixedTarget;
import java.util.UUID;
/**
* FAQ 2013/01/11
*
* <p>
* 702.97. Cipher
*
* <p>
* 702.97a Cipher appears on some instants and sorceries. It represents two
* static abilities, one that functions while the spell is on the stack and one
* that functions while the card with cipher is in the exile zone. "Cipher"
@ -33,17 +34,17 @@ import mage.target.targetpointer.FixedTarget;
* that creature, that creature has 'Whenever this creature deals combat damage
* to a player, you may copy this card and you may cast the copy without paying
* its mana cost.'"
*
* <p>
* 702.97b The term "encoded" describes the relationship between the card with
* cipher while in the exile zone and the creature chosen when the spell
* represented by that card resolves.
*
* <p>
* 702.97c The card with cipher remains encoded on the chosen creature as long
* as the card with cipher remains exiled and the creature remains on the
* battlefield. The card remains encoded on that object even if it changes
* controller or stops being a creature, as long as it remains on the
* battlefield.
*
* <p>
* TODO: Implement Cipher as two static abilities concerning the rules.
*
* @author LevelX2
@ -114,20 +115,13 @@ class CipherStoreEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
Card cipherCard = game.getCard(cipherCardId);
if (cipherCard != null) {
if (cipherCard != null && controller != null) {
Card copyCard = game.copyCard(cipherCard, source, controller.getId());
SpellAbility ability = copyCard.getSpellAbility();
// remove the cipher effect from the copy
Effect cipherEffect = null;
for (Effect effect : ability.getEffects()) {
if (effect instanceof CipherEffect) {
cipherEffect = effect;
}
}
ability.getEffects().remove(cipherEffect);
if (ability instanceof SpellAbility) {
controller.cast(ability, game, true, new MageObjectReference(source.getSourceObject(game), game));
}
ability.getEffects().removeIf(effect -> effect instanceof CipherEffect);
controller.cast(ability, game, true, new MageObjectReference(source.getSourceObject(game), game));
}
return false;

View file

@ -12,7 +12,6 @@ import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
/**
*
* @author LevelX2
*/
public class CantAttackYouUnlessPayManaAllEffect extends PayCostToAttackBlockEffectImpl {
@ -37,7 +36,7 @@ public class CantAttackYouUnlessPayManaAllEffect extends PayCostToAttackBlockEff
+ (payAlsoForAttackingPlaneswalker ? "or a planeswalker you control " : "")
+ "unless their controller pays "
+ (manaCosts == null ? "" : manaCosts.getText())
+ " for each creature he or she controls that's attacking you";
+ " for each creature they controls that's attacking you";
}
public CantAttackYouUnlessPayManaAllEffect(final CantAttackYouUnlessPayManaAllEffect effect) {

View file

@ -0,0 +1,44 @@
package mage.abilities.keyword;
import mage.abilities.MageSingleton;
import mage.abilities.common.SimpleStaticAbility;
import mage.constants.Zone;
import java.io.ObjectStreamException;
/**
* Hexproof from Monocolored (This creature or player can't be the target of monocolored
* spells or abilities your opponents control.)
*
* @author TheElk801
*/
public class HexproofFromMonocoloredAbility extends SimpleStaticAbility implements MageSingleton {
private static final HexproofFromMonocoloredAbility instance;
static {
instance = new HexproofFromMonocoloredAbility();
}
private Object readResolve() throws ObjectStreamException {
return instance;
}
public static HexproofFromMonocoloredAbility getInstance() {
return instance;
}
private HexproofFromMonocoloredAbility() {
super(Zone.BATTLEFIELD, null);
}
@Override
public HexproofFromMonocoloredAbility copy() {
return instance;
}
@Override
public String getRule() {
return "hexproof from monocolored <i>(This creature can't be the target of monocolored spells or abilities your opponents control.)</i>";
}
}

View file

@ -1,8 +1,6 @@
package mage.abilities.mana;
import java.util.ArrayList;
import java.util.List;
import mage.Mana;
import mage.abilities.Abilities;
import mage.abilities.Ability;
@ -20,8 +18,10 @@ import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author LevelX2
*/
public class AnyColorLandsProduceManaAbility extends ActivatedManaAbilityImpl {
@ -31,7 +31,11 @@ public class AnyColorLandsProduceManaAbility extends ActivatedManaAbilityImpl {
}
public AnyColorLandsProduceManaAbility(TargetController targetController, boolean onlyColors) {
super(Zone.BATTLEFIELD, new AnyColorLandsProduceManaEffect(targetController, onlyColors), new TapSourceCost());
this(targetController, onlyColors, null);
}
public AnyColorLandsProduceManaAbility(TargetController targetController, boolean onlyColors, FilterPermanent filter) {
super(Zone.BATTLEFIELD, new AnyColorLandsProduceManaEffect(targetController, onlyColors, filter), new TapSourceCost());
}
public AnyColorLandsProduceManaAbility(final AnyColorLandsProduceManaAbility ability) {
@ -62,16 +66,21 @@ class AnyColorLandsProduceManaEffect extends ManaEffect {
private boolean inManaTypeCalculation = false;
public AnyColorLandsProduceManaEffect(TargetController targetController, boolean onlyColors) {
AnyColorLandsProduceManaEffect(TargetController targetController, boolean onlyColors, FilterPermanent filter) {
super();
filter = new FilterLandPermanent();
if (filter == null) {
this.filter = new FilterLandPermanent();
} else {
this.filter = filter.copy();
}
this.onlyColors = onlyColors;
filter.add(new ControllerPredicate(targetController));
this.filter.add(new ControllerPredicate(targetController));
String text = targetController == TargetController.OPPONENT ? "an opponent controls" : "you control";
staticText = "Add one mana of any " + (this.onlyColors ? "color" : "type") + " that a land " + text + " could produce";
staticText = "Add one mana of any " + (this.onlyColors ? "color" : "type") + " that a "
+ (filter == null ? "land " : filter.getMessage() + " ") + text + " could produce";
}
public AnyColorLandsProduceManaEffect(final AnyColorLandsProduceManaEffect effect) {
private AnyColorLandsProduceManaEffect(final AnyColorLandsProduceManaEffect effect) {
super(effect);
this.filter = effect.filter.copy();
this.onlyColors = effect.onlyColors;

View file

@ -43,7 +43,7 @@ public abstract class PermanentImpl extends CardImpl implements Permanent {
private static final Logger logger = Logger.getLogger(PermanentImpl.class);
public class MarkedDamageInfo {
static class MarkedDamageInfo {
public MarkedDamageInfo(Counter counter, MageObject sourceObject) {
this.counter = counter;
@ -956,6 +956,14 @@ public abstract class PermanentImpl extends CardImpl implements Permanent {
}
}
if (abilities.containsKey(HexproofFromMonocoloredAbility.getInstance().getId())) {
if (game.getPlayer(this.getControllerId()).hasOpponent(sourceControllerId, game)
&& null == game.getContinuousEffects().asThough(this.getId(), AsThoughEffectType.HEXPROOF, null, sourceControllerId, game)
&& !source.getColor(game).isColorless() && !source.getColor(game).isMulticolored()) {
return false;
}
}
if (hasProtectionFrom(source, game)) {
return false;
}