mirror of
https://github.com/magefree/mage.git
synced 2025-12-28 14:32:06 -08:00
* Reworked non mana costs with variable amount. The values have now to be announced before targeting. Fixed some wrong implementations (Firestorm, Myr Battlesphere, Skeletal Scrying).
This commit is contained in:
parent
2d9f260b1e
commit
7ebb8a9cbe
46 changed files with 1176 additions and 1187 deletions
|
|
@ -28,33 +28,43 @@
|
|||
|
||||
package mage.abilities;
|
||||
|
||||
import mage.constants.AbilityType;
|
||||
import mage.constants.EffectType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.costs.*;
|
||||
import mage.abilities.costs.AdjustingSourceCosts;
|
||||
import mage.abilities.costs.AlternativeCost;
|
||||
import mage.abilities.costs.AlternativeSourceCosts;
|
||||
import mage.abilities.costs.Cost;
|
||||
import mage.abilities.costs.Costs;
|
||||
import mage.abilities.costs.CostsImpl;
|
||||
import mage.abilities.costs.OptionalAdditionalSourceCosts;
|
||||
import mage.abilities.costs.VariableCost;
|
||||
import mage.abilities.costs.mana.ManaCost;
|
||||
import mage.abilities.costs.mana.ManaCosts;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.costs.mana.VariableManaCost;
|
||||
import mage.abilities.effects.*;
|
||||
import mage.abilities.effects.ContinuousEffect;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.Effects;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.PostResolveEffect;
|
||||
import mage.abilities.mana.ManaAbility;
|
||||
import mage.cards.Card;
|
||||
import mage.choices.Choice;
|
||||
import mage.choices.Choices;
|
||||
import mage.constants.AbilityType;
|
||||
import mage.constants.EffectType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
import mage.game.command.Emblem;
|
||||
import mage.game.permanent.PermanentCard;
|
||||
import mage.players.Player;
|
||||
import mage.target.Target;
|
||||
import mage.target.Targets;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import mage.game.command.Emblem;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
|
|
@ -72,7 +82,7 @@ public abstract class AbilityImpl<T extends AbilityImpl<T>> implements Ability {
|
|||
protected ManaCosts<ManaCost> manaCosts;
|
||||
protected ManaCosts<ManaCost> manaCostsToPay;
|
||||
protected Costs<Cost> costs;
|
||||
protected ArrayList<AlternativeCost> alternativeCosts = new ArrayList<AlternativeCost>();
|
||||
protected ArrayList<AlternativeCost> alternativeCosts = new ArrayList<>();
|
||||
protected Costs<Cost> optionalCosts;
|
||||
protected Modes modes;
|
||||
protected Zone zone;
|
||||
|
|
@ -89,10 +99,10 @@ public abstract class AbilityImpl<T extends AbilityImpl<T>> implements Ability {
|
|||
this.originalId = id;
|
||||
this.abilityType = abilityType;
|
||||
this.zone = zone;
|
||||
this.manaCosts = new ManaCostsImpl<ManaCost>();
|
||||
this.manaCostsToPay = new ManaCostsImpl<ManaCost>();
|
||||
this.costs = new CostsImpl<Cost>();
|
||||
this.optionalCosts = new CostsImpl<Cost>();
|
||||
this.manaCosts = new ManaCostsImpl<>();
|
||||
this.manaCostsToPay = new ManaCostsImpl<>();
|
||||
this.costs = new CostsImpl<>();
|
||||
this.optionalCosts = new CostsImpl<>();
|
||||
this.modes = new Modes();
|
||||
}
|
||||
|
||||
|
|
@ -222,7 +232,8 @@ public abstract class AbilityImpl<T extends AbilityImpl<T>> implements Ability {
|
|||
// 20121001 - 601.2b
|
||||
// If the spell has a variable cost that will be paid as it's being cast (such as an {X} in
|
||||
// its mana cost; see rule 107.3), the player announces the value of that variable.
|
||||
VariableManaCost variableManaCost = handleXCosts(game, noMana);
|
||||
VariableManaCost variableManaCost = handleManaXCosts(game, noMana);
|
||||
String announceString = handleOtherXCosts(game);
|
||||
|
||||
for (UUID modeId :this.getModes().getSelectedModes()) {
|
||||
this.getModes().setMode(this.getModes().get(modeId));
|
||||
|
|
@ -247,8 +258,11 @@ public abstract class AbilityImpl<T extends AbilityImpl<T>> implements Ability {
|
|||
card.adjustTargets(this, game);
|
||||
}
|
||||
if (getTargets().size() > 0 && getTargets().chooseTargets(getEffects().get(0).getOutcome(), this.controllerId, this, game) == false) {
|
||||
if (variableManaCost != null) {
|
||||
game.informPlayers(new StringBuilder(card != null ? card.getName(): "").append(": no valid targets with this value of X").toString());
|
||||
if (variableManaCost != null || announceString != null) {
|
||||
Player controller = game.getPlayer(this.getControllerId());
|
||||
if (controller != null) {
|
||||
game.informPlayer(controller, new StringBuilder(card != null ? card.getName(): "").append(": no valid targets with this value of X").toString());
|
||||
}
|
||||
} else {
|
||||
logger.debug("activate failed - target");
|
||||
}
|
||||
|
|
@ -305,21 +319,52 @@ public abstract class AbilityImpl<T extends AbilityImpl<T>> implements Ability {
|
|||
return false;
|
||||
}
|
||||
// inform about x costs now, so canceled announcements are not shown in the log
|
||||
if (announceString != null) {
|
||||
game.informPlayers(announceString);
|
||||
}
|
||||
if (variableManaCost != null) {
|
||||
int xValue = getManaCostsToPay().getX();
|
||||
game.informPlayers(new StringBuilder(game.getPlayer(this.controllerId).getName()).append(" announced a value of ").append(xValue).append(" for ").append(variableManaCost.getText()).toString());
|
||||
game.informPlayers(new StringBuilder(game.getPlayer(this.controllerId).getName()).append(" announces a value of ").append(xValue).append(" for ").append(variableManaCost.getText()).toString());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the announcement of X mana costs and sets manaCostsToPay.
|
||||
* Handles the setting of non mana X costs
|
||||
*
|
||||
* @param game
|
||||
* @return announce message
|
||||
*
|
||||
*/
|
||||
protected String handleOtherXCosts(Game game) {
|
||||
String announceString = null;
|
||||
for (VariableCost variableCost : this.costs.getVariableCosts()) {
|
||||
if (!(variableCost instanceof VariableManaCost)) {
|
||||
int xValue = variableCost.announceXValue(this, game);
|
||||
costs.add(variableCost.getFixedCostsFromAnnouncedValue(xValue));
|
||||
// set the xcosts to paid
|
||||
variableCost.setAmount(xValue);
|
||||
((Cost) variableCost).setPaid();
|
||||
String message = new StringBuilder(game.getPlayer(this.controllerId).getName())
|
||||
.append(" announces a value of ").append(xValue).append(" (").append(variableCost.getActionText()).append(")").toString();
|
||||
if (announceString == null) {
|
||||
announceString = message;
|
||||
} else {
|
||||
announceString = new StringBuilder(announceString).append(" ").append(message).toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
return announceString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles X mana costs and sets manaCostsToPay.
|
||||
*
|
||||
* @param game
|
||||
* @param noMana
|
||||
* @return variableManaCost for late check
|
||||
* @return variableManaCost for posting to log later
|
||||
*/
|
||||
protected VariableManaCost handleXCosts(Game game, boolean noMana) {
|
||||
protected VariableManaCost handleManaXCosts(Game game, boolean noMana) {
|
||||
// 20121001 - 601.2b
|
||||
// If the spell has a variable cost that will be paid as it's being cast (such as an {X} in
|
||||
// its mana cost; see rule 107.3), the player announces the value of that variable.
|
||||
|
|
|
|||
|
|
@ -213,8 +213,8 @@ public abstract class ActivatedAbilityImpl<T extends ActivatedAbilityImpl<T>> ex
|
|||
return "";
|
||||
}
|
||||
MageObject object = game.getObject(this.sourceId);
|
||||
return new StringBuilder(" activates ")
|
||||
.append(object != null ? this.getRule(object.getName()) :this.getRule())
|
||||
return new StringBuilder(" activates: ")
|
||||
.append(object != null ? this.formatRule(modes.getText(), object.getName()) :modes.getText())
|
||||
.append(" from ")
|
||||
.append(getMessageText(game)).toString();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,16 +28,61 @@
|
|||
|
||||
package mage.abilities.costs;
|
||||
|
||||
import mage.filter.FilterMana;
|
||||
import mage.abilities.Ability;
|
||||
import mage.game.Game;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public interface VariableCost {
|
||||
|
||||
/**
|
||||
* Returns the variable amount if alreaady set
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
int getAmount();
|
||||
/**
|
||||
* Sets the variable amount
|
||||
*
|
||||
* @param amount
|
||||
*/
|
||||
void setAmount(int amount);
|
||||
void setFilter(FilterMana filter);
|
||||
FilterMana getFilter();
|
||||
|
||||
/**
|
||||
* returns the action text (e.g. "creature cards to exile from your hand", "life to pay")
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getActionText();
|
||||
/**
|
||||
* Return a min value to announce
|
||||
*
|
||||
* @param source
|
||||
* @param game
|
||||
* @return
|
||||
*/
|
||||
int getMinValue(Ability source, Game game);
|
||||
/**
|
||||
* Returns a max value to announce
|
||||
*
|
||||
* @param source
|
||||
* @param game
|
||||
* @return
|
||||
*/
|
||||
int getMaxValue(Ability source, Game game);
|
||||
/**
|
||||
* Asks the controller to announce the variable value
|
||||
* @param source
|
||||
* @param game
|
||||
* @return
|
||||
*/
|
||||
int announceXValue(Ability source, Game game);
|
||||
/**
|
||||
* Returns a fixed cost with the announced variabke value
|
||||
*
|
||||
* @param xValue
|
||||
* @return
|
||||
*/
|
||||
Cost getFixedCostsFromAnnouncedValue(int xValue);
|
||||
}
|
||||
|
|
|
|||
166
Mage/src/mage/abilities/costs/VariableCostImpl.java
Normal file
166
Mage/src/mage/abilities/costs/VariableCostImpl.java
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
/*
|
||||
* 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.costs;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
import mage.target.Target;
|
||||
import mage.target.Targets;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
* @param <T> variable cost type
|
||||
*/
|
||||
|
||||
public abstract class VariableCostImpl<T extends VariableCostImpl<T>> implements Cost, VariableCost {
|
||||
|
||||
protected UUID id;
|
||||
protected String text;
|
||||
protected boolean paid;
|
||||
protected Targets targets;
|
||||
protected int amountPaid;
|
||||
protected String xText;
|
||||
protected String actionText;
|
||||
|
||||
@Override
|
||||
public abstract T copy();
|
||||
|
||||
public VariableCostImpl(String actionText) {
|
||||
this("X", actionText);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param xText string for the defined value
|
||||
* @param actionText what happens with the value (e.g. "to tap", "to exile from your graveyard")
|
||||
*/
|
||||
public VariableCostImpl(String xText, String actionText) {
|
||||
id = UUID.randomUUID();
|
||||
paid = false;
|
||||
targets = new Targets();
|
||||
amountPaid = 0;
|
||||
this.xText = xText;
|
||||
this.actionText = actionText;
|
||||
}
|
||||
|
||||
public VariableCostImpl(final VariableCostImpl cost) {
|
||||
this.id = cost.id;
|
||||
this.text = cost.text;
|
||||
this.paid = cost.paid;
|
||||
this.targets = cost.targets.copy();
|
||||
this.xText = cost.xText;
|
||||
this.actionText = cost.actionText;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getActionText() {
|
||||
return actionText;
|
||||
}
|
||||
|
||||
public void addTarget(Target target) {
|
||||
if (target != null) {
|
||||
this.targets.add(target);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Targets getTargets() {
|
||||
return this.targets;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPaid() {
|
||||
return paid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearPaid() {
|
||||
paid = false;
|
||||
amountPaid = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPaid() {
|
||||
paid = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPay(UUID sourceId, UUID controllerId, Game game) {
|
||||
return true; /* not used */
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana) {
|
||||
return true; /* not used */
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAmount() {
|
||||
return amountPaid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAmount(int amount) {
|
||||
amountPaid = amount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMinValue(Ability source, Game game) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxValue(Ability source, Game game) {
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int announceXValue(Ability source, Game game) {
|
||||
int xValue = 0;
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
xValue = controller.announceXCost(0, getMaxValue(source, game),
|
||||
new StringBuilder("Announce the number of ").append(actionText).toString(),
|
||||
game, source, this);
|
||||
}
|
||||
return xValue;
|
||||
}
|
||||
}
|
||||
84
Mage/src/mage/abilities/costs/common/DiscardXTargetCost.java
Normal file
84
Mage/src/mage/abilities/costs/common/DiscardXTargetCost.java
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* 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.costs.common;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.costs.Cost;
|
||||
import mage.abilities.costs.VariableCostImpl;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
import mage.target.common.TargetCardInHand;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
|
||||
public class DiscardXTargetCost extends VariableCostImpl<DiscardXTargetCost> {
|
||||
|
||||
protected FilterCard filter;
|
||||
|
||||
public DiscardXTargetCost(FilterCard filter) {
|
||||
this(filter, false);
|
||||
}
|
||||
|
||||
public DiscardXTargetCost(FilterCard filter, boolean additionalCostText) {
|
||||
super(new StringBuilder(filter.getMessage()).append(" to discard").toString());
|
||||
this.text = new StringBuilder(additionalCostText ? "As an additional cost to cast {source}, discard ":"Discard ")
|
||||
.append(xText).append(" ").append(filter.getMessage()).toString();
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
public DiscardXTargetCost(final DiscardXTargetCost cost) {
|
||||
super(cost);
|
||||
this.filter = cost.filter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DiscardXTargetCost copy() {
|
||||
return new DiscardXTargetCost(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxValue(Ability source, Game game) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
return controller.getHand().count(filter, game);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cost getFixedCostsFromAnnouncedValue(int xValue) {
|
||||
TargetCardInHand target = new TargetCardInHand(xValue, filter);
|
||||
target.setRequired(true);
|
||||
return new DiscardTargetCost(target);
|
||||
}
|
||||
}
|
||||
|
|
@ -76,14 +76,18 @@ public class ExileFromGraveCost extends CostImpl<ExileFromGraveCost> {
|
|||
|
||||
@Override
|
||||
public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana) {
|
||||
if (targets.choose(Outcome.Exile, controllerId, sourceId, game)) {
|
||||
for (UUID targetId: targets.get(0).getTargets()) {
|
||||
Card card = game.getCard(targetId);
|
||||
if (card == null || !game.getState().getZone(targetId).equals(Zone.GRAVEYARD)) {
|
||||
return false;
|
||||
Player controller = game.getPlayer(controllerId);
|
||||
if (controller != null) {
|
||||
if (targets.choose(Outcome.Exile, controllerId, sourceId, game)) {
|
||||
for (UUID targetId: targets.get(0).getTargets()) {
|
||||
Card card = game.getCard(targetId);
|
||||
if (card == null || !game.getState().getZone(targetId).equals(Zone.GRAVEYARD)) {
|
||||
return false;
|
||||
}
|
||||
paid |= controller.moveCardToExileWithInfo(card, null, null, sourceId, game, Zone.GRAVEYARD);
|
||||
}
|
||||
paid |= card.moveToZone(Zone.EXILED, sourceId, game, false);
|
||||
}
|
||||
|
||||
}
|
||||
return paid;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* 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.costs.common;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.costs.Cost;
|
||||
import mage.abilities.costs.VariableCostImpl;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
import mage.target.common.TargetCardInYourGraveyard;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
|
||||
public class ExileXFromYourGraveCost extends VariableCostImpl<ExileXFromYourGraveCost> {
|
||||
|
||||
protected FilterCard filter;
|
||||
|
||||
public ExileXFromYourGraveCost(FilterCard filter) {
|
||||
this(filter, false);
|
||||
}
|
||||
|
||||
public ExileXFromYourGraveCost(FilterCard filter, boolean additionalCostText) {
|
||||
super(new StringBuilder(filter.getMessage()).append(" to exile").toString());
|
||||
this.filter = filter;
|
||||
this.text = new StringBuilder(additionalCostText ? "As an additional cost to cast {source}, exile ":"Exile ")
|
||||
.append(xText).append(" ").append(filter.getMessage()).toString();
|
||||
}
|
||||
|
||||
public ExileXFromYourGraveCost(final ExileXFromYourGraveCost cost) {
|
||||
super(cost);
|
||||
this.amountPaid = cost.amountPaid;
|
||||
this.filter = cost.filter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExileXFromYourGraveCost copy() {
|
||||
return new ExileXFromYourGraveCost(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxValue(Ability source, Game game) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
return controller.getGraveyard().count(filter, game);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cost getFixedCostsFromAnnouncedValue(int xValue) {
|
||||
TargetCardInYourGraveyard target = new TargetCardInYourGraveyard(xValue, filter);
|
||||
target.setRequired(true);
|
||||
return new ExileFromGraveCost(target);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -28,11 +28,9 @@
|
|||
|
||||
package mage.abilities.costs.common;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.costs.CostImpl;
|
||||
import mage.abilities.costs.VariableCost;
|
||||
import mage.filter.FilterMana;
|
||||
import mage.abilities.costs.Cost;
|
||||
import mage.abilities.costs.VariableCostImpl;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
|
||||
|
|
@ -41,70 +39,20 @@ import mage.players.Player;
|
|||
* @author LevelX2
|
||||
*/
|
||||
|
||||
public class PayVariableLifeCost extends CostImpl<PayVariableLifeCost> implements VariableCost {
|
||||
|
||||
protected int amountPaid = 0;
|
||||
public class PayVariableLifeCost extends VariableCostImpl<PayVariableLifeCost> {
|
||||
|
||||
public PayVariableLifeCost() {
|
||||
this.text = "pay X life";
|
||||
this(false);
|
||||
}
|
||||
|
||||
public PayVariableLifeCost(boolean additionalCostText) {
|
||||
super("life to pay");
|
||||
this.text = new StringBuilder(additionalCostText ? "As an additional cost to cast {source}, pay ":"Pay ")
|
||||
.append(xText).append(" ").append("life").toString();
|
||||
}
|
||||
|
||||
public PayVariableLifeCost(final PayVariableLifeCost cost) {
|
||||
super(cost);
|
||||
this.amountPaid = cost.amountPaid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPay(UUID sourceId, UUID controllerId, Game game) {
|
||||
Player controller = game.getPlayer(controllerId);
|
||||
return controller != null && controller.getLife() > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana) {
|
||||
Player controller = game.getPlayer(controllerId);
|
||||
if (controller != null) {
|
||||
this.amountPaid = controller.getAmount(0, controller.getLife(), "Choose X (life to pay)", game);
|
||||
if (this.amountPaid> 0) {
|
||||
controller.loseLife(amountPaid, game);
|
||||
}
|
||||
game.informPlayers(new StringBuilder(controller.getName()).append(" pays ").append(amountPaid).append(" life.").toString());
|
||||
this.paid = true;
|
||||
}
|
||||
return paid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearPaid() {
|
||||
paid = false;
|
||||
amountPaid = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAmount() {
|
||||
return amountPaid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAmount(int amount) {
|
||||
amountPaid = amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Not Supported
|
||||
* @param filter
|
||||
*/
|
||||
@Override
|
||||
public void setFilter(FilterMana filter) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Not supported
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public FilterMana getFilter() {
|
||||
return new FilterMana();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -112,4 +60,19 @@ public class PayVariableLifeCost extends CostImpl<PayVariableLifeCost> implement
|
|||
return new PayVariableLifeCost(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cost getFixedCostsFromAnnouncedValue(int xValue) {
|
||||
return new PayLifeCost(xValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxValue(Ability source, Game game) {
|
||||
int maxValue = 0;
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
maxValue = controller.getLife();
|
||||
}
|
||||
return maxValue;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,91 +28,46 @@
|
|||
|
||||
package mage.abilities.costs.common;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.costs.CostImpl;
|
||||
import mage.abilities.costs.VariableCost;
|
||||
import mage.abilities.costs.Cost;
|
||||
import mage.abilities.costs.VariableCostImpl;
|
||||
import mage.counters.CounterType;
|
||||
import mage.filter.FilterMana;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class PayVariableLoyaltyCost extends CostImpl<PayVariableLoyaltyCost> implements VariableCost {
|
||||
|
||||
protected int amountPaid = 0;
|
||||
public class PayVariableLoyaltyCost extends VariableCostImpl<PayVariableLoyaltyCost> {
|
||||
|
||||
public PayVariableLoyaltyCost() {
|
||||
super("loyality counters to remove");
|
||||
this.text = "-X";
|
||||
}
|
||||
|
||||
public PayVariableLoyaltyCost(final PayVariableLoyaltyCost cost) {
|
||||
super(cost);
|
||||
this.amountPaid = cost.amountPaid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPay(UUID sourceId, UUID controllerId, Game game) {
|
||||
Permanent planeswalker = game.getPermanent(sourceId);
|
||||
return !planeswalker.isLoyaltyUsed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana) {
|
||||
Permanent planeswalker = game.getPermanent(sourceId);
|
||||
Player player = game.getPlayer(planeswalker.getControllerId());
|
||||
this.amountPaid = player.getAmount(0, planeswalker.getCounters().getCount(CounterType.LOYALTY), "Choose X", game);
|
||||
if (this.amountPaid> 0) {
|
||||
planeswalker.getCounters().removeCounter(CounterType.LOYALTY, this.amountPaid);
|
||||
} else if (this.amountPaid < 0) {
|
||||
planeswalker.getCounters().addCounter(CounterType.LOYALTY.createInstance(Math.abs(this.amountPaid)));
|
||||
}
|
||||
planeswalker.setLoyaltyUsed(true);
|
||||
this.paid = true;
|
||||
return paid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearPaid() {
|
||||
paid = false;
|
||||
amountPaid = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAmount() {
|
||||
return amountPaid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAmount(int amount) {
|
||||
amountPaid = amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Not Supported
|
||||
* @param filter
|
||||
*/
|
||||
@Override
|
||||
public void setFilter(FilterMana filter) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Not supported
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public FilterMana getFilter() {
|
||||
return new FilterMana();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PayVariableLoyaltyCost copy() {
|
||||
return new PayVariableLoyaltyCost(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cost getFixedCostsFromAnnouncedValue(int xValue) {
|
||||
return new PayLoyaltyCost(xValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxValue(Ability source, Game game) {
|
||||
int maxValue = 0;
|
||||
Permanent permanent = game.getPermanent(source.getSourceId());
|
||||
if (permanent != null) {
|
||||
maxValue = permanent.getCounters().getCount(CounterType.LOYALTY.getName());
|
||||
}
|
||||
return maxValue;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,17 +32,18 @@ import java.util.HashSet;
|
|||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import mage.constants.Outcome;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.costs.CostImpl;
|
||||
import mage.choices.Choice;
|
||||
import mage.choices.ChoiceImpl;
|
||||
import mage.constants.Outcome;
|
||||
import mage.counters.Counter;
|
||||
import mage.counters.CounterType;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.TargetPermanent;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -53,69 +54,96 @@ public class RemoveCounterCost extends CostImpl<RemoveCounterCost> {
|
|||
private TargetPermanent target;
|
||||
private String name;
|
||||
private CounterType counterTypeToRemove;
|
||||
private int countersToRemove;
|
||||
|
||||
public RemoveCounterCost(TargetPermanent target) {
|
||||
this(target, null);
|
||||
}
|
||||
|
||||
public RemoveCounterCost(TargetPermanent target, CounterType counterTypeToRemove) {
|
||||
this(target, counterTypeToRemove, 1);
|
||||
}
|
||||
|
||||
public RemoveCounterCost(TargetPermanent target, CounterType counterTypeToRemove, int countersToRemove) {
|
||||
this.target = target;
|
||||
this.counterTypeToRemove = counterTypeToRemove;
|
||||
text = setText();
|
||||
this.countersToRemove = countersToRemove;
|
||||
|
||||
this.text = setText();
|
||||
}
|
||||
|
||||
public RemoveCounterCost(final RemoveCounterCost cost) {
|
||||
super(cost);
|
||||
this.target = cost.target.copy();
|
||||
this.name = cost.name;
|
||||
this.countersToRemove = cost.countersToRemove;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana) {
|
||||
paid = false;
|
||||
int countersRemoved = 0;
|
||||
Player controller = game.getPlayer(controllerId);
|
||||
if (target.choose(Outcome.UnboostCreature, controllerId, sourceId, game)) {
|
||||
for (UUID targetId: (List<UUID>)target.getTargets()) {
|
||||
Permanent permanent = game.getPermanent(targetId);
|
||||
if (permanent != null) {
|
||||
if (permanent.getCounters().size() > 0 && (counterTypeToRemove == null || permanent.getCounters().containsKey(counterTypeToRemove))) {
|
||||
String counterName = null;
|
||||
if (counterTypeToRemove != null) {
|
||||
counterName = counterTypeToRemove.getName();
|
||||
} else {
|
||||
if (permanent.getCounters().size() > 1 && counterTypeToRemove == null) {
|
||||
Choice choice = new ChoiceImpl(true);
|
||||
Set<String> choices = new HashSet<String>();
|
||||
for (Counter counter : permanent.getCounters().values()) {
|
||||
if (permanent.getCounters().getCount(counter.getName()) > 0) {
|
||||
choices.add(counter.getName());
|
||||
}
|
||||
}
|
||||
choice.setChoices(choices);
|
||||
choice.setMessage("Choose a counter to remove from " + permanent.getName());
|
||||
controller.choose(Outcome.UnboostCreature, choice, game);
|
||||
counterName = choice.getChoice();
|
||||
if (controller != null) {
|
||||
target.clearChosen();
|
||||
if (target.choose(Outcome.UnboostCreature, controllerId, sourceId, game)) {
|
||||
for (UUID targetId: (List<UUID>)target.getTargets()) {
|
||||
Permanent permanent = game.getPermanent(targetId);
|
||||
if (permanent != null) {
|
||||
if (permanent.getCounters().size() > 0 && (counterTypeToRemove == null || permanent.getCounters().containsKey(counterTypeToRemove))) {
|
||||
String counterName = null;
|
||||
|
||||
if (counterTypeToRemove != null) {
|
||||
counterName = counterTypeToRemove.getName();
|
||||
} else {
|
||||
for (Counter counter : permanent.getCounters().values()) {
|
||||
if (counter.getCount() > 0) {
|
||||
counterName = counter.getName();
|
||||
if (permanent.getCounters().size() > 1 && counterTypeToRemove == null) {
|
||||
Choice choice = new ChoiceImpl(true);
|
||||
Set<String> choices = new HashSet<>();
|
||||
for (Counter counter : permanent.getCounters().values()) {
|
||||
if (permanent.getCounters().getCount(counter.getName()) > 0) {
|
||||
choices.add(counter.getName());
|
||||
}
|
||||
}
|
||||
choice.setChoices(choices);
|
||||
choice.setMessage("Choose a counter to remove from " + permanent.getName());
|
||||
controller.choose(Outcome.UnboostCreature, choice, game);
|
||||
counterName = choice.getChoice();
|
||||
} else {
|
||||
for (Counter counter : permanent.getCounters().values()) {
|
||||
if (counter.getCount() > 0) {
|
||||
counterName = counter.getName();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (counterName != null) {
|
||||
permanent.removeCounters(counterName, 1, game);
|
||||
if (permanent.getCounters().getCount(counterName) == 0 ){
|
||||
permanent.getCounters().removeCounter(counterName);
|
||||
if (counterName != null) {
|
||||
int countersLeft = countersToRemove - countersRemoved;
|
||||
int countersOnPermanent = permanent.getCounters().getCount(counterName);
|
||||
int numberOfCountersSelected = 1;
|
||||
if (countersLeft > 1 && countersOnPermanent > 1) {
|
||||
numberOfCountersSelected = controller.getAmount(1, Math.min(countersLeft, countersOnPermanent),
|
||||
new StringBuilder("Remove how many counters from ").append(permanent.getName()).toString(), game);
|
||||
}
|
||||
permanent.removeCounters(counterName, numberOfCountersSelected, game);
|
||||
if (permanent.getCounters().getCount(counterName) == 0 ){
|
||||
permanent.getCounters().removeCounter(counterName);
|
||||
}
|
||||
countersRemoved += numberOfCountersSelected;
|
||||
game.informPlayers(new StringBuilder(controller.getName())
|
||||
.append(" removes ").append(numberOfCountersSelected == 1 ? "a":numberOfCountersSelected).append(" ")
|
||||
.append(counterName).append(numberOfCountersSelected == 1 ? " counter from ":" counters from ")
|
||||
.append(permanent.getName()).toString());
|
||||
if (countersRemoved == countersToRemove) {
|
||||
this.paid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.paid = true;
|
||||
game.informPlayers(new StringBuilder(controller.getName()).append(" removes a ").append(counterName).append(" counter from ").append(permanent.getName()).toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
target.clearChosen();
|
||||
|
||||
return paid;
|
||||
}
|
||||
|
||||
|
|
@ -125,11 +153,12 @@ public class RemoveCounterCost extends CostImpl<RemoveCounterCost> {
|
|||
}
|
||||
|
||||
private String setText() {
|
||||
StringBuilder sb = new StringBuilder("Remove a ");
|
||||
StringBuilder sb = new StringBuilder("Remove ");
|
||||
sb.append(CardUtil.numberToText(countersToRemove, "a")).append(" ");
|
||||
if (counterTypeToRemove != null) {
|
||||
sb.append(counterTypeToRemove.getName()).append(" ");
|
||||
sb.append(counterTypeToRemove.getName());
|
||||
}
|
||||
sb.append("counter from a ").append(target.getTargetName());
|
||||
sb.append(countersToRemove == 1 ? " counter from ":" counters from ").append(target.getMaxNumberOfTargets() == 1 ? "a ":"").append(target.getTargetName());
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,30 +28,27 @@
|
|||
|
||||
package mage.abilities.costs.common;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.costs.CostImpl;
|
||||
import mage.abilities.costs.VariableCost;
|
||||
import mage.abilities.costs.Cost;
|
||||
import mage.abilities.costs.VariableCostImpl;
|
||||
import mage.counters.Counter;
|
||||
import mage.filter.FilterMana;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public class RemoveVariableCountersSourceCost extends CostImpl<RemoveVariableCountersSourceCost> implements VariableCost {
|
||||
public class RemoveVariableCountersSourceCost extends VariableCostImpl<RemoveVariableCountersSourceCost> {
|
||||
|
||||
protected int amountPaid = 0;
|
||||
protected int minimalCountersToPay = 0;
|
||||
private String name;
|
||||
private String counterName;
|
||||
|
||||
public RemoveVariableCountersSourceCost(Counter counter, int minimalCountersToPay) {
|
||||
super(new StringBuilder(counter.getName()).append(" counters to remove").toString());
|
||||
this.minimalCountersToPay = minimalCountersToPay;
|
||||
this.name = counter.getName();
|
||||
this.text = "Remove X " + name + " counters from {this}";
|
||||
this.counterName = counter.getName();
|
||||
this.text = new StringBuilder("Remove ").append(xText).append(" ").append(counterName).append(" counters from {this}").toString();
|
||||
}
|
||||
|
||||
public RemoveVariableCountersSourceCost(Counter counter) {
|
||||
|
|
@ -60,65 +57,8 @@ public class RemoveVariableCountersSourceCost extends CostImpl<RemoveVariableCou
|
|||
|
||||
public RemoveVariableCountersSourceCost(final RemoveVariableCountersSourceCost cost) {
|
||||
super(cost);
|
||||
this.amountPaid = cost.amountPaid;
|
||||
this.minimalCountersToPay = cost.minimalCountersToPay;
|
||||
this.name = cost.name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPay(UUID sourceId, UUID controllerId, Game game) {
|
||||
Permanent permanent = game.getPermanent(sourceId);
|
||||
return permanent != null && permanent.getCounters().getCount(name) >= minimalCountersToPay;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana) {
|
||||
Permanent permanent = game.getPermanent(sourceId);
|
||||
if (permanent != null) {
|
||||
Player player = game.getPlayer(permanent.getControllerId());
|
||||
if (player != null) {
|
||||
this.amountPaid = player.getAmount(minimalCountersToPay, permanent.getCounters().getCount(name), "Choose X counters to remove", game);
|
||||
if (this.amountPaid >= minimalCountersToPay) {
|
||||
permanent.removeCounters(name, amountPaid, game);
|
||||
this.paid = true;
|
||||
}
|
||||
game.informPlayers(new StringBuilder(player.getName()).append(" removes ").append(this.amountPaid).append(" ").append(name).append(" counter from ").append(permanent.getName()).toString());
|
||||
}
|
||||
}
|
||||
return paid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearPaid() {
|
||||
paid = false;
|
||||
amountPaid = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAmount() {
|
||||
return amountPaid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAmount(int amount) {
|
||||
amountPaid = amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Not Supported
|
||||
* @param filter
|
||||
*/
|
||||
@Override
|
||||
public void setFilter(FilterMana filter) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Not supported
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public FilterMana getFilter() {
|
||||
return new FilterMana();
|
||||
this.counterName = cost.counterName;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -126,5 +66,25 @@ public class RemoveVariableCountersSourceCost extends CostImpl<RemoveVariableCou
|
|||
return new RemoveVariableCountersSourceCost(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cost getFixedCostsFromAnnouncedValue(int xValue) {
|
||||
return new RemoveCountersSourceCost(new Counter(counterName, xValue));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMinValue(Ability source, Game game) {
|
||||
return minimalCountersToPay;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxValue(Ability source, Game game) {
|
||||
int maxValue = 0;
|
||||
Permanent permanent = game.getPermanent(source.getSourceId());
|
||||
if (permanent != null) {
|
||||
maxValue = permanent.getCounters().getCount(counterName);
|
||||
}
|
||||
return maxValue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,144 +28,109 @@
|
|||
|
||||
package mage.abilities.costs.common;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import mage.constants.Outcome;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.costs.CostImpl;
|
||||
import mage.abilities.costs.VariableCost;
|
||||
import mage.choices.Choice;
|
||||
import mage.choices.ChoiceImpl;
|
||||
import mage.abilities.costs.Cost;
|
||||
import mage.abilities.costs.VariableCostImpl;
|
||||
import mage.counters.Counter;
|
||||
import mage.counters.CounterType;
|
||||
import mage.filter.FilterMana;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.TargetPermanent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX
|
||||
*/
|
||||
public class RemoveVariableCountersTargetCost extends CostImpl<RemoveVariableCountersTargetCost> implements VariableCost {
|
||||
public class RemoveVariableCountersTargetCost extends VariableCostImpl<RemoveVariableCountersTargetCost> {
|
||||
|
||||
protected int amountPaid = 0;
|
||||
protected TargetPermanent target;
|
||||
protected String name;
|
||||
protected FilterPermanent filter;
|
||||
protected CounterType counterTypeToRemove;
|
||||
protected int minValue;
|
||||
|
||||
public RemoveVariableCountersTargetCost(TargetPermanent target) {
|
||||
this(target, null);
|
||||
public RemoveVariableCountersTargetCost(FilterPermanent filter) {
|
||||
this(filter, null);
|
||||
}
|
||||
|
||||
public RemoveVariableCountersTargetCost(TargetPermanent target, CounterType counterTypeToRemove) {
|
||||
this.target = target;
|
||||
public RemoveVariableCountersTargetCost(FilterPermanent filter, CounterType counterTypeToRemove) {
|
||||
this(filter, counterTypeToRemove, "X", 0);
|
||||
}
|
||||
|
||||
public RemoveVariableCountersTargetCost(FilterPermanent filter, CounterType counterTypeToRemove, String xText, int minValue) {
|
||||
super(xText, new StringBuilder(counterTypeToRemove != null ? counterTypeToRemove.getName() + " ":"").append("counters to remove").toString());
|
||||
this.filter = filter;
|
||||
this.counterTypeToRemove = counterTypeToRemove;
|
||||
text = setText();
|
||||
this.text = setText();
|
||||
this.minValue = minValue;
|
||||
}
|
||||
|
||||
public RemoveVariableCountersTargetCost(final RemoveVariableCountersTargetCost cost) {
|
||||
super(cost);
|
||||
this.target = cost.target.copy();
|
||||
this.name = cost.name;
|
||||
this.filter = cost.filter;
|
||||
this.minValue = cost.minValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana) {
|
||||
paid = false;
|
||||
Player controller = game.getPlayer(controllerId);
|
||||
if (target.choose(Outcome.UnboostCreature, controllerId, sourceId, game)) {
|
||||
for (UUID targetId: (List<UUID>)target.getTargets()) {
|
||||
Permanent permanent = game.getPermanent(targetId);
|
||||
if (permanent != null) {
|
||||
if (permanent.getCounters().size() > 0 && (counterTypeToRemove == null || permanent.getCounters().containsKey(counterTypeToRemove))) {
|
||||
String counterName = null;
|
||||
if (counterTypeToRemove != null) {
|
||||
counterName = counterTypeToRemove.getName();
|
||||
} else {
|
||||
if (permanent.getCounters().size() > 1 && counterTypeToRemove == null) {
|
||||
Choice choice = new ChoiceImpl(true);
|
||||
Set<String> choices = new HashSet<String>();
|
||||
for (Counter counter : permanent.getCounters().values()) {
|
||||
if (permanent.getCounters().getCount(counter.getName()) > 0) {
|
||||
choices.add(counter.getName());
|
||||
}
|
||||
}
|
||||
choice.setChoices(choices);
|
||||
choice.setMessage("Choose a counter to remove from " + permanent.getName());
|
||||
controller.choose(Outcome.UnboostCreature, choice, game);
|
||||
counterName = choice.getChoice();
|
||||
} else {
|
||||
for (Counter counter : permanent.getCounters().values()) {
|
||||
if (counter.getCount() > 0) {
|
||||
counterName = counter.getName();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (counterName != null) {
|
||||
int countersToRemove = 1;
|
||||
if (permanent.getCounters().getCount(counterName) > 1) {
|
||||
countersToRemove = controller.getAmount(1, permanent.getCounters().getCount(counterName),"Remove how many counters from " + permanent.getName(), game);
|
||||
}
|
||||
permanent.removeCounters(counterName, countersToRemove, game);
|
||||
if (permanent.getCounters().getCount(counterName) == 0 ){
|
||||
permanent.getCounters().removeCounter(counterName);
|
||||
}
|
||||
this.amountPaid += countersToRemove;
|
||||
this.paid = true;
|
||||
game.informPlayers(new StringBuilder(controller.getName()).append(" removes ").append(countersToRemove).append(" ").append(counterName).append(" counter from ").append(permanent.getName()).toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
target.clearChosen();
|
||||
// paid = false;
|
||||
// Player controller = game.getPlayer(controllerId);
|
||||
// if (target.choose(Outcome.UnboostCreature, controllerId, sourceId, game)) {
|
||||
// for (UUID targetId: (List<UUID>)target.getTargets()) {
|
||||
// Permanent permanent = game.getPermanent(targetId);
|
||||
// if (permanent != null) {
|
||||
// if (permanent.getCounters().size() > 0 && (counterTypeToRemove == null || permanent.getCounters().containsKey(counterTypeToRemove))) {
|
||||
// String counterName = null;
|
||||
// if (counterTypeToRemove != null) {
|
||||
// counterName = counterTypeToRemove.getName();
|
||||
// } else {
|
||||
// if (permanent.getCounters().size() > 1 && counterTypeToRemove == null) {
|
||||
// Choice choice = new ChoiceImpl(true);
|
||||
// Set<String> choices = new HashSet<>();
|
||||
// for (Counter counter : permanent.getCounters().values()) {
|
||||
// if (permanent.getCounters().getCount(counter.getName()) > 0) {
|
||||
// choices.add(counter.getName());
|
||||
// }
|
||||
// }
|
||||
// choice.setChoices(choices);
|
||||
// choice.setMessage("Choose a counter to remove from " + permanent.getName());
|
||||
// controller.choose(Outcome.UnboostCreature, choice, game);
|
||||
// counterName = choice.getChoice();
|
||||
// } else {
|
||||
// for (Counter counter : permanent.getCounters().values()) {
|
||||
// if (counter.getCount() > 0) {
|
||||
// counterName = counter.getName();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// if (counterName != null) {
|
||||
// int countersToRemove = 1;
|
||||
// if (permanent.getCounters().getCount(counterName) > 1) {
|
||||
// countersToRemove = controller.getAmount(1, permanent.getCounters().getCount(counterName),"Remove how many counters from " + permanent.getName(), game);
|
||||
// }
|
||||
// permanent.removeCounters(counterName, countersToRemove, game);
|
||||
// if (permanent.getCounters().getCount(counterName) == 0 ){
|
||||
// permanent.getCounters().removeCounter(counterName);
|
||||
// }
|
||||
// this.amountPaid += countersToRemove;
|
||||
// this.paid = true;
|
||||
// game.informPlayers(new StringBuilder(controller.getName()).append(" removes ").append(countersToRemove).append(" ").append(counterName).append(" counter from ").append(permanent.getName()).toString());
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// target.clearChosen();
|
||||
return paid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAmount() {
|
||||
return amountPaid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAmount(int amount) {
|
||||
amountPaid = amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Not Supported
|
||||
* @param filter
|
||||
*/
|
||||
@Override
|
||||
public void setFilter(FilterMana filter) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Not supported
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public FilterMana getFilter() {
|
||||
return new FilterMana();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPay(UUID sourceId, UUID controllerId, Game game) {
|
||||
return target.canChoose(controllerId, game);
|
||||
}
|
||||
|
||||
private String setText() {
|
||||
// Remove one or more +1/+1 counters from among creatures you control
|
||||
StringBuilder sb = new StringBuilder("Remove one or more ");
|
||||
StringBuilder sb = new StringBuilder("Remove ").append(xText);
|
||||
if (counterTypeToRemove != null) {
|
||||
sb.append(counterTypeToRemove.getName()).append(" ");
|
||||
sb.append(" ").append(counterTypeToRemove.getName());
|
||||
}
|
||||
sb.append("counter from among ").append(target.getTargetName());
|
||||
sb.append(" counters from among ").append(filter.getMessage());
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
|
@ -173,4 +138,25 @@ public class RemoveVariableCountersTargetCost extends CostImpl<RemoveVariableCou
|
|||
public RemoveVariableCountersTargetCost copy() {
|
||||
return new RemoveVariableCountersTargetCost(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxValue(Ability source, Game game) {
|
||||
int maxValue = 0;
|
||||
for (Permanent permanent :game.getBattlefield().getAllActivePermanents(filter, source.getControllerId(), game)) {
|
||||
if (counterTypeToRemove != null) {
|
||||
maxValue += permanent.getCounters().getCount(counterTypeToRemove);
|
||||
} else {
|
||||
for(Counter counter :permanent.getCounters().values()){
|
||||
maxValue += counter.getCount();
|
||||
}
|
||||
}
|
||||
}
|
||||
return maxValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cost getFixedCostsFromAnnouncedValue(int xValue) {
|
||||
return new RemoveCounterCost(new TargetPermanent(1,Integer.MAX_VALUE, filter, true), counterTypeToRemove, xValue);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* 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.costs.common;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.costs.Cost;
|
||||
import mage.abilities.costs.VariableCostImpl;
|
||||
import mage.filter.common.FilterControlledPermanent;
|
||||
import mage.game.Game;
|
||||
import mage.target.common.TargetControlledPermanent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public class SacrificeXTargetCost extends VariableCostImpl<SacrificeXTargetCost> {
|
||||
|
||||
protected FilterControlledPermanent filter;
|
||||
|
||||
public SacrificeXTargetCost(FilterControlledPermanent filter) {
|
||||
this(filter, false);
|
||||
}
|
||||
|
||||
public SacrificeXTargetCost(FilterControlledPermanent filter, boolean additionalCostText) {
|
||||
super(new StringBuilder(filter.getMessage()).append(" to sacrifice").toString());
|
||||
this.text = new StringBuilder(additionalCostText ? "As an additional cost to cast {source}, sacrifice ":"Sacrifice ").append(xText).append(" ").append(filter.getMessage()).toString();
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
public SacrificeXTargetCost(final SacrificeXTargetCost cost) {
|
||||
super(cost);
|
||||
this.filter = cost.filter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SacrificeXTargetCost copy() {
|
||||
return new SacrificeXTargetCost(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxValue(Ability source, Game game) {
|
||||
return game.getBattlefield().count(filter, source.getSourceId(), source.getControllerId(), game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cost getFixedCostsFromAnnouncedValue(int xValue) {
|
||||
TargetControlledPermanent target = new TargetControlledPermanent(xValue, xValue, filter, true);
|
||||
target.setRequired(true);
|
||||
return new SacrificeTargetCost(target);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -28,90 +28,35 @@
|
|||
|
||||
package mage.abilities.costs.common;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.UUID;
|
||||
import mage.constants.Outcome;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.costs.CostImpl;
|
||||
import mage.abilities.costs.VariableCost;
|
||||
import mage.filter.FilterMana;
|
||||
import mage.abilities.costs.Cost;
|
||||
import mage.abilities.costs.VariableCostImpl;
|
||||
import mage.filter.common.FilterControlledPermanent;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.target.common.TargetControlledPermanent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class TapVariableTargetCost extends CostImpl<TapVariableTargetCost> implements VariableCost {
|
||||
public class TapVariableTargetCost extends VariableCostImpl<TapVariableTargetCost> {
|
||||
|
||||
protected int amountPaid = 0;
|
||||
protected TargetControlledPermanent target;
|
||||
protected FilterControlledPermanent filter;
|
||||
|
||||
public TapVariableTargetCost(TargetControlledPermanent target) {
|
||||
this.target = target;
|
||||
this.text = "tap X " + target.getTargetName() + " you control";
|
||||
public TapVariableTargetCost(FilterControlledPermanent filter) {
|
||||
this(filter, false, "X");
|
||||
}
|
||||
|
||||
public TapVariableTargetCost(FilterControlledPermanent filter, boolean additionalCostText, String xText) {
|
||||
super(xText, new StringBuilder(filter.getMessage()).append(" to tap").toString());
|
||||
this.filter = filter;
|
||||
this.text = new StringBuilder(additionalCostText ? "As an additional cost to cast {source}, tap ":"Tap ")
|
||||
.append(this.xText).append(" ").append(filter.getMessage()).toString();
|
||||
}
|
||||
|
||||
public TapVariableTargetCost(final TapVariableTargetCost cost) {
|
||||
super(cost);
|
||||
this.target = cost.target.copy();
|
||||
this.amountPaid = cost.amountPaid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPay(UUID sourceId, UUID controllerId, Game game) {
|
||||
return target.canChoose(controllerId, game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana) {
|
||||
amountPaid = 0;
|
||||
target.clearChosen();
|
||||
if (target.canChoose(sourceId, controllerId, game) && target.choose(Outcome.Tap, controllerId, sourceId, game)) {
|
||||
for (Iterator it = target.getTargets().iterator(); it.hasNext();) {
|
||||
UUID uuid = (UUID) it.next();
|
||||
Permanent permanent = game.getPermanent(uuid);
|
||||
if (permanent != null && permanent.tap(game)) {
|
||||
amountPaid++;
|
||||
}
|
||||
}
|
||||
}
|
||||
paid = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearPaid() {
|
||||
paid = false;
|
||||
amountPaid = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAmount() {
|
||||
return amountPaid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAmount(int amount) {
|
||||
amountPaid = amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Not Supported
|
||||
* @param filter
|
||||
*/
|
||||
@Override
|
||||
public void setFilter(FilterMana filter) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Not supported
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public FilterMana getFilter() {
|
||||
return new FilterMana();
|
||||
this.filter = cost.filter.copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -119,4 +64,14 @@ public class TapVariableTargetCost extends CostImpl<TapVariableTargetCost> imple
|
|||
return new TapVariableTargetCost(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxValue(Ability source, Game game) {
|
||||
return game.getBattlefield().countAll(filter, source.getControllerId(), game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cost getFixedCostsFromAnnouncedValue(int xValue) {
|
||||
return new TapTargetCost(new TargetControlledPermanent(xValue, xValue, filter, true));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ import mage.abilities.costs.VariableCost;
|
|||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
* @param <T>
|
||||
*/
|
||||
public interface ManaCosts<T extends ManaCost> extends List<T>, ManaCost {
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ package mage.abilities.costs.mana;
|
|||
|
||||
import mage.Mana;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.costs.Cost;
|
||||
import mage.abilities.costs.VariableCost;
|
||||
import mage.constants.ColoredManaSymbol;
|
||||
import mage.filter.FilterMana;
|
||||
|
|
@ -113,16 +114,6 @@ public class VariableManaCost extends ManaCostImpl<VariableManaCost> implements
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFilter(FilterMana filter) {
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FilterMana getFilter() {
|
||||
return filter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VariableManaCost copy() {
|
||||
return new VariableManaCost(this);
|
||||
|
|
@ -152,4 +143,37 @@ public class VariableManaCost extends ManaCostImpl<VariableManaCost> implements
|
|||
public boolean containsColor(ColoredManaSymbol coloredManaSymbol) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int announceXValue(Ability source, Game game) {
|
||||
throw new UnsupportedOperationException("Not supported."); //To change body of generated methods, choose Tools | Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cost getFixedCostsFromAnnouncedValue(int xValue) {
|
||||
throw new UnsupportedOperationException("Not supported."); //To change body of generated methods, choose Tools | Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getActionText() {
|
||||
throw new UnsupportedOperationException("Not supported."); //To change body of generated methods, choose Tools | Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMinValue(Ability source, Game game) {
|
||||
throw new UnsupportedOperationException("Not supported."); //To change body of generated methods, choose Tools | Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxValue(Ability source, Game game) {
|
||||
throw new UnsupportedOperationException("Not supported."); //To change body of generated methods, choose Tools | Templates.
|
||||
}
|
||||
|
||||
public FilterMana getFilter() {
|
||||
return filter;
|
||||
}
|
||||
|
||||
public void setFilter(FilterMana filter) {
|
||||
this.filter = filter;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -86,6 +86,9 @@ public class ReturnFromGraveyardToBattlefieldTargetEffect extends OneShotEffect<
|
|||
|
||||
@Override
|
||||
public String getText(Mode mode) {
|
||||
if (staticText != null && !staticText.isEmpty()) {
|
||||
return staticText;
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
Target target = mode.getTargets().get(0);
|
||||
sb.append("Return ");
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ public class TransformSourceEffect extends OneShotEffect<TransformSourceEffect>
|
|||
this(fromDayToNight, false);
|
||||
}
|
||||
|
||||
private TransformSourceEffect(boolean fromDayToNight, boolean withoutTrigger) {
|
||||
public TransformSourceEffect(boolean fromDayToNight, boolean withoutTrigger) {
|
||||
super(Outcome.Transform);
|
||||
this.withoutTrigger = withoutTrigger;
|
||||
this.fromDayToNight = fromDayToNight;
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ import java.io.Serializable;
|
|||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
* @param <T>
|
||||
*/
|
||||
public class Counter<T extends Counter<T>> implements Serializable {
|
||||
|
||||
|
|
|
|||
|
|
@ -53,27 +53,31 @@ public class Counters extends HashMap<String, Counter> implements Serializable {
|
|||
}
|
||||
|
||||
public void addCounter(String name) {
|
||||
if (!this.containsKey(name))
|
||||
if (!this.containsKey(name)) {
|
||||
this.put(name, new Counter(name));
|
||||
}
|
||||
this.get(name).add();
|
||||
}
|
||||
|
||||
public void addCounter(String name, int amount) {
|
||||
if (!this.containsKey(name))
|
||||
if (!this.containsKey(name)) {
|
||||
this.put(name, new Counter(name));
|
||||
}
|
||||
this.get(name).add(amount);
|
||||
}
|
||||
|
||||
public void addCounter(Counter counter) {
|
||||
if (!this.containsKey(counter.name))
|
||||
if (!this.containsKey(counter.name)) {
|
||||
put(counter.name, counter);
|
||||
else
|
||||
} else {
|
||||
get(counter.name).add(counter.getCount());
|
||||
}
|
||||
}
|
||||
|
||||
public void removeCounter(String name) {
|
||||
if (this.containsKey(name))
|
||||
if (this.containsKey(name)) {
|
||||
this.get(name).remove();
|
||||
}
|
||||
}
|
||||
|
||||
public void removeCounter(CounterType counterType, int amount) {
|
||||
|
|
@ -83,13 +87,15 @@ public class Counters extends HashMap<String, Counter> implements Serializable {
|
|||
}
|
||||
|
||||
public void removeCounter(String name, int amount) {
|
||||
if (this.containsKey(name))
|
||||
if (this.containsKey(name)) {
|
||||
this.get(name).remove(amount);
|
||||
}
|
||||
}
|
||||
|
||||
public int getCount(String name) {
|
||||
if (this.containsKey(name))
|
||||
if (this.containsKey(name)) {
|
||||
return this.get(name).getCount();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -98,16 +104,18 @@ public class Counters extends HashMap<String, Counter> implements Serializable {
|
|||
}
|
||||
|
||||
public int getCount(CounterType type) {
|
||||
if (this.containsKey(type.getName()))
|
||||
if (this.containsKey(type.getName())) {
|
||||
return this.get(type.getName()).getCount();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public List<BoostCounter> getBoostCounters() {
|
||||
List<BoostCounter> boosters = new ArrayList<BoostCounter>();
|
||||
List<BoostCounter> boosters = new ArrayList<>();
|
||||
for (Counter counter: this.values()) {
|
||||
if (counter instanceof BoostCounter)
|
||||
if (counter instanceof BoostCounter) {
|
||||
boosters.add((BoostCounter)counter);
|
||||
}
|
||||
}
|
||||
return boosters;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,13 +6,20 @@ import mage.abilities.keyword.FlyingAbility;
|
|||
import mage.constants.CardType;
|
||||
|
||||
public class AngelToken extends Token {
|
||||
|
||||
public AngelToken() {
|
||||
this("M14");
|
||||
}
|
||||
|
||||
public AngelToken(String tokenImageSetCode) {
|
||||
super("Angel", "4/4 white Angel creature token with flying");
|
||||
this.setOriginalExpansionSetCode(tokenImageSetCode);
|
||||
cardType.add(CardType.CREATURE);
|
||||
color = ObjectColor.WHITE;
|
||||
subtype.add("Angel");
|
||||
power = new MageInt(4);
|
||||
toughness = new MageInt(4);
|
||||
addAbility(FlyingAbility.getInstance());
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,8 +4,14 @@ import mage.MageInt;
|
|||
import mage.constants.CardType;
|
||||
|
||||
public class MyrToken extends Token {
|
||||
|
||||
public MyrToken() {
|
||||
this("SOM");
|
||||
}
|
||||
|
||||
public MyrToken(String expansionSetCode) {
|
||||
super("Myr", "1/1 colorless Myr artifact creature token");
|
||||
this.setOriginalExpansionSetCode(expansionSetCode);
|
||||
cardType.add(CardType.CREATURE);
|
||||
cardType.add(CardType.ARTIFACT);
|
||||
subtype.add("Myr");
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ import mage.abilities.Mode;
|
|||
import mage.abilities.Modes;
|
||||
import mage.abilities.SpellAbility;
|
||||
import mage.abilities.TriggeredAbility;
|
||||
import mage.abilities.costs.VariableCost;
|
||||
import mage.abilities.costs.mana.ManaCost;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.Cards;
|
||||
|
|
@ -278,9 +279,12 @@ public interface Player extends MageItem, Copyable<Player> {
|
|||
*/
|
||||
boolean putCardsOnBottomOfLibrary(Cards cards, Game game, Ability source, boolean anyOrder);
|
||||
|
||||
// set the value for X spells and abilities
|
||||
// set the value for X mana spells and abilities
|
||||
int announceXMana(int min, int max, String message, Game game, Ability ability);
|
||||
|
||||
// set the value for non mana X costs
|
||||
int announceXCost(int min, int max, String message, Game game, Ability ability, VariableCost variableCost);
|
||||
|
||||
int chooseEffect(List<String> rEffects, Game game);
|
||||
TriggeredAbility chooseTriggeredAbility(List<TriggeredAbility> abilities, Game game);
|
||||
Mode chooseMode(Modes modes, Ability source, Game game);
|
||||
|
|
|
|||
|
|
@ -46,8 +46,8 @@ import java.util.*;
|
|||
*/
|
||||
public abstract class TargetImpl<T extends TargetImpl<T>> implements Target {
|
||||
|
||||
protected Map<UUID, Integer> targets = new LinkedHashMap<UUID, Integer>();
|
||||
protected Map<UUID, Integer> zoneChangeCounters = new HashMap<UUID, Integer>();
|
||||
protected Map<UUID, Integer> targets = new LinkedHashMap<>();
|
||||
protected Map<UUID, Integer> zoneChangeCounters = new HashMap<>();
|
||||
|
||||
protected String targetName;
|
||||
protected Zone zone;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue