mirror of
https://github.com/correl/mage.git
synced 2024-12-25 11:11:16 +00:00
Reworked AsThoughEffect. Added SPEND_ANY_MANA AsThoughType. Added some framework effects.
This commit is contained in:
parent
297ed13d86
commit
7c34668f0d
9 changed files with 328 additions and 90 deletions
|
@ -28,18 +28,17 @@
|
|||
|
||||
package mage.abilities;
|
||||
|
||||
import mage.constants.AbilityType;
|
||||
import mage.constants.AsThoughEffectType;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Zone;
|
||||
import java.util.UUID;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.costs.mana.ManaCost;
|
||||
import mage.abilities.keyword.FlashAbility;
|
||||
import mage.game.Game;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.constants.SpellAbilityType;
|
||||
import mage.cards.SplitCard;
|
||||
import mage.constants.AbilityType;
|
||||
import mage.constants.AsThoughEffectType;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SpellAbilityType;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -71,24 +70,25 @@ public class SpellAbility extends ActivatedAbilityImpl<SpellAbility> {
|
|||
|
||||
}
|
||||
|
||||
// public SpellAbility(Cost cost, String cardName, Effect effect, Zone zone) {
|
||||
// super(zone, effect, cost);
|
||||
// this.spellAbilityType = SpellAbilityType.BASE;
|
||||
// this.name = "Cast " + cardName;
|
||||
// }
|
||||
|
||||
public SpellAbility(SpellAbility ability) {
|
||||
super(ability);
|
||||
this.spellAbilityType = ability.spellAbilityType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canActivate(UUID playerId, Game game) {
|
||||
public boolean spellCanBeActivatedRegularlyNow(UUID playerId, Game game) {
|
||||
MageObject object = game.getObject(sourceId);
|
||||
if ((object.getCardType().contains(CardType.INSTANT) ||
|
||||
object.getAbilities().containsKey(FlashAbility.getInstance().getId()) ||
|
||||
game.getContinuousEffects().asThough(sourceId, AsThoughEffectType.CAST, game) ||
|
||||
game.canPlaySorcery(playerId))) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canActivate(UUID playerId, Game game) {
|
||||
if (this.spellCanBeActivatedRegularlyNow(playerId, game) ||
|
||||
game.getContinuousEffects().asThough(sourceId, AsThoughEffectType.CAST, game)) {
|
||||
if (spellAbilityType.equals(SpellAbilityType.SPLIT)) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -92,6 +92,17 @@ public abstract class ManaCostImpl<T extends ManaCostImpl<T>> extends CostImpl<T
|
|||
return this.sourceFilter;
|
||||
}
|
||||
|
||||
/*
|
||||
* Restrict the allowed mana sources to pay the cost
|
||||
*
|
||||
* e.g. Spend only mana produced by basic lands to cast Imperiosaur.
|
||||
* uses:
|
||||
* private static final FilterLandPermanent filter = new FilterLandPermanent();
|
||||
* static { filter.add(new SupertypePredicate("Basic")); }
|
||||
*
|
||||
* It will be cecked in ManaPool.pay method
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public void setSourceFilter(Filter filter) {
|
||||
this.sourceFilter = filter;
|
||||
|
|
|
@ -29,11 +29,18 @@
|
|||
package mage.abilities.effects;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
import mage.constants.AsThoughEffectType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Layer;
|
||||
import mage.constants.SubLayer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.MageSingleton;
|
||||
|
@ -42,8 +49,12 @@ import mage.abilities.StaticAbility;
|
|||
import mage.abilities.keyword.SpliceOntoArcaneAbility;
|
||||
import mage.cards.Cards;
|
||||
import mage.cards.CardsImpl;
|
||||
import mage.constants.AsThoughEffectType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Layer;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SpellAbilityType;
|
||||
import mage.constants.SubLayer;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.predicate.Predicate;
|
||||
import mage.filter.predicate.Predicates;
|
||||
|
@ -69,7 +80,7 @@ public class ContinuousEffects implements Serializable {
|
|||
private ContinuousEffectsList<RequirementEffect> requirementEffects = new ContinuousEffectsList<RequirementEffect>();
|
||||
private ContinuousEffectsList<RestrictionEffect> restrictionEffects = new ContinuousEffectsList<RestrictionEffect>();
|
||||
private ContinuousEffectsList<RestrictionUntapNotMoreThanEffect> restrictionUntapNotMoreThanEffects = new ContinuousEffectsList<RestrictionUntapNotMoreThanEffect>();
|
||||
private ContinuousEffectsList<AsThoughEffect> asThoughEffects = new ContinuousEffectsList<AsThoughEffect>();
|
||||
private Map<AsThoughEffectType, ContinuousEffectsList<AsThoughEffect>> asThoughEffectsMap = new EnumMap<AsThoughEffectType, ContinuousEffectsList<AsThoughEffect>>(AsThoughEffectType.class);
|
||||
private ContinuousEffectsList<CostModificationEffect> costModificationEffects = new ContinuousEffectsList<CostModificationEffect>();
|
||||
private ContinuousEffectsList<SpliceCardEffect> spliceCardEffects = new ContinuousEffectsList<SpliceCardEffect>();
|
||||
|
||||
|
@ -101,7 +112,10 @@ public class ContinuousEffects implements Serializable {
|
|||
requirementEffects = effect.requirementEffects.copy();
|
||||
restrictionEffects = effect.restrictionEffects.copy();
|
||||
restrictionUntapNotMoreThanEffects = effect.restrictionUntapNotMoreThanEffects.copy();
|
||||
asThoughEffects = effect.asThoughEffects.copy();
|
||||
for (Map.Entry<AsThoughEffectType, ContinuousEffectsList<AsThoughEffect>> entry : effect.asThoughEffectsMap.entrySet()) {
|
||||
asThoughEffectsMap.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
|
||||
costModificationEffects = effect.costModificationEffects.copy();
|
||||
spliceCardEffects = effect.spliceCardEffects.copy();
|
||||
for (Map.Entry<UUID, UUID> entry : effect.sources.entrySet()) {
|
||||
|
@ -118,7 +132,9 @@ public class ContinuousEffects implements Serializable {
|
|||
allEffectsLists.add(requirementEffects);
|
||||
allEffectsLists.add(restrictionEffects);
|
||||
allEffectsLists.add(restrictionUntapNotMoreThanEffects);
|
||||
allEffectsLists.add(asThoughEffects);
|
||||
for(ContinuousEffectsList asThoughtlist :asThoughEffectsMap.values()) {
|
||||
allEffectsLists.add(asThoughtlist);
|
||||
}
|
||||
allEffectsLists.add(costModificationEffects);
|
||||
allEffectsLists.add(spliceCardEffects);
|
||||
}
|
||||
|
@ -141,7 +157,9 @@ public class ContinuousEffects implements Serializable {
|
|||
preventionEffects.removeEndOfCombatEffects();
|
||||
requirementEffects.removeEndOfCombatEffects();
|
||||
restrictionEffects.removeEndOfCombatEffects();
|
||||
asThoughEffects.removeEndOfCombatEffects();
|
||||
for(ContinuousEffectsList asThoughtlist :asThoughEffectsMap.values()) {
|
||||
asThoughtlist.removeEndOfCombatEffects();
|
||||
}
|
||||
costModificationEffects.removeEndOfCombatEffects();
|
||||
spliceCardEffects.removeEndOfCombatEffects();
|
||||
}
|
||||
|
@ -152,7 +170,9 @@ public class ContinuousEffects implements Serializable {
|
|||
preventionEffects.removeEndOfTurnEffects();
|
||||
requirementEffects.removeEndOfTurnEffects();
|
||||
restrictionEffects.removeEndOfTurnEffects();
|
||||
asThoughEffects.removeEndOfTurnEffects();
|
||||
for(ContinuousEffectsList asThoughtlist :asThoughEffectsMap.values()) {
|
||||
asThoughtlist.removeEndOfTurnEffects();
|
||||
}
|
||||
costModificationEffects.removeEndOfTurnEffects();
|
||||
spliceCardEffects.removeEndOfTurnEffects();
|
||||
}
|
||||
|
@ -164,7 +184,9 @@ public class ContinuousEffects implements Serializable {
|
|||
requirementEffects.removeInactiveEffects(game);
|
||||
restrictionEffects.removeInactiveEffects(game);
|
||||
restrictionUntapNotMoreThanEffects.removeInactiveEffects(game);
|
||||
asThoughEffects.removeInactiveEffects(game);
|
||||
for(ContinuousEffectsList asThoughtlist :asThoughEffectsMap.values()) {
|
||||
asThoughtlist.removeInactiveEffects(game);
|
||||
}
|
||||
costModificationEffects.removeInactiveEffects(game);
|
||||
spliceCardEffects.removeInactiveEffects(game);
|
||||
}
|
||||
|
@ -394,15 +416,12 @@ public class ContinuousEffects implements Serializable {
|
|||
}
|
||||
|
||||
public boolean asThough(UUID objectId, AsThoughEffectType type, Game game) {
|
||||
List<AsThoughEffect> asThoughEffectsList = getApplicableAsThoughEffects(game);
|
||||
|
||||
List<AsThoughEffect> asThoughEffectsList = getApplicableAsThoughEffects(type, game);
|
||||
for (AsThoughEffect effect: asThoughEffectsList) {
|
||||
if (effect.getAsThoughEffectType() == type) {
|
||||
HashSet<Ability> abilities = asThoughEffects.getAbility(effect.getId());
|
||||
for (Ability ability : abilities) {
|
||||
if (effect.applies(objectId, ability, game)) {
|
||||
return true;
|
||||
}
|
||||
HashSet<Ability> abilities = asThoughEffectsMap.get(type).getAbility(effect.getId());
|
||||
for (Ability ability : abilities) {
|
||||
if (effect.applies(objectId, ability, game)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -412,24 +431,25 @@ public class ContinuousEffects implements Serializable {
|
|||
/**
|
||||
* Filters out asThough effects that are not active.
|
||||
*
|
||||
* @param AsThoughEffectType type
|
||||
* @param game
|
||||
* @return
|
||||
*/
|
||||
private List<AsThoughEffect> getApplicableAsThoughEffects(Game game) {
|
||||
private List<AsThoughEffect> getApplicableAsThoughEffects(AsThoughEffectType type, Game game) {
|
||||
List<AsThoughEffect> asThoughEffectsList = new ArrayList<AsThoughEffect>();
|
||||
|
||||
for (AsThoughEffect effect: asThoughEffects) {
|
||||
HashSet<Ability> abilities = asThoughEffects.getAbility(effect.getId());
|
||||
for (Ability ability : abilities) {
|
||||
if (!(ability instanceof StaticAbility) || ability.isInUseableZone(game, null, false)) {
|
||||
if (effect.getDuration() != Duration.OneUse || !effect.isUsed()) {
|
||||
asThoughEffectsList.add(effect);
|
||||
break;
|
||||
if (asThoughEffectsMap.containsKey(type)) {
|
||||
for (AsThoughEffect effect: asThoughEffectsMap.get(type)) {
|
||||
HashSet<Ability> abilities = asThoughEffectsMap.get(type).getAbility(effect.getId());
|
||||
for (Ability ability : abilities) {
|
||||
if (!(ability instanceof StaticAbility) || ability.isInUseableZone(game, null, false)) {
|
||||
if (effect.getDuration() != Duration.OneUse || !effect.isUsed()) {
|
||||
asThoughEffectsList.add(effect);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return asThoughEffectsList;
|
||||
}
|
||||
|
||||
|
@ -743,7 +763,11 @@ public class ContinuousEffects implements Serializable {
|
|||
break;
|
||||
case ASTHOUGH:
|
||||
AsThoughEffect newAsThoughEffect = (AsThoughEffect)effect;
|
||||
asThoughEffects.addEffect(newAsThoughEffect, source);
|
||||
if (!asThoughEffectsMap.containsKey(newAsThoughEffect.getAsThoughEffectType())) {
|
||||
ContinuousEffectsList list = new ContinuousEffectsList();
|
||||
asThoughEffectsMap.put(newAsThoughEffect.getAsThoughEffectType(), list);
|
||||
}
|
||||
asThoughEffectsMap.get(newAsThoughEffect.getAsThoughEffectType()).addEffect(newAsThoughEffect, source);
|
||||
break;
|
||||
case COSTMODIFICATION:
|
||||
CostModificationEffect newCostModificationEffect = (CostModificationEffect)effect;
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.cards.Card;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public class ReturnToBattlefieldUnderOwnerControlTargetEffect extends OneShotEffect<ReturnToBattlefieldUnderOwnerControlTargetEffect> {
|
||||
|
||||
public ReturnToBattlefieldUnderOwnerControlTargetEffect() {
|
||||
super(Outcome.Benefit);
|
||||
staticText = "return that card to the battlefield under its owner's control";
|
||||
}
|
||||
|
||||
public ReturnToBattlefieldUnderOwnerControlTargetEffect(final ReturnToBattlefieldUnderOwnerControlTargetEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReturnToBattlefieldUnderOwnerControlTargetEffect copy() {
|
||||
return new ReturnToBattlefieldUnderOwnerControlTargetEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Card card = game.getCard(targetPointer.getFirst(game, source));
|
||||
if (card != null) {
|
||||
Zone currentZone = game.getState().getZone(card.getId());
|
||||
if (card.putOntoBattlefield(game, currentZone, source.getId(), card.getOwnerId())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* 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.continious;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.RestrictionEffect;
|
||||
import mage.constants.Duration;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
|
||||
public class CantBeBlockedByCreaturesSourceEffect extends RestrictionEffect<CantBeBlockedByCreaturesSourceEffect> {
|
||||
|
||||
private FilterCreaturePermanent filter;
|
||||
|
||||
public CantBeBlockedByCreaturesSourceEffect(FilterCreaturePermanent filter, Duration duration) {
|
||||
super(Duration.WhileOnBattlefield);
|
||||
this.filter = filter;
|
||||
staticText = new StringBuilder("{this} can't be blocked by ").append(filter.getMessage()).toString();
|
||||
}
|
||||
|
||||
public CantBeBlockedByCreaturesSourceEffect(final CantBeBlockedByCreaturesSourceEffect effect) {
|
||||
super(effect);
|
||||
this.filter = effect.filter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applies(Permanent permanent, Ability source, Game game) {
|
||||
if (permanent.getId().equals(source.getSourceId())) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBeBlocked(Permanent attacker, Permanent blocker, Ability source, Game game) {
|
||||
if (filter.match(blocker, source.getSourceId(), source.getControllerId(), game)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CantBeBlockedByCreaturesSourceEffect copy() {
|
||||
return new CantBeBlockedByCreaturesSourceEffect(this);
|
||||
}
|
||||
}
|
|
@ -5,13 +5,14 @@ package mage.constants;
|
|||
* @author North
|
||||
*/
|
||||
public enum AsThoughEffectType {
|
||||
BLOCK_TAPPED,
|
||||
BE_BLOCKED,
|
||||
ATTACK,
|
||||
BLOCK_TAPPED,
|
||||
BE_BLOCKED,
|
||||
CAST,
|
||||
TARGET,
|
||||
PAY,
|
||||
DAMAGE,
|
||||
HEXPROOF,
|
||||
REVEAL_FACE_DOWN
|
||||
SPEND_ANY_MANA,
|
||||
PAY,
|
||||
REVEAL_FACE_DOWN,
|
||||
TARGET
|
||||
}
|
||||
|
|
|
@ -28,19 +28,19 @@
|
|||
|
||||
package mage.players;
|
||||
|
||||
import mage.ConditionalMana;
|
||||
import mage.constants.ManaType;
|
||||
import mage.Mana;
|
||||
import mage.abilities.Ability;
|
||||
import mage.filter.Filter;
|
||||
import mage.filter.FilterMana;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import mage.ConditionalMana;
|
||||
import mage.Mana;
|
||||
import mage.abilities.Ability;
|
||||
import mage.constants.AsThoughEffectType;
|
||||
import mage.constants.ManaType;
|
||||
import mage.filter.Filter;
|
||||
import mage.filter.FilterMana;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -85,9 +85,14 @@ public class ManaPool implements Serializable {
|
|||
}
|
||||
for (ManaPoolItem mana : manaItems) {
|
||||
if (filter == null || filter.match(game.getObject(mana.getSourceId()), game)) {
|
||||
if (mana.get(manaType) > 0) {
|
||||
boolean spendAnyMana = spendAnyMana(ability, game);
|
||||
if (mana.get(manaType) > 0 || (spendAnyMana && mana.count() > 0)) {
|
||||
game.fireEvent(new GameEvent(GameEvent.EventType.MANA_PAYED, ability.getId(), mana.getSourceId(), ability.getControllerId()));
|
||||
mana.remove(manaType);
|
||||
if (spendAnyMana) {
|
||||
mana.removeAny();
|
||||
} else {
|
||||
mana.remove(manaType);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -95,6 +100,11 @@ public class ManaPool implements Serializable {
|
|||
return false;
|
||||
}
|
||||
|
||||
// check if any mana can be spend to cast the mana cost of an ability
|
||||
private boolean spendAnyMana(Ability ability, Game game) {
|
||||
return game.getContinuousEffects().asThough(ability.getSourceId(), AsThoughEffectType.SPEND_ANY_MANA, game);
|
||||
}
|
||||
|
||||
public int get(ManaType manaType) {
|
||||
return getMana().get(manaType);
|
||||
}
|
||||
|
@ -105,8 +115,9 @@ public class ManaPool implements Serializable {
|
|||
}
|
||||
for (ManaPoolItem mana : manaItems) {
|
||||
if (mana.isConditional() && mana.getConditionalMana().get(manaType) > 0 && mana.getConditionalMana().apply(ability, game, mana.getSourceId())) {
|
||||
if (filter == null || filter.match(game.getObject(mana.getSourceId()), game))
|
||||
if (filter == null || filter.match(game.getObject(mana.getSourceId()), game)) {
|
||||
return mana.getConditionalMana().get(manaType);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
@ -195,8 +206,9 @@ public class ManaPool implements Serializable {
|
|||
if (count > 0) {
|
||||
total += count;
|
||||
c.removeAll(filter);
|
||||
if (c.count() == 0)
|
||||
if (c.count() == 0) {
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -225,8 +237,9 @@ public class ManaPool implements Serializable {
|
|||
total += item.getColorless();
|
||||
item.removeColorless();
|
||||
}
|
||||
if (item.count() == 0)
|
||||
if (item.count() == 0) {
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
return total;
|
||||
|
@ -246,12 +259,24 @@ public class ManaPool implements Serializable {
|
|||
}
|
||||
Mana test = getMana();
|
||||
Mana m = new Mana();
|
||||
if (filter.isBlack()) m.setBlack(test.getBlack());
|
||||
if (filter.isBlue()) m.setBlue(test.getBlue());
|
||||
if (filter.isColorless()) m.setColorless(test.getColorless());
|
||||
if (filter.isGreen()) m.setGreen(test.getGreen());
|
||||
if (filter.isRed()) m.setRed(test.getRed());
|
||||
if (filter.isWhite()) m.setWhite(test.getWhite());
|
||||
if (filter.isBlack()) {
|
||||
m.setBlack(test.getBlack());
|
||||
}
|
||||
if (filter.isBlue()) {
|
||||
m.setBlue(test.getBlue());
|
||||
}
|
||||
if (filter.isColorless()) {
|
||||
m.setColorless(test.getColorless());
|
||||
}
|
||||
if (filter.isGreen()) {
|
||||
m.setGreen(test.getGreen());
|
||||
}
|
||||
if (filter.isRed()) {
|
||||
m.setRed(test.getRed());
|
||||
}
|
||||
if (filter.isWhite()) {
|
||||
m.setWhite(test.getWhite());
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,12 +27,11 @@
|
|||
*/
|
||||
package mage.players;
|
||||
|
||||
import mage.ConditionalMana;
|
||||
import mage.constants.ManaType;
|
||||
import mage.Mana;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.UUID;
|
||||
import mage.ConditionalMana;
|
||||
import mage.Mana;
|
||||
import mage.constants.ManaType;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -74,8 +73,9 @@ public class ManaPoolItem implements Serializable {
|
|||
this.white = item.white;
|
||||
this.black = item.black;
|
||||
this.colorless = item.colorless;
|
||||
if (item.conditionalMana != null)
|
||||
if (item.conditionalMana != null) {
|
||||
this.conditionalMana = item.conditionalMana.copy();
|
||||
}
|
||||
this.sourceId = item.sourceId;
|
||||
}
|
||||
|
||||
|
@ -92,8 +92,9 @@ public class ManaPoolItem implements Serializable {
|
|||
}
|
||||
|
||||
public void removeRed() {
|
||||
if (red > 0)
|
||||
if (red > 0) {
|
||||
red--;
|
||||
}
|
||||
}
|
||||
|
||||
public int getGreen() {
|
||||
|
@ -101,8 +102,9 @@ public class ManaPoolItem implements Serializable {
|
|||
}
|
||||
|
||||
public void removeGreen() {
|
||||
if (green > 0)
|
||||
if (green > 0) {
|
||||
green--;
|
||||
}
|
||||
}
|
||||
|
||||
public int getBlue() {
|
||||
|
@ -110,8 +112,9 @@ public class ManaPoolItem implements Serializable {
|
|||
}
|
||||
|
||||
public void removeBlue() {
|
||||
if (blue > 0)
|
||||
if (blue > 0) {
|
||||
blue--;
|
||||
}
|
||||
}
|
||||
|
||||
public int getBlack() {
|
||||
|
@ -119,8 +122,9 @@ public class ManaPoolItem implements Serializable {
|
|||
}
|
||||
|
||||
public void removeBlack() {
|
||||
if (black > 0)
|
||||
if (black > 0) {
|
||||
black--;
|
||||
}
|
||||
}
|
||||
|
||||
public int getWhite() {
|
||||
|
@ -128,8 +132,9 @@ public class ManaPoolItem implements Serializable {
|
|||
}
|
||||
|
||||
public void removeWhite() {
|
||||
if (white > 0)
|
||||
if (white > 0) {
|
||||
white--;
|
||||
}
|
||||
}
|
||||
|
||||
public int getColorless() {
|
||||
|
@ -137,8 +142,9 @@ public class ManaPoolItem implements Serializable {
|
|||
}
|
||||
|
||||
public void removeColorless() {
|
||||
if (colorless > 0)
|
||||
if (colorless > 0) {
|
||||
colorless--;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isConditional() {
|
||||
|
@ -154,8 +160,9 @@ public class ManaPoolItem implements Serializable {
|
|||
}
|
||||
|
||||
public int count() {
|
||||
if (conditionalMana == null)
|
||||
if (conditionalMana == null) {
|
||||
return red + green + blue + white + black + colorless;
|
||||
}
|
||||
return conditionalMana.count();
|
||||
}
|
||||
|
||||
|
@ -177,31 +184,53 @@ public class ManaPoolItem implements Serializable {
|
|||
return 0;
|
||||
}
|
||||
|
||||
public void removeAny() {
|
||||
if (black > 0) {
|
||||
black--;
|
||||
} else if (blue > 0) {
|
||||
blue--;
|
||||
} else if (green > 0) {
|
||||
green--;
|
||||
} else if (red > 0) {
|
||||
red--;
|
||||
} else if (white > 0) {
|
||||
white--;
|
||||
} else if (colorless > 0) {
|
||||
colorless--;
|
||||
}
|
||||
}
|
||||
|
||||
public void remove(ManaType manaType) {
|
||||
switch(manaType) {
|
||||
case BLACK:
|
||||
if (black > 0)
|
||||
if (black > 0) {
|
||||
black--;
|
||||
}
|
||||
break;
|
||||
case BLUE:
|
||||
if (blue > 0)
|
||||
if (blue > 0) {
|
||||
blue--;
|
||||
}
|
||||
break;
|
||||
case GREEN:
|
||||
if (green > 0)
|
||||
if (green > 0) {
|
||||
green--;
|
||||
}
|
||||
break;
|
||||
case RED:
|
||||
if (red > 0)
|
||||
if (red > 0) {
|
||||
red--;
|
||||
}
|
||||
break;
|
||||
case WHITE:
|
||||
if (white > 0)
|
||||
if (white > 0) {
|
||||
white--;
|
||||
}
|
||||
break;
|
||||
case COLORLESS:
|
||||
if (colorless > 0)
|
||||
if (colorless > 0) {
|
||||
colorless--;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -914,6 +914,7 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
|
|||
if (zone != Zone.HAND) {
|
||||
if (zone != Zone.BATTLEFIELD && game.getContinuousEffects().asThough(object.getId(), AsThoughEffectType.CAST, game)) {
|
||||
for (ActivatedAbility ability: object.getAbilities().getActivatedAbilities(Zone.HAND)) {
|
||||
ability.setControllerId(this.getId());
|
||||
useable.put(ability.getId(), ability);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue