Merge branch 'master' into feature/HASCON2017Promos

This commit is contained in:
Eleros 2017-08-09 22:11:19 +02:00 committed by GitHub
commit b770e8ba51
332 changed files with 27691 additions and 3161 deletions

View file

@ -36,10 +36,6 @@ public interface MageObject extends MageItem, Serializable {
boolean hasSubtype(SubType subtype, Game game);
default boolean hasSubtype(String subtype, Game game){
return hasSubtype(SubType.byDescription(subtype), game);
}
EnumSet<SuperType> getSuperType();
Abilities<Ability> getAbilities();

View file

@ -111,6 +111,23 @@ public class ObjectColor implements Serializable, Copyable<ObjectColor>, Compara
return newColor;
}
/**
* Returns a new color which contains the intersection of the colors of this
* ObjectColor and the other ObjectColor.
*
* @param other The other ObjectColor to intersect with
* @return A new color which is the intersection of this and other
*/
public ObjectColor intersection(ObjectColor other) {
ObjectColor newColor = new ObjectColor();
newColor.white = white && other.white;
newColor.blue = blue && other.blue;
newColor.black = black && other.black;
newColor.red = red && other.red;
newColor.green = green && other.green;
return newColor;
}
public int getColorCount() {
int count = 0;
if (white) {

View file

@ -0,0 +1,87 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package mage.abilities.condition.common;
import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.condition.Condition;
import mage.filter.FilterPermanent;
import mage.filter.predicate.Predicate;
import mage.filter.predicate.mageobject.ColorPredicate;
import mage.game.Game;
/**
*
* @author TheElk801
*/
public class MostCommonColorCondition implements Condition {
protected ObjectColor compareColor;
protected boolean isMono;
protected Predicate predicate;
public MostCommonColorCondition(ObjectColor color) {
this(color, false, null);
}
//Use this one if you don't want a tie for most common and want to restrict to a player (literally only Call to Arms)
public MostCommonColorCondition(ObjectColor color, boolean isMono, Predicate predicate) {
this.compareColor = color;
this.isMono = isMono;
}
@Override
public boolean apply(Game game, Ability source) {
FilterPermanent[] colorFilters = new FilterPermanent[6];
int i = 0;
for (ObjectColor color : ObjectColor.getAllColors()) {
colorFilters[i] = new FilterPermanent();
colorFilters[i].add(new ColorPredicate(color));
if (predicate != null) {
colorFilters[i].add(predicate);
}
i++;
}
int[] colorCounts = new int[6];
i = 0;
for (ObjectColor color : ObjectColor.getAllColors()) {
colorFilters[i].add(new ColorPredicate(color));
colorCounts[i] = game.getBattlefield().count(colorFilters[i], source.getId(), source.getControllerId(), game);
i++;
}
int max = 0;
for (i = 0; i < 5; i++) {
if (colorCounts[i] > max) {
max = colorCounts[i] * 1;
}
}
i = 0;
ObjectColor commonest = new ObjectColor();
for (ObjectColor color : ObjectColor.getAllColors()) {
if (colorCounts[i] == max) {
commonest.addColor(color);
}
i++;
}
if (compareColor.shares(commonest)) {
if (isMono) {
return !commonest.isMulticolored();
} else {
return true;
}
}
return false;
}
@Override
public String toString() {
if (!compareColor.isMulticolored()) {
return compareColor.getDescription() + " is the most common color among all permanents or is tied for most common";
} else {
return "it shares a color with the most common color among all permanents or a color tied for most common";
}
}
}

View file

@ -39,6 +39,7 @@ import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.util.CardUtil;
import java.util.LinkedHashSet;
import java.util.stream.Collectors;
/**
@ -65,7 +66,7 @@ public class ChooseCreatureTypeEffect extends OneShotEffect {
if (controller != null && mageObject != null) {
Choice typeChoice = new ChoiceImpl(true);
typeChoice.setMessage("Choose creature type");
typeChoice.setChoices(SubType.getCreatureTypes(false).stream().map(SubType::toString).collect(Collectors.toSet()));
typeChoice.setChoices(SubType.getCreatureTypes(false).stream().map(SubType::toString).collect(Collectors.toCollection(LinkedHashSet::new)));
while (!controller.choose(outcome, typeChoice, game)) {
if (!controller.canRespond()) {
return false;
@ -74,7 +75,7 @@ public class ChooseCreatureTypeEffect extends OneShotEffect {
if (!game.isSimulation()) {
game.informPlayers(mageObject.getName() + ": " + controller.getLogName() + " has chosen " + typeChoice.getChoice());
}
game.getState().setValue(mageObject.getId() + "_type", typeChoice.getChoice());
game.getState().setValue(mageObject.getId() + "_type", SubType.byDescription(typeChoice.getChoice()));
if (mageObject instanceof Permanent) {
((Permanent) mageObject).addInfo("chosen type", CardUtil.addToolTipMarkTags("Chosen type: " + typeChoice.getChoice()), game);
}

View file

@ -53,7 +53,7 @@ public class ChooseLandTypeEffect extends OneShotEffect {
if (!game.isSimulation()) {
game.informPlayers(mageObject.getName() + ": " + controller.getLogName() + " has chosen " + typeChoice.getChoice());
}
game.getState().setValue(mageObject.getId() + "_type", typeChoice.getChoice());
game.getState().setValue(mageObject.getId() + "_type", SubType.byDescription(typeChoice.getChoice()));
if (mageObject instanceof Permanent) {
((Permanent) mageObject).addInfo("chosen type", CardUtil.addToolTipMarkTags("Chosen type: " + typeChoice.getChoice()), game);
}

View file

@ -45,7 +45,7 @@ public class CantBlockUnlessYouControlSourceEffect extends RestrictionEffect {
public CantBlockUnlessYouControlSourceEffect(FilterControlledPermanent filter) {
super(Duration.WhileOnBattlefield);
this.filter = filter;
staticText = "{this} can't block unless you control" + filter.getMessage();
staticText = "{this} can't block unless you control " + filter.getMessage();
}
public CantBlockUnlessYouControlSourceEffect(final CantBlockUnlessYouControlSourceEffect effect) {

View file

@ -32,7 +32,6 @@ import mage.abilities.Ability;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.constants.*;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterLandPermanent;
import mage.game.Game;
import mage.game.permanent.Permanent;
@ -43,9 +42,9 @@ import mage.game.permanent.Permanent;
public class AddCardSubtypeAllEffect extends ContinuousEffectImpl {
private static FilterPermanent filter;
private static String addedSubtype;
private static SubType addedSubtype;
public AddCardSubtypeAllEffect(FilterPermanent _filter, String _addedSubtype, DependencyType _dependency) {
public AddCardSubtypeAllEffect(FilterPermanent _filter, SubType _addedSubtype, DependencyType _dependency) {
super(Duration.WhileOnBattlefield, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Benefit);
filter = _filter;
staticText = "";

View file

@ -30,24 +30,19 @@ package mage.abilities.effects.common.continuous;
import mage.abilities.Ability;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.mana.*;
import mage.constants.Duration;
import mage.constants.Layer;
import mage.constants.Outcome;
import mage.constants.SubLayer;
import mage.constants.*;
import mage.game.Game;
import mage.game.permanent.Permanent;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class BecomesBasicLandEnchantedEffect extends ContinuousEffectImpl {
protected final static ArrayList<String> allLandTypes = new ArrayList<>();
protected List<SubType> landTypes = new ArrayList<>();
protected ArrayList<String> landTypes = new ArrayList<>();
public BecomesBasicLandEnchantedEffect(String... landNames) {
public BecomesBasicLandEnchantedEffect(SubType... landNames) {
super(Duration.WhileOnBattlefield, Outcome.Detriment);
landTypes.addAll(Arrays.asList(landNames));
this.staticText = setText();
@ -77,30 +72,30 @@ public class BecomesBasicLandEnchantedEffect extends ContinuousEffectImpl {
switch (layer) {
case AbilityAddingRemovingEffects_6:
permanent.removeAllAbilities(source.getSourceId(), game);
for (String landType : landTypes) {
for (SubType landType : landTypes) {
switch (landType) {
case "Swamp":
if (permanent.getSubtype(game).contains("Swamp")) { // type can be removed by other effect with newer timestamp, so no ability adding
case SWAMP:
if (permanent.getSubtype(game).contains(SubType.SWAMP)) { // type can be removed by other effect with newer timestamp, so no ability adding
permanent.addAbility(new BlackManaAbility(), source.getSourceId(), game);
}
break;
case "Mountain":
if (permanent.getSubtype(game).contains("Mountain")) {
case MOUNTAIN:
if (permanent.getSubtype(game).contains(SubType.MOUNTAIN)) {
permanent.addAbility(new RedManaAbility(), source.getSourceId(), game);
}
break;
case "Forest":
if (permanent.getSubtype(game).contains("Forest")) {
case FOREST:
if (permanent.getSubtype(game).contains(SubType.FOREST)) {
permanent.addAbility(new GreenManaAbility(), source.getSourceId(), game);
}
break;
case "Island":
if (permanent.getSubtype(game).contains("Island")) {
case ISLAND:
if (permanent.getSubtype(game).contains(SubType.ISLAND)) {
permanent.addAbility(new BlueManaAbility(), source.getSourceId(), game);
}
break;
case "Plains":
if (permanent.getSubtype(game).contains("Plains")) {
case PLAINS:
if (permanent.getSubtype(game).contains(SubType.PLAINS)) {
permanent.addAbility(new WhiteManaAbility(), source.getSourceId(), game);
}
break;
@ -109,7 +104,7 @@ public class BecomesBasicLandEnchantedEffect extends ContinuousEffectImpl {
break;
case TypeChangingEffects_4:
// subtypes are all removed by changing the subtype to a land type.
permanent.getSubtype(game).removeAll(allLandTypes);
permanent.getSubtype(game).removeAll(SubType.getLandTypes(false));
permanent.getSubtype(game).addAll(landTypes);
break;
}
@ -127,7 +122,7 @@ public class BecomesBasicLandEnchantedEffect extends ContinuousEffectImpl {
private String setText() {
StringBuilder sb = new StringBuilder("Enchanted land is a ");
int i = 1;
for (String landType : landTypes) {
for (SubType landType : landTypes) {
if (i > 1) {
if (i == landTypes.size()) {
sb.append(" and ");

View file

@ -39,6 +39,7 @@ import mage.players.Player;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
/**
@ -49,38 +50,38 @@ import java.util.UUID;
public class BecomesBasicLandTargetEffect extends ContinuousEffectImpl {
protected boolean chooseLandType;
protected ArrayList<String> landTypes = new ArrayList();
protected ArrayList<String> landTypesToAdd = new ArrayList();
protected List<SubType> landTypes = new ArrayList<>();
protected List<SubType> landTypesToAdd = new ArrayList<>();
protected boolean loseOther; // loses all other abilities, card types, and creature types
public BecomesBasicLandTargetEffect(Duration duration) {
this(duration, true, new String[0]);
this(duration, true);
}
public BecomesBasicLandTargetEffect(Duration duration, String... landNames) {
public BecomesBasicLandTargetEffect(Duration duration, SubType... landNames) {
this(duration, false, landNames);
}
public BecomesBasicLandTargetEffect(Duration duration, boolean chooseLandType, String... landNames) {
public BecomesBasicLandTargetEffect(Duration duration, boolean chooseLandType, SubType... landNames) {
this(duration, chooseLandType, true, landNames);
}
public BecomesBasicLandTargetEffect(Duration duration, boolean chooseLandType, boolean loseOther, String... landNames) {
public BecomesBasicLandTargetEffect(Duration duration, boolean chooseLandType, boolean loseOther, SubType... landNames) {
super(duration, Outcome.Detriment);
this.landTypes.addAll(Arrays.asList(landNames));
if (landTypes.contains("Mountain")) {
if (landTypes.contains(SubType.MOUNTAIN)) {
dependencyTypes.add(DependencyType.BecomeMountain);
}
if (landTypes.contains("Forest")) {
if (landTypes.contains(SubType.FOREST)) {
dependencyTypes.add(DependencyType.BecomeForest);
}
if (landTypes.contains("Swamp")) {
if (landTypes.contains(SubType.SWAMP)) {
dependencyTypes.add(DependencyType.BecomeSwamp);
}
if (landTypes.contains("Island")) {
if (landTypes.contains(SubType.ISLAND)) {
dependencyTypes.add(DependencyType.BecomeIsland);
}
if (landTypes.contains("Plains")) {
if (landTypes.contains(SubType.PLAINS)) {
dependencyTypes.add(DependencyType.BecomePlains);
}
this.chooseLandType = chooseLandType;
@ -116,7 +117,7 @@ public class BecomesBasicLandTargetEffect extends ContinuousEffectImpl {
if (controller != null) {
Choice choice = new ChoiceBasicLandType();
controller.choose(outcome, choice, game);
landTypes.add(choice.getChoice());
landTypes.add(SubType.byDescription(choice.getChoice()));
} else {
this.discard();
}
@ -147,7 +148,7 @@ public class BecomesBasicLandTargetEffect extends ContinuousEffectImpl {
land.getSubtype(game).addAll(landTypes);
} else {
landTypesToAdd.clear();
for (String subtype : landTypes) {
for (SubType subtype : landTypes) {
if (!land.getSubtype(game).contains(subtype)) {
land.getSubtype(game).add(subtype);
landTypesToAdd.add(subtype);
@ -156,21 +157,21 @@ public class BecomesBasicLandTargetEffect extends ContinuousEffectImpl {
}
break;
case AbilityAddingRemovingEffects_6:
for (String landType : landTypesToAdd) {
for (SubType landType : landTypesToAdd) {
switch (landType) {
case "Swamp":
case SWAMP:
land.addAbility(new BlackManaAbility(), source.getSourceId(), game);
break;
case "Mountain":
case MOUNTAIN:
land.addAbility(new RedManaAbility(), source.getSourceId(), game);
break;
case "Forest":
case FOREST:
land.addAbility(new GreenManaAbility(), source.getSourceId(), game);
break;
case "Island":
case ISLAND:
land.addAbility(new BlueManaAbility(), source.getSourceId(), game);
break;
case "Plains":
case PLAINS:
land.addAbility(new WhiteManaAbility(), source.getSourceId(), game);
break;
}
@ -194,7 +195,7 @@ public class BecomesBasicLandTargetEffect extends ContinuousEffectImpl {
} else {
sb.append("Target land becomes a ");
int i = 1;
for (String landType : landTypes) {
for (SubType landType : landTypes) {
if (i > 1) {
if (i == landTypes.size()) {
sb.append(" and ");

View file

@ -6,16 +6,13 @@ import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.choices.Choice;
import mage.choices.ChoiceImpl;
import mage.choices.ChoiceCreatureType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.game.Game;
import mage.players.Player;
import mage.target.targetpointer.FixedTarget;
import mage.util.SubTypeList;
import java.util.stream.Collectors;
public class BecomesChosenCreatureTypeTargetEffect extends OneShotEffect {
@ -48,17 +45,15 @@ public class BecomesChosenCreatureTypeTargetEffect extends OneShotEffect {
Card card = game.getCard(source.getSourceId());
String chosenType = "";
if (player != null && card != null) {
Choice typeChoice = new ChoiceImpl(true);
Choice typeChoice = new ChoiceCreatureType();
String msg = "Choose a creature type";
if(nonWall) {
msg += " other than Wall";
}
typeChoice.setMessage(msg);
SubTypeList types = SubType.getCreatureTypes(false);
if(nonWall) {
types.remove(SubType.WALL);
typeChoice.getChoices().remove(SubType.WALL.getDescription());
}
typeChoice.setChoices(types.stream().map(SubType::toString).collect(Collectors.toSet()));
while (!player.choose(Outcome.BoostCreature, typeChoice, game)) {
if (!player.canRespond()) {
return false;

View file

@ -48,9 +48,9 @@ public class BoostAllOfChosenSubtypeEffect extends BoostAllEffect {
@Override
protected void setRuntimeData(Ability source, Game game) {
String s = (String) game.getState().getValue(source.getSourceId() + "_type");
if (subtype != null) {
subtype = SubType.byDescription(s);
SubType s = (SubType) game.getState().getValue(source.getSourceId() + "_type");
if (s != null) {
subtype = s;
} else {
discard();
}

View file

@ -44,8 +44,8 @@ public class GainAbilityAllOfChosenSubtypeEffect extends GainAbilityAllEffect {
@Override
protected void setRuntimeData(Ability source, Game game) {
String s = (String) game.getState().getValue(source.getSourceId() + "_type");
subtype = SubType.byDescription(s);
subtype = (SubType) game.getState().getValue(source.getSourceId() + "_type");
}
}

View file

@ -32,9 +32,9 @@ public class SpellsCostReductionAllOfChosenSubtypeEffect extends SpellsCostReduc
@Override
protected boolean selectedByRuntimeData(Card card, Ability source, Game game) {
String subtype = (String) game.getState().getValue(source.getSourceId() + "_type");
SubType subtype = (SubType) game.getState().getValue(source.getSourceId() + "_type");
if (subtype != null) {
return card.hasSubtype(SubType.byDescription(subtype), game);
return card.hasSubtype(subtype, game);
}
return false;
}

View file

@ -0,0 +1,71 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.abilities.effects.common.counter;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.constants.Outcome;
import mage.counters.CounterType;
import mage.game.Game;
import mage.game.permanent.Permanent;
/**
*
* @author TheElk801
*/
public class RemoveAllCountersSourceEffect extends OneShotEffect {
private final CounterType counterType;
public RemoveAllCountersSourceEffect(CounterType counterType) {
super(Outcome.Neutral);
this.counterType = counterType;
staticText = "remove all " + counterType.getName() + " counters from {this}.";
}
public RemoveAllCountersSourceEffect(RemoveAllCountersSourceEffect effect) {
super(effect);
this.counterType = effect.counterType;
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getSourceId());
if(permanent != null) {
int count = permanent.getCounters(game).getCount(counterType);
permanent.removeCounters(counterType.getName(), count, game);
return true;
}
return false;
}
@Override
public RemoveAllCountersSourceEffect copy() {
return new RemoveAllCountersSourceEffect(this);
}
}

View file

@ -31,6 +31,7 @@ import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.game.Game;
import mage.game.permanent.Permanent;
@ -57,7 +58,7 @@ public class EnterAttributeAddChosenSubtypeEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanentEntering(source.getSourceId());
String subtype = (String) game.getState().getValue(source.getSourceId() + "_type");
SubType subtype = (SubType) game.getState().getValue(source.getSourceId() + "_type");
if (permanent != null && subtype != null) {
MageObject mageObject = permanent.getBasicMageObject(game);
if (!mageObject.getSubtype(null).contains(subtype)) {

View file

@ -94,7 +94,7 @@ class AuraSwapEffect extends OneShotEffect {
if (controller != null) {
Permanent auraSourcePermanent = game.getPermanent(source.getSourceId());
if (auraSourcePermanent != null
&& auraSourcePermanent.getSubtype(game).contains("Aura")
&& auraSourcePermanent.getSubtype(game).contains(SubType.AURA)
&& auraSourcePermanent.getOwnerId().equals(source.getControllerId())) {
Permanent enchantedPermanent = game.getPermanent(auraSourcePermanent.getAttachedTo());
filterCardToCheck.add(new AuraCardCanAttachToPermanentId(enchantedPermanent.getId()));

View file

@ -110,8 +110,8 @@ class EmbalmEffect extends OneShotEffect {
EmptyToken token = new EmptyToken();
CardUtil.copyTo(token).from(card); // needed so that entersBattlefied triggered abilities see the attributes (e.g. Master Biomancer)
token.getColor(game).setColor(ObjectColor.WHITE);
if (!token.getSubtype(game).contains("Zombie")) {
token.getSubtype(game).add(0, "Zombie");
if (!token.getSubtype(game).contains(SubType.ZOMBIE)) {
token.getSubtype(game).add(0, SubType.ZOMBIE);
}
token.getManaCost().clear();
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.EMBALMED_CREATURE, token.getId(), source.getSourceId(), controller.getId()));

View file

@ -115,13 +115,13 @@ class EternalizeEffect extends OneShotEffect {
EmptyToken token = new EmptyToken();
CardUtil.copyTo(token).from(card); // needed so that entersBattlefied triggered abilities see the attributes (e.g. Master Biomancer)
token.getColor(game).setColor(ObjectColor.BLACK);
if (!token.getSubtype(game).contains("Zombie")) {
token.getSubtype(game).add(0, "Zombie");
if (!token.getSubtype(game).contains(SubType.ZOMBIE)) {
token.getSubtype(game).add(0, SubType.ZOMBIE);
}
token.getManaCost().clear();
token.getPower().modifyBaseValue(4);
token.getToughness().modifyBaseValue(4);
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.EMBALMED_CREATURE, token.getId(), source.getSourceId(), controller.getId()));
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.ETERNALIZED_CREATURE, token.getId(), source.getSourceId(), controller.getId()));
token.putOntoBattlefield(1, game, source.getSourceId(), source.getControllerId(), false, false, null);
// Probably it makes sense to remove also the Eternalize ability (it's not shown on the token cards).
// Also it can never get active or? But it's not mentioned in the reminder text.

View file

@ -1,8 +1,9 @@
package mage.cards;
import java.io.Serializable;
import mage.constants.Rarity;
import java.io.Serializable;
public final class CardSetInfo implements Serializable {
private final String name;
@ -22,7 +23,7 @@ public final class CardSetInfo implements Serializable {
this.rarity = rarity;
if (graphicInfo == null && Rarity.LAND == rarity) {
// Workaround to get images of basic land permanents loaded
this.graphicInfo = new CardGraphicInfo(null, true);
this.graphicInfo = ExpansionSet.NON_FULL_USE_VARIOUS;
} else {
this.graphicInfo = graphicInfo;
}

View file

@ -43,6 +43,9 @@ import java.util.stream.Collectors;
*/
public abstract class ExpansionSet implements Serializable {
public final static CardGraphicInfo NON_FULL_USE_VARIOUS = new CardGraphicInfo(null, true);
public final static CardGraphicInfo FULL_ART_BFZ_VARIOUS = new CardGraphicInfo(FrameStyle.BFZ_FULL_ART_BASIC, true);
public class SetCardInfo implements Serializable {
private final String name;
@ -305,29 +308,22 @@ public abstract class ExpansionSet implements Serializable {
private void addSpecial(List<Card> booster) {
int specialCards = 0;
List<CardInfo> specialBonus = getSpecialBonus();
if (specialBonus != null) {
specialCards += specialBonus.size();
}
specialCards += specialBonus.size();
List<CardInfo> specialMythic = getSpecialMythic();
if (specialMythic != null) {
specialCards += specialMythic.size();
}
specialCards += specialMythic.size();
List<CardInfo> specialRare = getSpecialRare();
if (specialRare != null) {
specialCards += specialRare.size();
}
specialCards += specialRare.size();
List<CardInfo> specialUncommon = getSpecialUncommon();
if (specialUncommon != null) {
specialCards += specialUncommon.size();
}
specialCards += specialUncommon.size();
List<CardInfo> specialCommon = getSpecialCommon();
if (specialCommon != null) {
specialCards += specialCommon.size();
}
specialCards += specialCommon.size();
if (specialCards > 0) {
for (int i = 0; i < numBoosterSpecial; i++) {
if (RandomUtil.nextInt(15) < 10) {
if (specialCommon != null && !specialCommon.isEmpty()) {
if (!specialCommon.isEmpty()) {
addToBooster(booster, specialCommon);
} else {
i--;
@ -335,7 +331,7 @@ public abstract class ExpansionSet implements Serializable {
continue;
}
if (RandomUtil.nextInt(4) < 3) {
if (specialUncommon != null && !specialUncommon.isEmpty()) {
if (!specialUncommon.isEmpty()) {
addToBooster(booster, specialUncommon);
} else {
i--;
@ -343,15 +339,15 @@ public abstract class ExpansionSet implements Serializable {
continue;
}
if (RandomUtil.nextInt(8) < 7) {
if (specialRare != null && !specialRare.isEmpty()) {
if (!specialRare.isEmpty()) {
addToBooster(booster, specialRare);
} else {
i--;
}
continue;
}
if (specialMythic != null && !specialMythic.isEmpty()) {
if (specialBonus != null && !specialBonus.isEmpty()) {
if (!specialMythic.isEmpty()) {
if (!specialBonus.isEmpty()) {
if (RandomUtil.nextInt(3) < 2) {
addToBooster(booster, specialMythic);
continue;
@ -363,7 +359,7 @@ public abstract class ExpansionSet implements Serializable {
} else {
i--;
}
if (specialBonus != null && !specialBonus.isEmpty()) {
if (!specialBonus.isEmpty()) {
addToBooster(booster, specialBonus);
}
}
@ -404,27 +400,27 @@ public abstract class ExpansionSet implements Serializable {
}
public List<CardInfo> getSpecialCommon() {
return null;
return new ArrayList<>();
}
public List<CardInfo> getSpecialUncommon() {
return null;
return new ArrayList<>();
}
public List<CardInfo> getSpecialRare() {
return null;
return new ArrayList<>();
}
public List<CardInfo> getSpecialMythic() {
return null;
return new ArrayList<>();
}
public List<CardInfo> getSpecialBonus() {
return null;
return new ArrayList<>();
}
public List<CardInfo> getSpecialLand() {
return null;
return new ArrayList<>();
}
public boolean isCustomSet() {

View file

@ -2,13 +2,14 @@ package mage.choices;
import mage.constants.SubType;
import java.util.LinkedHashSet;
import java.util.stream.Collectors;
public class ChoiceCreatureType extends ChoiceImpl {
public ChoiceCreatureType() {
super(true);
this.setChoices(SubType.getCreatureTypes(false).stream().map(SubType::toString).collect(Collectors.toSet()));
this.setChoices(SubType.getCreatureTypes(false).stream().map(SubType::toString).collect(Collectors.toCollection(LinkedHashSet::new)));
this.message = "Choose a creature type:";
}

View file

@ -0,0 +1,58 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.filter.common;
import mage.constants.SubType;
import mage.filter.FilterPermanent;
import mage.filter.predicate.mageobject.SubtypePredicate;
/**
*
* @author TheElk801
*/
public class FilterEquipmentPermanent extends FilterPermanent {
public FilterEquipmentPermanent() {
this("equipment");
}
public FilterEquipmentPermanent(String name) {
super(name);
this.add(new SubtypePredicate(SubType.EQUIPMENT));
}
public FilterEquipmentPermanent(final FilterEquipmentPermanent filter) {
super(filter);
}
@Override
public FilterEquipmentPermanent copy() {
return new FilterEquipmentPermanent(this);
}
}

View file

@ -48,8 +48,8 @@ public class ChosenSubtypePredicate implements Predicate<MageObject> {
@Override
public boolean apply(MageObject input, Game game) {
String subtype = (String) game.getState().getValue(cardID + "_type");
return input.hasSubtype(SubType.byDescription(subtype), game);
SubType subtype = (SubType) game.getState().getValue(cardID + "_type");
return input.hasSubtype(subtype, game);
}
@Override

View file

@ -292,6 +292,7 @@ public class GameEvent implements Serializable {
EXPLOITED_CREATURE,
EVOLVED_CREATURE,
EMBALMED_CREATURE,
ETERNALIZED_CREATURE,
ATTACH, ATTACHED,
STAY_ATTACHED,
UNATTACH, UNATTACHED,

View file

@ -27,7 +27,6 @@
*/
package mage.game.permanent;
import java.util.*;
import mage.MageObject;
import mage.MageObjectReference;
import mage.ObjectColor;
@ -56,6 +55,8 @@ import mage.players.Player;
import mage.util.GameLog;
import mage.util.ThreadLocalStringBuilder;
import java.util.*;
/**
* @author BetaSteward_at_googlemail.com
*/
@ -925,7 +926,7 @@ public abstract class PermanentImpl extends CardImpl implements Permanent {
@Override
public boolean cantBeAttachedBy(MageObject source, Game game) {
for (ProtectionAbility ability : this.getAbilities(game).getProtectionAbilities()) {
if (!(source.getSubtype(game).contains("Aura")
if (!(source.getSubtype(game).contains(SubType.AURA)
&& !ability.removesAuras())
&& !source.getId().equals(ability.getAuraIdNotToBeRemoved())
&& !ability.canTarget(source, game)) {

View file

@ -30,6 +30,7 @@ package mage.game.permanent.token;
import mage.constants.CardType;
import mage.MageInt;
import mage.ObjectColor;
import mage.constants.SubType;
/**
*
@ -40,8 +41,8 @@ public class RiptideReplicatorToken extends Token {
public RiptideReplicatorToken() {
this(null, null, 1);
}
public RiptideReplicatorToken(ObjectColor color, String type, int x) {
super(type, "X/X creature token of the chosen color and type");
public RiptideReplicatorToken(ObjectColor color, SubType type, int x) {
super(type.getDescription(), "X/X creature token of the chosen color and type");
cardType.add(CardType.CREATURE);
if (color != null) {
this.color.setColor(color);

View file

@ -30,6 +30,7 @@ package mage.game.permanent.token;
import mage.constants.CardType;
import mage.MageInt;
import mage.ObjectColor;
import mage.constants.SubType;
/**
*
@ -40,8 +41,8 @@ public class VolrathsLaboratoryToken extends Token {
public VolrathsLaboratoryToken() {
this(null, null);
}
public VolrathsLaboratoryToken(ObjectColor color, String type) {
super(type, "2/2 creature token of the chosen color and type");
public VolrathsLaboratoryToken(ObjectColor color, SubType type) {
super(type.getDescription(), "2/2 creature token of the chosen color and type");
cardType.add(CardType.CREATURE);
if (color != null) {
this.color.setColor(color);

View file

@ -0,0 +1,64 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.target.common;
import mage.filter.common.FilterEquipmentPermanent;
import mage.target.TargetPermanent;
/**
*
* @author TheElk801
*/
public class TargetEquipmentPermanent extends TargetPermanent {
public TargetEquipmentPermanent() {
this(1, 1, new FilterEquipmentPermanent(), false);
}
public TargetEquipmentPermanent(FilterEquipmentPermanent filter) {
this(1, 1, filter, false);
}
public TargetEquipmentPermanent(int numTargets) {
this(numTargets, numTargets, new FilterEquipmentPermanent(), false);
}
public TargetEquipmentPermanent(int minNumTargets, int maxNumTargets, FilterEquipmentPermanent filter, boolean notTarget) {
super(minNumTargets, maxNumTargets, filter, notTarget);
}
public TargetEquipmentPermanent(final TargetEquipmentPermanent target) {
super(target);
}
@Override
public TargetEquipmentPermanent copy() {
return new TargetEquipmentPermanent(this);
}
}

View file

@ -9,15 +9,6 @@ import java.util.stream.Collectors;
public class SubTypeList extends ArrayList<SubType> {
public void add(int index, String s) {
add(index, SubType.byDescription(s));
}
public void add(int index, SubType s) {
super.add(index, s);
}
public boolean addAll(List<String> subtypes) {
return addAll(subtypes.stream().map(SubType::byDescription).collect(Collectors.toList()));
}
@ -26,9 +17,6 @@ public class SubTypeList extends ArrayList<SubType> {
return removeAll(subtypes.stream().map(SubType::byDescription).collect(Collectors.toList()));
}
public boolean add(SubType s) {
return super.add(s);
}
public boolean add(SubType... subTypes) {
return Collections.addAll(this, subTypes);