Merge pull request #2856 from ingmargoudt/master

rewrites and cleanups
This commit is contained in:
ingmargoudt 2017-02-12 13:37:01 +01:00 committed by GitHub
commit 86bae57d87
41 changed files with 178 additions and 239 deletions

View file

@ -28,6 +28,7 @@ public class PropertiesUtil {
} }
} else { } else {
logger.warn("No xmage.properties were found on classpath"); logger.warn("No xmage.properties were found on classpath");
} }
} }

View file

@ -52,7 +52,7 @@ public class SessionManager {
private final ConcurrentHashMap<String, Session> sessions = new ConcurrentHashMap<>(); private final ConcurrentHashMap<String, Session> sessions = new ConcurrentHashMap<>();
public Session getSession(String sessionId) { public Session getSession(String sessionId) {
if (sessions == null || sessionId == null) { if (sessionId == null) {
return null; return null;
} }
Session session = sessions.get(sessionId); Session session = sessions.get(sessionId);

View file

@ -171,7 +171,7 @@ public class DraftController {
return false; return false;
} }
for (DraftPlayer player: draft.getPlayers()) { for (DraftPlayer player: draft.getPlayers()) {
if (player.getPlayer().isHuman() && draftSessions.get(player.getPlayer().getId()) == null) { if (player.getPlayer().isHuman() && !draftSessions.containsKey(player.getPlayer().getId())) {
return false; return false;
} }
} }

View file

@ -111,12 +111,7 @@ class TargetCardInLibrarySharingLandType extends TargetCardInLibrary {
landTypes = new HashSet<>(); landTypes = new HashSet<>();
landTypes.addAll(landCard.getSubtype(game)); landTypes.addAll(landCard.getSubtype(game));
} else { } else {
for (Iterator<String> iterator = landTypes.iterator(); iterator.hasNext();) { landTypes.removeIf(next -> !landCard.getSubtype(game).contains(next));
String next = iterator.next();
if (!landCard.getSubtype(game).contains(next)) {
iterator.remove();
}
}
} }
} }
} }

View file

@ -33,6 +33,7 @@ import java.util.Collections;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import mage.abilities.common.ZoneChangeTriggeredAbility; import mage.abilities.common.ZoneChangeTriggeredAbility;
import mage.abilities.costs.Cost; import mage.abilities.costs.Cost;
import mage.abilities.keyword.ProtectionAbility; import mage.abilities.keyword.ProtectionAbility;
@ -44,9 +45,8 @@ import mage.util.ThreadLocalStringBuilder;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
/** /**
*
* @author BetaSteward_at_googlemail.com
* @param <T> * @param <T>
* @author BetaSteward_at_googlemail.com
*/ */
public class AbilitiesImpl<T extends Ability> extends ArrayList<T> implements Abilities<T> { public class AbilitiesImpl<T extends Ability> extends ArrayList<T> implements Abilities<T> {
@ -171,7 +171,7 @@ public class AbilitiesImpl<T extends Ability> extends ArrayList<T> implements Ab
public Abilities<Ability> getManaAbilities(Zone zone) { public Abilities<Ability> getManaAbilities(Zone zone) {
Abilities<Ability> abilities = new AbilitiesImpl<>(); Abilities<Ability> abilities = new AbilitiesImpl<>();
for (T ability : this) { for (T ability : this) {
if (ability.getAbilityType().equals(AbilityType.MANA) && ability.getZone().match(zone)) { if (ability.getAbilityType() == AbilityType.MANA && ability.getZone().match(zone)) {
abilities.add(ability); abilities.add(ability);
} }
} }
@ -257,7 +257,7 @@ public class AbilitiesImpl<T extends Ability> extends ArrayList<T> implements Ab
@Override @Override
public boolean contains(T ability) { public boolean contains(T ability) {
for (Iterator<T> iterator = this.iterator(); iterator.hasNext();) { // simple loop can cause java.util.ConcurrentModificationException for (Iterator<T> iterator = this.iterator(); iterator.hasNext(); ) { // simple loop can cause java.util.ConcurrentModificationException
T test = iterator.next(); T test = iterator.next();
// Checking also by getRule() without other restrictions is a problem when a triggered ability will be copied to a permanent that had the same ability // Checking also by getRule() without other restrictions is a problem when a triggered ability will be copied to a permanent that had the same ability
// already before the copy. Because then it keeps the triggered ability twice and it triggers twice. // already before the copy. Because then it keeps the triggered ability twice and it triggers twice.
@ -287,6 +287,7 @@ public class AbilitiesImpl<T extends Ability> extends ArrayList<T> implements Ab
@Override @Override
public boolean containsAll(Abilities<T> abilities) { public boolean containsAll(Abilities<T> abilities) {
if (this.size() < abilities.size()) { if (this.size() < abilities.size()) {
return false; return false;
} }

View file

@ -54,7 +54,7 @@ import mage.game.events.GameEvent;
if (this.size() > 0) { if (this.size() > 0) {
for (Iterator<DelayedTriggeredAbility> it = this.iterator();it.hasNext();) { for (Iterator<DelayedTriggeredAbility> it = this.iterator();it.hasNext();) {
DelayedTriggeredAbility ability = it.next(); DelayedTriggeredAbility ability = it.next();
if (ability.getDuration().equals(Duration.Custom)){ if (ability.getDuration()== Duration.Custom){
if (ability.isInactive(game)) { if (ability.isInactive(game)) {
it.remove(); it.remove();
continue; continue;
@ -74,21 +74,11 @@ import mage.game.events.GameEvent;
} }
public void removeEndOfTurnAbilities() { public void removeEndOfTurnAbilities() {
for (Iterator<DelayedTriggeredAbility> it = this.iterator();it.hasNext();) { this.removeIf(ability -> ability.getDuration() == Duration.EndOfTurn);
DelayedTriggeredAbility ability = it.next();
if (ability.getDuration() == Duration.EndOfTurn) {
it.remove();
}
}
} }
public void removeEndOfCombatAbilities() { public void removeEndOfCombatAbilities() {
for (Iterator<DelayedTriggeredAbility> it = this.iterator();it.hasNext();) { this.removeIf(ability -> ability.getDuration() == Duration.EndOfCombat);
DelayedTriggeredAbility ability = it.next();
if (ability.getDuration() == Duration.EndOfCombat) {
it.remove();
}
}
} }

View file

@ -67,11 +67,6 @@ public class SpecialActions extends AbilitiesImpl<SpecialAction> {
} }
public void removeManaActions() { public void removeManaActions() {
for (Iterator<SpecialAction> iterator = this.iterator(); iterator.hasNext();) { this.removeIf(SpecialAction::isManaAction);
SpecialAction next = iterator.next();
if (next.isManaAction()) {
iterator.remove();
}
}
} }
} }

View file

@ -27,22 +27,18 @@
*/ */
package mage.abilities; package mage.abilities;
import java.util.UUID;
import mage.MageObject; import mage.MageObject;
import mage.abilities.costs.mana.ManaCost; import mage.abilities.costs.mana.ManaCost;
import mage.abilities.keyword.FlashAbility; import mage.abilities.keyword.FlashAbility;
import mage.cards.SplitCard; import mage.cards.SplitCard;
import mage.constants.AbilityType; import mage.constants.*;
import mage.constants.AsThoughEffectType;
import mage.constants.SpellAbilityType;
import mage.constants.TimingRule;
import mage.constants.Zone;
import mage.game.Game; import mage.game.Game;
import mage.game.events.GameEvent; import mage.game.events.GameEvent;
import mage.players.Player; import mage.players.Player;
import java.util.UUID;
/** /**
*
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
public class SpellAbility extends ActivatedAbilityImpl { public class SpellAbility extends ActivatedAbilityImpl {
@ -90,7 +86,7 @@ public class SpellAbility extends ActivatedAbilityImpl {
public boolean canActivate(UUID playerId, Game game) { public boolean canActivate(UUID playerId, Game game) {
if (game.getContinuousEffects().asThough(sourceId, AsThoughEffectType.CAST_AS_INSTANT, this, playerId, game) // check this first to allow Offering in main phase if (game.getContinuousEffects().asThough(sourceId, AsThoughEffectType.CAST_AS_INSTANT, this, playerId, game) // check this first to allow Offering in main phase
|| this.spellCanBeActivatedRegularlyNow(playerId, game)) { || this.spellCanBeActivatedRegularlyNow(playerId, game)) {
if (spellAbilityType.equals(SpellAbilityType.SPLIT)) { if (spellAbilityType == SpellAbilityType.SPLIT) {
return false; return false;
} }
// fix for Gitaxian Probe and casting opponent's spells // fix for Gitaxian Probe and casting opponent's spells
@ -106,7 +102,7 @@ public class SpellAbility extends ActivatedAbilityImpl {
} }
} }
// Alternate spell abilities (Flashback, Overload) can't be cast with no mana to pay option // Alternate spell abilities (Flashback, Overload) can't be cast with no mana to pay option
if (getSpellAbilityType().equals(SpellAbilityType.BASE_ALTERNATE)) { if (getSpellAbilityType()== SpellAbilityType.BASE_ALTERNATE) {
Player player = game.getPlayer(playerId); Player player = game.getPlayer(playerId);
if (player != null && getSourceId().equals(player.getCastSourceIdWithAlternateMana())) { if (player != null && getSourceId().equals(player.getCastSourceIdWithAlternateMana())) {
return false; return false;

View file

@ -56,7 +56,7 @@ public abstract class StaticAbility extends AbilityImpl {
if (game.getShortLivingLKI(getSourceId(), zone)) { if (game.getShortLivingLKI(getSourceId(), zone)) {
return true; // maybe this can be a problem if effects removed the ability from the object return true; // maybe this can be a problem if effects removed the ability from the object
} }
if (game.getPermanentEntering(getSourceId()) != null && zone.equals(Zone.BATTLEFIELD)) { if (game.getPermanentEntering(getSourceId()) != null && zone == Zone.BATTLEFIELD) {
return true; // abilities of permanents entering battlefield are countes as on battlefield return true; // abilities of permanents entering battlefield are countes as on battlefield
} }
return super.isInUseableZone(game, source, event); return super.isInUseableZone(game, source, event);

View file

@ -188,7 +188,7 @@ public abstract class TriggeredAbilityImpl extends AbilityImpl implements Trigge
case ZONE_CHANGE: case ZONE_CHANGE:
case DESTROYED_PERMANENT: case DESTROYED_PERMANENT:
if (isLeavesTheBattlefieldTrigger()) { if (isLeavesTheBattlefieldTrigger()) {
if (event.getType().equals(EventType.DESTROYED_PERMANENT)) { if (event.getType() == EventType.DESTROYED_PERMANENT) {
source = game.getLastKnownInformation(getSourceId(), Zone.BATTLEFIELD); source = game.getLastKnownInformation(getSourceId(), Zone.BATTLEFIELD);
} else if (((ZoneChangeEvent) event).getTarget() != null) { } else if (((ZoneChangeEvent) event).getTarget() != null) {
source = ((ZoneChangeEvent) event).getTarget(); source = ((ZoneChangeEvent) event).getTarget();

View file

@ -77,7 +77,7 @@ public class AttackedByCreatureTriggeredAbility extends TriggeredAbilityImpl {
UUID playerId = game.getCombat().getDefendingPlayerId(event.getSourceId(), game); UUID playerId = game.getCombat().getDefendingPlayerId(event.getSourceId(), game);
Permanent attackingCreature = game.getPermanent(event.getSourceId()); Permanent attackingCreature = game.getPermanent(event.getSourceId());
if (getControllerId().equals(playerId) && attackingCreature != null) { if (getControllerId().equals(playerId) && attackingCreature != null) {
if (!setTargetPointer.equals(SetTargetPointer.NONE)) { if (setTargetPointer != SetTargetPointer.NONE) {
for (Effect effect : this.getEffects()) { for (Effect effect : this.getEffects()) {
switch (setTargetPointer) { switch (setTargetPointer) {
case PERMANENT: case PERMANENT:

View file

@ -46,7 +46,7 @@ public class BeginningOfCombatTriggeredAbility extends TriggeredAbilityImpl {
boolean yours = event.getPlayerId().equals(this.controllerId); boolean yours = event.getPlayerId().equals(this.controllerId);
if (yours && setTargetPointer) { if (yours && setTargetPointer) {
if (getTargets().isEmpty()) { if (getTargets().isEmpty()) {
this.getEffects().stream().forEach((effect) -> { this.getEffects().forEach(effect -> {
effect.setTargetPointer(new FixedTarget(event.getPlayerId())); effect.setTargetPointer(new FixedTarget(event.getPlayerId()));
}); });
} }
@ -55,7 +55,7 @@ public class BeginningOfCombatTriggeredAbility extends TriggeredAbilityImpl {
case OPPONENT: case OPPONENT:
if (game.getPlayer(this.controllerId).hasOpponent(event.getPlayerId(), game)) { if (game.getPlayer(this.controllerId).hasOpponent(event.getPlayerId(), game)) {
if (setTargetPointer) { if (setTargetPointer) {
this.getEffects().stream().forEach((effect) -> { this.getEffects().forEach(effect -> {
effect.setTargetPointer(new FixedTarget(event.getPlayerId())); effect.setTargetPointer(new FixedTarget(event.getPlayerId()));
}); });
} }
@ -64,7 +64,7 @@ public class BeginningOfCombatTriggeredAbility extends TriggeredAbilityImpl {
break; break;
case ANY: case ANY:
if (setTargetPointer) { if (setTargetPointer) {
this.getEffects().stream().forEach((effect) -> { this.getEffects().forEach(effect -> {
effect.setTargetPointer(new FixedTarget(event.getPlayerId())); effect.setTargetPointer(new FixedTarget(event.getPlayerId()));
}); });
} }

View file

@ -62,7 +62,7 @@ public class CycleAllTriggeredAbility extends TriggeredAbilityImpl {
} }
StackObject item = game.getState().getStack().getFirst(); StackObject item = game.getState().getStack().getFirst();
if (item instanceof StackAbility if (item instanceof StackAbility
&& ((StackAbility) item).getStackAbility() instanceof CyclingAbility) { && item.getStackAbility() instanceof CyclingAbility) {
return true; return true;
} }
return false; return false;

View file

@ -76,7 +76,7 @@ public class DealsCombatDamageTriggeredAbility extends TriggeredAbilityImpl {
return true; return true;
} }
if (event.getType().equals(GameEvent.EventType.COMBAT_DAMAGE_STEP_PRE)) { if (event.getType()== GameEvent.EventType.COMBAT_DAMAGE_STEP_PRE) {
usedInPhase = false; usedInPhase = false;
} }
return false; return false;

View file

@ -13,7 +13,6 @@ import mage.game.events.GameEvent;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
/** /**
*
* @author LevelX2 * @author LevelX2
*/ */
@ -34,9 +33,9 @@ public class DealsDamageAttachedTriggeredAbility extends TriggeredAbilityImpl {
@Override @Override
public boolean checkEventType(GameEvent event, Game game) { public boolean checkEventType(GameEvent event, Game game) {
return event.getType().equals(GameEvent.EventType.DAMAGED_CREATURE) return event.getType() == GameEvent.EventType.DAMAGED_CREATURE
|| event.getType().equals(GameEvent.EventType.DAMAGED_PLAYER) || event.getType() == GameEvent.EventType.DAMAGED_PLAYER
|| event.getType().equals(GameEvent.EventType.DAMAGED_PLANESWALKER); || event.getType() == GameEvent.EventType.DAMAGED_PLANESWALKER;
} }
@Override @Override

View file

@ -38,7 +38,6 @@ import mage.game.permanent.Permanent;
import mage.target.targetpointer.FixedTarget; import mage.target.targetpointer.FixedTarget;
/** /**
*
* @author LevelX * @author LevelX
*/ */
public class DealsDamageToACreatureAttachedTriggeredAbility extends TriggeredAbilityImpl { public class DealsDamageToACreatureAttachedTriggeredAbility extends TriggeredAbilityImpl {
@ -76,8 +75,7 @@ public class DealsDamageToACreatureAttachedTriggeredAbility extends TriggeredAbi
Permanent attachment = game.getPermanent(this.getSourceId()); Permanent attachment = game.getPermanent(this.getSourceId());
if (attachment != null if (attachment != null
&& attachment.getAttachedTo() != null && attachment.getAttachedTo() != null
&& event.getSourceId().equals(attachment.getAttachedTo()) && event.getSourceId().equals(attachment.getAttachedTo())) {
) {
if (setTargetPointer) { if (setTargetPointer) {
for (Effect effect : this.getEffects()) { for (Effect effect : this.getEffects()) {
effect.setTargetPointer(new FixedTarget(event.getTargetId())); effect.setTargetPointer(new FixedTarget(event.getTargetId()));
@ -95,7 +93,7 @@ public class DealsDamageToACreatureAttachedTriggeredAbility extends TriggeredAbi
public String getRule() { public String getRule() {
return new StringBuilder("Whenever ").append(attachedDescription) return new StringBuilder("Whenever ").append(attachedDescription)
.append(" deals ") .append(" deals ")
.append(combatOnly ? "combat ":"") .append(combatOnly ? "combat " : "")
.append("damage to a creature, ") .append("damage to a creature, ")
.append(super.getRule()).toString(); .append(super.getRule()).toString();
} }

View file

@ -11,7 +11,6 @@ import mage.game.Game;
import mage.game.events.GameEvent; import mage.game.events.GameEvent;
/** /**
*
* @author LevelX2 * @author LevelX2
*/ */
public class DealsDamageToOneOrMoreCreaturesTriggeredAbility extends DealsDamageToACreatureTriggeredAbility { public class DealsDamageToOneOrMoreCreaturesTriggeredAbility extends DealsDamageToACreatureTriggeredAbility {
@ -28,7 +27,8 @@ public class DealsDamageToOneOrMoreCreaturesTriggeredAbility extends DealsDamage
public boolean checkTrigger(GameEvent event, Game game) { public boolean checkTrigger(GameEvent event, Game game) {
if (super.checkTrigger(event, game)) { if (super.checkTrigger(event, game)) {
// check that combat damage does only once trigger also if multiple creatures were damaged because they block or were blocked by source // check that combat damage does only once trigger also if multiple creatures were damaged because they block or were blocked by source
if (game.getTurn().getStepType().equals(PhaseStep.COMBAT_DAMAGE) || game.getTurn().getStepType().equals(PhaseStep.FIRST_COMBAT_DAMAGE)) { if (game.getTurn().getStepType() == PhaseStep.COMBAT_DAMAGE
|| game.getTurn().getStepType() == PhaseStep.FIRST_COMBAT_DAMAGE) {
String stepHash = (String) game.getState().getValue("damageStep" + getOriginalId()); String stepHash = (String) game.getState().getValue("damageStep" + getOriginalId());
String newStepHash = game.getStep().getType().toString() + game.getTurnNum(); String newStepHash = game.getStep().getType().toString() + game.getTurnNum();
if (stepHash == null || !newStepHash.equals(stepHash)) { if (stepHash == null || !newStepHash.equals(stepHash)) {

View file

@ -67,7 +67,7 @@ public class DiesCreatureTriggeredAbility extends TriggeredAbilityImpl {
@Override @Override
public boolean checkTrigger(GameEvent event, Game game) { public boolean checkTrigger(GameEvent event, Game game) {
ZoneChangeEvent zEvent = (ZoneChangeEvent) event; ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
if (zEvent.getFromZone().equals(Zone.BATTLEFIELD) && zEvent.getToZone().equals(Zone.GRAVEYARD)) { if (zEvent.getFromZone() == Zone.BATTLEFIELD && zEvent.getToZone() == Zone.GRAVEYARD) {
if (filter.match(zEvent.getTarget(), sourceId, controllerId, game)) { if (filter.match(zEvent.getTarget(), sourceId, controllerId, game)) {
if (setTargetPointer) { if (setTargetPointer) {
for (Effect effect : this.getEffects()) { for (Effect effect : this.getEffects()) {

View file

@ -77,7 +77,7 @@ public class LandfallAbility extends TriggeredAbilityImpl {
&& permanent.getCardType().contains(CardType.LAND) && permanent.getCardType().contains(CardType.LAND)
&& permanent.getControllerId().equals(this.controllerId)) { && permanent.getControllerId().equals(this.controllerId)) {
triggeringLand = permanent; triggeringLand = permanent;
if (setTargetPointer.equals(SetTargetPointer.PERMANENT)) { if (setTargetPointer == SetTargetPointer.PERMANENT) {
for (Effect effect : getAllEffects()) { for (Effect effect : getAllEffects()) {
effect.setTargetPointer(new FixedTarget(permanent, game)); effect.setTargetPointer(new FixedTarget(permanent, game));
} }

View file

@ -87,7 +87,7 @@ public class SpellCastAllTriggeredAbility extends TriggeredAbilityImpl {
public boolean checkTrigger(GameEvent event, Game game) { public boolean checkTrigger(GameEvent event, Game game) {
Spell spell = game.getStack().getSpell(event.getTargetId()); Spell spell = game.getStack().getSpell(event.getTargetId());
if (spell != null && filter.match(spell, getSourceId(), getControllerId(), game)) { if (spell != null && filter.match(spell, getSourceId(), getControllerId(), game)) {
if (!setTargetPointer.equals(SetTargetPointer.NONE)) { if (setTargetPointer != SetTargetPointer.NONE) {
for (Effect effect : this.getEffects()) { for (Effect effect : this.getEffects()) {
switch (setTargetPointer) { switch (setTargetPointer) {
case SPELL: case SPELL:

View file

@ -38,7 +38,6 @@ import mage.game.stack.Spell;
import mage.target.targetpointer.FixedTarget; import mage.target.targetpointer.FixedTarget;
/** /**
*
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
public class SpellCastOpponentTriggeredAbility extends TriggeredAbilityImpl { public class SpellCastOpponentTriggeredAbility extends TriggeredAbilityImpl {
@ -60,7 +59,6 @@ public class SpellCastOpponentTriggeredAbility extends TriggeredAbilityImpl {
} }
/** /**
*
* @param zone * @param zone
* @param effect * @param effect
* @param filter * @param filter
@ -89,8 +87,8 @@ public class SpellCastOpponentTriggeredAbility extends TriggeredAbilityImpl {
if (game.getPlayer(this.getControllerId()).hasOpponent(event.getPlayerId(), game)) { if (game.getPlayer(this.getControllerId()).hasOpponent(event.getPlayerId(), game)) {
Spell spell = game.getStack().getSpell(event.getTargetId()); Spell spell = game.getStack().getSpell(event.getTargetId());
if (spell != null && filter.match(spell, game)) { if (spell != null && filter.match(spell, game)) {
if (!setTargetPointer.equals(SetTargetPointer.NONE)) { if (setTargetPointer != SetTargetPointer.NONE) {
for (Effect effect: this.getEffects()) { for (Effect effect : this.getEffects()) {
switch (setTargetPointer) { switch (setTargetPointer) {
case SPELL: case SPELL:
effect.setTargetPointer(new FixedTarget(event.getTargetId())); effect.setTargetPointer(new FixedTarget(event.getTargetId()));

View file

@ -44,7 +44,7 @@ public class SpellCounteredControllerTriggeredAbility extends TriggeredAbilityIm
@Override @Override
public boolean checkTrigger(GameEvent event, Game game) { public boolean checkTrigger(GameEvent event, Game game) {
StackObject stackObjectThatCountered = (StackObject) game.getStack().getStackObject(event.getSourceId()); StackObject stackObjectThatCountered = game.getStack().getStackObject(event.getSourceId());
if (stackObjectThatCountered == null) { if (stackObjectThatCountered == null) {
stackObjectThatCountered = (StackObject) game.getLastKnownInformation(event.getSourceId(), Zone.STACK); stackObjectThatCountered = (StackObject) game.getLastKnownInformation(event.getSourceId(), Zone.STACK);
} }

View file

@ -37,7 +37,6 @@ import mage.game.events.GameEvent.EventType;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
/** /**
*
* @author LevelX2 * @author LevelX2
*/ */
public class AtTheBeginOfMainPhaseDelayedTriggeredAbility extends DelayedTriggeredAbility { public class AtTheBeginOfMainPhaseDelayedTriggeredAbility extends DelayedTriggeredAbility {
@ -93,8 +92,8 @@ public class AtTheBeginOfMainPhaseDelayedTriggeredAbility extends DelayedTrigger
case ANY: case ANY:
return true; return true;
case YOU: case YOU:
boolean yours = event.getPlayerId().equals(this.controllerId); return event.getPlayerId().equals(this.controllerId);
return yours;
case OPPONENT: case OPPONENT:
if (game.getPlayer(this.getControllerId()).hasOpponent(event.getPlayerId(), game)) { if (game.getPlayer(this.getControllerId()).hasOpponent(event.getPlayerId(), game)) {
return true; return true;
@ -117,11 +116,11 @@ public class AtTheBeginOfMainPhaseDelayedTriggeredAbility extends DelayedTrigger
switch (phaseSelection) { switch (phaseSelection) {
case NEXT_MAIN: case NEXT_MAIN:
case NEXT_MAIN_THIS_TURN: case NEXT_MAIN_THIS_TURN:
return EventType.PRECOMBAT_MAIN_PHASE_PRE.equals(eventType) || EventType.POSTCOMBAT_MAIN_PHASE_PRE.equals(eventType); return EventType.PRECOMBAT_MAIN_PHASE_PRE == eventType || EventType.POSTCOMBAT_MAIN_PHASE_PRE == eventType;
case NEXT_POSTCOMAT_MAIN: case NEXT_POSTCOMAT_MAIN:
return EventType.POSTCOMBAT_MAIN_PHASE_PRE.equals(eventType); return EventType.POSTCOMBAT_MAIN_PHASE_PRE == eventType;
case NEXT_PRECOMBAT_MAIN: case NEXT_PRECOMBAT_MAIN:
return EventType.PRECOMBAT_MAIN_PHASE_PRE.equals(eventType); return EventType.PRECOMBAT_MAIN_PHASE_PRE == eventType;
default: default:
return false; return false;
} }

View file

@ -73,8 +73,8 @@ public class AtTheBeginOfNextEndStepDelayedTriggeredAbility extends DelayedTrigg
case ANY: case ANY:
return true; return true;
case YOU: case YOU:
boolean yours = event.getPlayerId().equals(this.controllerId); return event.getPlayerId().equals(this.controllerId);
return yours;
case OPPONENT: case OPPONENT:
if (game.getPlayer(this.getControllerId()).hasOpponent(event.getPlayerId(), game)) { if (game.getPlayer(this.getControllerId()).hasOpponent(event.getPlayerId(), game)) {
return true; return true;

View file

@ -11,7 +11,6 @@ import mage.constants.PhaseStep;
import mage.game.Game; import mage.game.Game;
/** /**
*
* @author LevelX2 * @author LevelX2
*/ */
public class AfterUpkeepStepCondtion implements Condition { public class AfterUpkeepStepCondtion implements Condition {
@ -24,8 +23,8 @@ public class AfterUpkeepStepCondtion implements Condition {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
return !(game.getStep().getType().equals(PhaseStep.UNTAP) return !(game.getStep().getType() == PhaseStep.UNTAP
|| game.getStep().getType().equals(PhaseStep.UPKEEP)); || game.getStep().getType() == PhaseStep.UPKEEP);
} }
@Override @Override

View file

@ -44,7 +44,7 @@ import mage.util.CardUtil;
*/ */
public class CardsInHandCondition implements Condition { public class CardsInHandCondition implements Condition {
public static enum CountType { public enum CountType {
MORE_THAN, FEWER_THAN, EQUAL_TO MORE_THAN, FEWER_THAN, EQUAL_TO
} }

View file

@ -53,7 +53,7 @@ public class IsStepCondition implements Condition {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
return phaseStep.equals(game.getStep().getType()) && (!onlyDuringYourSteps || game.getActivePlayerId().equals(source.getControllerId())); return phaseStep == game.getStep().getType() && (!onlyDuringYourSteps || game.getActivePlayerId().equals(source.getControllerId()));
} }
@Override @Override

View file

@ -166,12 +166,7 @@ public class AlternativeCostSourceAbility extends StaticAbility implements Alter
if (alternativeCostsToCheck.canPay(ability, ability.getSourceId(), ability.getControllerId(), game) if (alternativeCostsToCheck.canPay(ability, ability.getSourceId(), ability.getControllerId(), game)
&& player.chooseUse(Outcome.Benefit, costChoiceText, this, game)) { && player.chooseUse(Outcome.Benefit, costChoiceText, this, game)) {
if (ability instanceof SpellAbility) { if (ability instanceof SpellAbility) {
for (Iterator<ManaCost> iterator = ability.getManaCostsToPay().iterator(); iterator.hasNext();) { ability.getManaCostsToPay().removeIf(manaCost -> manaCost instanceof VariableCost);
ManaCost manaCost = iterator.next();
if (manaCost instanceof VariableCost) {
iterator.remove();
}
}
CardUtil.reduceCost((SpellAbility) ability, ability.getManaCosts()); CardUtil.reduceCost((SpellAbility) ability, ability.getManaCosts());
} else { } else {

View file

@ -52,7 +52,7 @@ public class OptionalAdditionalCostImpl<T extends OptionalAdditionalCostImpl> ex
this.delimiter = delimiter; this.delimiter = delimiter;
this.reminderText = "<i>(" + reminderText + ")</i>"; this.reminderText = "<i>(" + reminderText + ")</i>";
this.activatedCounter = 0; this.activatedCounter = 0;
this.add((Cost) cost); this.add(cost);
} }
public OptionalAdditionalCostImpl(final OptionalAdditionalCostImpl cost) { public OptionalAdditionalCostImpl(final OptionalAdditionalCostImpl cost) {

View file

@ -20,7 +20,7 @@ public final class CardSetInfo implements Serializable {
this.expansionSetCode = expansionSetCode; this.expansionSetCode = expansionSetCode;
this.cardNumber = cardNumber; this.cardNumber = cardNumber;
this.rarity = rarity; this.rarity = rarity;
if (graphicInfo == null && Rarity.LAND.equals(rarity)) { if (graphicInfo == null && Rarity.LAND == rarity) {
// Workaround to get images of basic land permanents loaded // Workaround to get images of basic land permanents loaded
this.graphicInfo = new CardGraphicInfo(null, true); this.graphicInfo = new CardGraphicInfo(null, true);
} else { } else {

View file

@ -37,10 +37,12 @@ import com.j256.ormlite.stmt.Where;
import com.j256.ormlite.support.ConnectionSource; import com.j256.ormlite.support.ConnectionSource;
import com.j256.ormlite.support.DatabaseConnection; import com.j256.ormlite.support.DatabaseConnection;
import com.j256.ormlite.table.TableUtils; import com.j256.ormlite.table.TableUtils;
import java.io.File; import java.io.File;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.*; import java.util.*;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.SetType; import mage.constants.SetType;
@ -48,7 +50,6 @@ import mage.util.RandomUtil;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
/** /**
*
* @author North * @author North
*/ */
public enum CardRepository { public enum CardRepository {
@ -61,7 +62,7 @@ public enum CardRepository {
private static final long CARD_DB_VERSION = 50; private static final long CARD_DB_VERSION = 50;
// raise this if new cards were added to the server // raise this if new cards were added to the server
private static final long CARD_CONTENT_VERSION = 70; private static final long CARD_CONTENT_VERSION = 70;
private final TreeSet<String> landTypes = new TreeSet(); private final TreeSet<String> landTypes = new TreeSet<>();
private Dao<CardInfo, Object> cardDao; private Dao<CardInfo, Object> cardDao;
private Set<String> classNames; private Set<String> classNames;
@ -87,9 +88,7 @@ public enum CardRepository {
public void addCards(final List<CardInfo> cards) { public void addCards(final List<CardInfo> cards) {
try { try {
cardDao.callBatchTasks(new Callable<Object>() { cardDao.callBatchTasks(() -> {
@Override
public Object call() throws Exception {
try { try {
for (CardInfo card : cards) { for (CardInfo card : cards) {
cardDao.create(card); cardDao.create(card);
@ -101,7 +100,6 @@ public enum CardRepository {
Logger.getLogger(CardRepository.class).error("Error adding cards to DB - ", ex); Logger.getLogger(CardRepository.class).error("Error adding cards to DB - ", ex);
} }
return null; return null;
}
}); });
} catch (Exception ex) { } catch (Exception ex) {
} }
@ -157,6 +155,7 @@ public enum CardRepository {
} }
} }
} catch (SQLException ex) { } catch (SQLException ex) {
Logger.getLogger(CardRepository.class).error("Error getting names from DB : " + ex);
} }
return names; return names;
} }
@ -178,6 +177,8 @@ public enum CardRepository {
} }
} }
} catch (SQLException ex) { } catch (SQLException ex) {
Logger.getLogger(CardRepository.class).error("Error getting non-land names from DB : " + ex);
} }
return names; return names;
} }
@ -199,6 +200,8 @@ public enum CardRepository {
} }
} }
} catch (SQLException ex) { } catch (SQLException ex) {
Logger.getLogger(CardRepository.class).error("Error getting creature names from DB : " + ex);
} }
return names; return names;
} }
@ -221,6 +224,7 @@ public enum CardRepository {
} }
} }
} catch (SQLException ex) { } catch (SQLException ex) {
Logger.getLogger(CardRepository.class).error("Error getting non-land and non-creature names from DB : " + ex);
} }
return names; return names;
} }
@ -243,6 +247,8 @@ public enum CardRepository {
} }
} }
} catch (SQLException ex) { } catch (SQLException ex) {
Logger.getLogger(CardRepository.class).error("Error getting non-artifact non-land names from DB : " + ex);
} }
return names; return names;
} }
@ -284,6 +290,8 @@ public enum CardRepository {
subtypes.add("Triskelavite"); subtypes.add("Triskelavite");
} catch (SQLException ex) { } catch (SQLException ex) {
Logger.getLogger(CardRepository.class).error("Error getting creaturetypes from DB : " + ex);
} }
return subtypes; return subtypes;
} }
@ -302,6 +310,7 @@ public enum CardRepository {
landTypes.remove("Dryad"); landTypes.remove("Dryad");
} catch (SQLException ex) { } catch (SQLException ex) {
Logger.getLogger(CardRepository.class).error("Error getting landtypes from DB : " + ex);
} }
} }
return landTypes; return landTypes;
@ -316,6 +325,8 @@ public enum CardRepository {
return result.get(0); return result.get(0);
} }
} catch (SQLException ex) { } catch (SQLException ex) {
Logger.getLogger(CardRepository.class).error("Error finding card from DB : " + ex);
} }
return null; return null;
} }
@ -328,6 +339,7 @@ public enum CardRepository {
names.add(card.getClassName()); names.add(card.getClassName());
} }
} catch (SQLException ex) { } catch (SQLException ex) {
Logger.getLogger(CardRepository.class).error("Error getting classnames from DB : " + ex);
} }
return names; return names;
} }
@ -339,12 +351,14 @@ public enum CardRepository {
return cardDao.query(queryBuilder.prepare()); return cardDao.query(queryBuilder.prepare());
} catch (SQLException ex) { } catch (SQLException ex) {
Logger.getLogger(CardRepository.class).error("Error getting missing cards from DB : " + ex);
} }
return Collections.emptyList(); return Collections.emptyList();
} }
/** /**
*
* @param name * @param name
* @return random card with the provided name or null if none is found * @return random card with the provided name or null if none is found
*/ */

View file

@ -57,11 +57,9 @@ public class Counters extends HashMap<String, Counter> implements Serializable {
} }
public void addCounter(Counter counter) { public void addCounter(Counter counter) {
if (!this.containsKey(counter.name)) { putIfAbsent(counter.name, counter);
put(counter.name, counter);
} else {
get(counter.name).add(counter.getCount()); get(counter.name).add(counter.getCount());
}
} }
public boolean removeCounter(String name) { public boolean removeCounter(String name) {

View file

@ -32,6 +32,8 @@ import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.stream.Collectors;
import mage.cards.Card; import mage.cards.Card;
import mage.cards.SplitCard; import mage.cards.SplitCard;
import mage.filter.predicate.ObjectPlayer; import mage.filter.predicate.ObjectPlayer;
@ -41,7 +43,6 @@ import mage.filter.predicate.Predicates;
import mage.game.Game; import mage.game.Game;
/** /**
*
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
* @author North * @author North
*/ */
@ -105,13 +106,8 @@ public class FilterCard extends FilterObject<Card> {
} }
public Set<Card> filter(Set<Card> cards, Game game) { public Set<Card> filter(Set<Card> cards, Game game) {
Set<Card> filtered = new HashSet<>(); return cards.stream().filter(card -> match(card, game)).collect(Collectors.toSet());
for (Card card : cards) {
if (match(card, game)) {
filtered.add(card);
}
}
return filtered;
} }
public boolean hasPredicates() { public boolean hasPredicates() {

View file

@ -87,9 +87,7 @@ public class CardState implements Serializable {
abilities = new AbilitiesImpl<>(); abilities = new AbilitiesImpl<>();
} }
abilities.add(ability); abilities.add(ability);
for (Ability sub : ability.getSubAbilities()) { abilities.addAll(ability.getSubAbilities());
abilities.add(sub);
}
} }
public void clearAbilities() { public void clearAbilities() {

View file

@ -79,10 +79,7 @@ public class Exile implements Serializable, Copyable<Exile> {
} }
private ExileZone createZone(UUID id, String name, boolean hidden) { private ExileZone createZone(UUID id, String name, boolean hidden) {
if (!exileZones.containsKey(id)) { exileZones.putIfAbsent(id, new ExileZone(id, name, hidden));
ExileZone exile = new ExileZone(id, name, hidden);
exileZones.put(id, exile);
}
return exileZones.get(id); return exileZones.get(id);
} }

View file

@ -1092,9 +1092,7 @@ public class GameState implements Serializable, Copyable<GameState> {
} }
public CardState getCardState(UUID cardId) { public CardState getCardState(UUID cardId) {
if (!cardState.containsKey(cardId)) { cardState.putIfAbsent(cardId, new CardState());
cardState.put(cardId, new CardState());
}
return cardState.get(cardId); return cardState.get(cardId);
} }

View file

@ -68,9 +68,7 @@ public class Revealed extends HashMap<String, Cards> implements Serializable, Co
} }
public Cards createRevealed(String name) { public Cards createRevealed(String name) {
if (!this.containsKey(name)) { putIfAbsent(name, new CardsImpl());
this.put(name, new CardsImpl());
}
return this.get(name); return this.get(name);
} }

View file

@ -28,6 +28,7 @@
package mage.game; package mage.game;
import java.io.Serializable; import java.io.Serializable;
import java.util.Arrays;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;

View file

@ -27,23 +27,18 @@
*/ */
package mage.game.permanent; package mage.game.permanent;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;
import mage.abilities.keyword.PhasingAbility; import mage.abilities.keyword.PhasingAbility;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.RangeOfInfluence; import mage.constants.RangeOfInfluence;
import mage.filter.FilterPermanent; import mage.filter.FilterPermanent;
import mage.game.Game; import mage.game.Game;
import java.io.Serializable;
import java.util.*;
import java.util.Map.Entry;
import java.util.stream.Collectors;
/** /**
*
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
public class Battlefield implements Serializable { public class Battlefield implements Serializable {
@ -76,7 +71,7 @@ public class Battlefield implements Serializable {
/** /**
* Returns a count of all {@link Permanent} that match the filter and are * Returns a count of all {@link Permanent} that match the filter and are
* controlled by controllerId. * controlled by controllerId.
* * <p>
* Some filter predicates do not work here (e.g. AnotherPredicate() because * Some filter predicates do not work here (e.g. AnotherPredicate() because
* filter.match() is called without controllerId. To use this predicates you * filter.match() is called without controllerId. To use this predicates you
* can use count() instead of countAll() * can use count() instead of countAll()
@ -87,13 +82,13 @@ public class Battlefield implements Serializable {
* @return count * @return count
*/ */
public int countAll(FilterPermanent filter, UUID controllerId, Game game) { public int countAll(FilterPermanent filter, UUID controllerId, Game game) {
int count = 0; return (int) field.values()
for (Permanent permanent : field.values()) { .stream()
if (permanent.getControllerId().equals(controllerId) && filter.match(permanent, game) && permanent.isPhasedIn()) { .filter(permanent -> permanent.getControllerId().equals(controllerId)
count++; && filter.match(permanent, game)
} && permanent.isPhasedIn())
} .count();
return count;
} }
/** /**
@ -108,20 +103,20 @@ public class Battlefield implements Serializable {
* @return count * @return count
*/ */
public int count(FilterPermanent filter, UUID sourceId, UUID sourcePlayerId, Game game) { public int count(FilterPermanent filter, UUID sourceId, UUID sourcePlayerId, Game game) {
int count = 0; int count;
if (game.getRangeOfInfluence() == RangeOfInfluence.ALL) { if (game.getRangeOfInfluence() == RangeOfInfluence.ALL) {
for (Permanent permanent : field.values()) { count = (int) field.values()
if (filter.match(permanent, sourceId, sourcePlayerId, game) && permanent.isPhasedIn()) { .stream()
count++; .filter(permanent -> filter.match(permanent, sourceId, sourcePlayerId, game)
} && permanent.isPhasedIn())
} .count();
} else { } else {
Set<UUID> range = game.getPlayer(sourcePlayerId).getInRange(); Set<UUID> range = game.getPlayer(sourcePlayerId).getInRange();
for (Permanent permanent : field.values()) { count = (int) field.values()
if (range.contains(permanent.getControllerId()) && filter.match(permanent, sourceId, sourcePlayerId, game) && permanent.isPhasedIn()) { .stream()
count++; .filter(permanent -> range.contains(permanent.getControllerId())
} && filter.match(permanent, sourceId, sourcePlayerId, game)
} && permanent.isPhasedIn()).count();
} }
return count; return count;
} }
@ -136,16 +131,11 @@ public class Battlefield implements Serializable {
* @return boolean * @return boolean
*/ */
public boolean contains(FilterPermanent filter, int num, Game game) { public boolean contains(FilterPermanent filter, int num, Game game) {
int count = 0; return field.values()
for (Permanent permanent : field.values()) { .stream()
if (filter.match(permanent, game) && permanent.isPhasedIn()) { .filter(permanent -> filter.match(permanent, game)
count++; && permanent.isPhasedIn()).count() == num;
if (num == count) {
return true;
}
}
}
return false;
} }
/** /**
@ -186,14 +176,10 @@ public class Battlefield implements Serializable {
public boolean contains(FilterPermanent filter, UUID sourcePlayerId, Game game, int num) { public boolean contains(FilterPermanent filter, UUID sourcePlayerId, Game game, int num) {
int count = 0; int count = 0;
if (game.getRangeOfInfluence() == RangeOfInfluence.ALL) { if (game.getRangeOfInfluence() == RangeOfInfluence.ALL) {
for (Permanent permanent : field.values()) { return field.values().stream()
if (filter.match(permanent, null, sourcePlayerId, game) && permanent.isPhasedIn()) { .filter(permanent -> filter.match(permanent, null, sourcePlayerId, game)
count++; && permanent.isPhasedIn()).count() == num;
if (num == count) {
return true;
}
}
}
} else { } else {
Set<UUID> range = game.getPlayer(sourcePlayerId).getInRange(); Set<UUID> range = game.getPlayer(sourcePlayerId).getInRange();
for (Permanent permanent : field.values()) { for (Permanent permanent : field.values()) {
@ -245,13 +231,10 @@ public class Battlefield implements Serializable {
} }
public List<Permanent> getAllActivePermanents() { public List<Permanent> getAllActivePermanents() {
List<Permanent> active = new ArrayList<>(); return field.values()
for (Permanent perm : field.values()) { .stream()
if (perm.isPhasedIn()) { .filter(Permanent::isPhasedIn)
active.add(perm); .collect(Collectors.toList());
}
}
return active;
} }
/** /**
@ -263,13 +246,11 @@ public class Battlefield implements Serializable {
* @see Permanent * @see Permanent
*/ */
public List<Permanent> getAllActivePermanents(UUID controllerId) { public List<Permanent> getAllActivePermanents(UUID controllerId) {
List<Permanent> active = new ArrayList<>(); return field.values()
for (Permanent perm : field.values()) { .stream()
if (perm.isPhasedIn() && perm.getControllerId().equals(controllerId)) { .filter(perm -> perm.isPhasedIn()
active.add(perm); && perm.getControllerId().equals(controllerId))
} .collect(Collectors.toList());
}
return active;
} }
/** /**
@ -281,20 +262,13 @@ public class Battlefield implements Serializable {
* @see Permanent * @see Permanent
*/ */
public List<Permanent> getAllActivePermanents(CardType type) { public List<Permanent> getAllActivePermanents(CardType type) {
List<Permanent> active = new ArrayList<>(); return field.values().stream().filter(perm -> perm.isPhasedIn() && perm.getCardType().contains(type)).collect(Collectors.toList());
for (Permanent perm : field.values()) {
if (perm.isPhasedIn() && perm.getCardType().contains(type)) {
active.add(perm);
}
}
return active;
} }
/** /**
* Returns all {@link Permanent} on the battlefield that match the supplied * Returns all {@link Permanent} on the battlefield that match the supplied
* filter. This method ignores the range of influence. * filter. This method ignores the range of influence.
* *
*
* @param filter * @param filter
* @param game * @param game
* @return a list of {@link Permanent} * @return a list of {@link Permanent}
@ -387,14 +361,13 @@ public class Battlefield implements Serializable {
if (game.getRangeOfInfluence() == RangeOfInfluence.ALL) { if (game.getRangeOfInfluence() == RangeOfInfluence.ALL) {
return getAllActivePermanents(); return getAllActivePermanents();
} else { } else {
List<Permanent> active = new ArrayList<>();
Set<UUID> range = game.getPlayer(sourcePlayerId).getInRange(); Set<UUID> range = game.getPlayer(sourcePlayerId).getInRange();
for (Permanent perm : field.values()) { return field.values()
if (perm.isPhasedIn() && range.contains(perm.getControllerId())) { .stream()
active.add(perm); .filter(perm -> perm.isPhasedIn()
} && range.contains(perm.getControllerId()))
} .collect(Collectors.toList());
return active;
} }
} }

View file

@ -206,19 +206,19 @@ public class TournamentPlayer {
} }
public void setStateAtTournamentEnd() { public void setStateAtTournamentEnd() {
if (this.getState().equals(TournamentPlayerState.DRAFTING) if (this.getState() == TournamentPlayerState.DRAFTING
|| this.getState().equals(TournamentPlayerState.CONSTRUCTING) || this.getState() == TournamentPlayerState.CONSTRUCTING
|| this.getState().equals(TournamentPlayerState.DUELING) || this.getState() == TournamentPlayerState.DUELING
|| this.getState().equals(TournamentPlayerState.SIDEBOARDING) || this.getState() == TournamentPlayerState.SIDEBOARDING
|| this.getState().equals(TournamentPlayerState.WAITING)) { || this.getState() == TournamentPlayerState.WAITING) {
this.setState(TournamentPlayerState.FINISHED); this.setState(TournamentPlayerState.FINISHED);
} }
} }
public boolean isInTournament() { public boolean isInTournament() {
return !this.getState().equals(TournamentPlayerState.CANCELED) return !(this.getState() == TournamentPlayerState.CANCELED)
&& !this.getState().equals(TournamentPlayerState.ELIMINATED) && !(this.getState() == TournamentPlayerState.ELIMINATED)
&& !this.getState().equals(TournamentPlayerState.FINISHED); && !(this.getState() == TournamentPlayerState.FINISHED);
} }
public TournamentPlayer getReplacedTournamentPlayer() { public TournamentPlayer getReplacedTournamentPlayer() {

View file

@ -593,7 +593,7 @@ public class CardUtil {
public static Set<Integer> getCMC(MageObject object) { public static Set<Integer> getCMC(MageObject object) {
Set<Integer> cmcObject = new HashSet<>(); Set<Integer> cmcObject = new HashSet<>();
if (object instanceof Spell) { if (object instanceof Spell) {
cmcObject.add(((Spell) object).getConvertedManaCost()); cmcObject.add(object.getConvertedManaCost());
} else if (object instanceof Card) { } else if (object instanceof Card) {
Card card = (Card) object; Card card = (Card) object;
if (card instanceof SplitCard) { if (card instanceof SplitCard) {