use of mage.abilities.costs.mana.VariableManaCost in project mage by magefree.
the class ExileFromHandCost method pay.
@Override
public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) {
if (targets.choose(Outcome.Exile, controllerId, source.getSourceId(), game)) {
Player player = game.getPlayer(controllerId);
int cmc = 0;
for (UUID targetId : targets.get(0).getTargets()) {
Card card = player.getHand().get(targetId, game);
if (card == null) {
return false;
}
cmc += card.getManaValue();
this.cards.add(card);
}
Cards cardsToExile = new CardsImpl();
cardsToExile.addAll(cards);
player.moveCards(cardsToExile, Zone.EXILED, ability, game);
paid = true;
if (setXFromCMC) {
VariableManaCost vmc = new VariableManaCost(VariableCostType.ALTERNATIVE);
// no x events - rules from Unbound Flourishing:
// - Spells with additional costs that include X won't be affected by Unbound Flourishing. X must be in the spell's mana cost.
// TODO: wtf, look at setXFromCMC usage -- it used in cards with alternative costs, not additional... need to fix?
vmc.setAmount(cmc, cmc, false);
vmc.setPaid();
ability.getManaCostsToPay().add(vmc);
}
}
return paid;
}
use of mage.abilities.costs.mana.VariableManaCost in project mage by magefree.
the class AbilityImpl method activate.
@Override
public boolean activate(Game game, boolean noMana) {
Player controller = game.getPlayer(this.getControllerId());
if (controller == null) {
return false;
}
game.applyEffects();
MageObject sourceObject = getSourceObject(game);
if (getSourceObjectZoneChangeCounter() == 0) {
setSourceObjectZoneChangeCounter(game.getState().getZoneChangeCounter(getSourceId()));
}
setSourcePermanentTransformCount(game);
/* 20130201 - 601.2b
* If the player wishes to splice any cards onto the spell (see rule 702.45), he
* or she reveals those cards in their hand.
*/
if (this.abilityType == AbilityType.SPELL) {
game.getContinuousEffects().applySpliceEffects(this, game);
}
// For Flashback ability can be set X before, so the X costs have to be restored for the flashbacked ability
if (noMana) {
if (!this.getManaCostsToPay().getVariableCosts().isEmpty()) {
int xValue = this.getManaCostsToPay().getX();
this.getManaCostsToPay().clear();
VariableManaCost xCosts = new VariableManaCost(VariableCostType.ADDITIONAL);
// no x events - rules from Unbound Flourishing:
// - Spells with additional costs that include X won't be affected by Unbound Flourishing. X must be in the spell's mana cost.
xCosts.setAmount(xValue, xValue, false);
this.getManaCostsToPay().add(xCosts);
} else {
this.getManaCostsToPay().clear();
}
}
// A player can't apply two alternative methods of casting or two alternative costs to a single spell.
if (!activateAlternateOrAdditionalCosts(sourceObject, noMana, controller, game)) {
if (getAbilityType() == AbilityType.SPELL && ((SpellAbility) this).getSpellAbilityType() == SpellAbilityType.FACE_DOWN_CREATURE) {
return false;
}
}
// }
if (getAbilityType() == AbilityType.SPELL && (getManaCostsToPay().isEmpty() && getCosts().isEmpty()) && !noMana) {
return false;
}
// 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 = handleManaXCosts(game, noMana, controller);
String announceString = handleOtherXCosts(game, controller);
// For effects from cards like Void Winnower x costs have to be set
if (this.getAbilityType() == AbilityType.SPELL) {
GameEvent castEvent = GameEvent.getEvent(GameEvent.EventType.CAST_SPELL_LATE, this.getId(), this, getControllerId());
castEvent.setZone(game.getState().getZone(CardUtil.getMainCardId(game, sourceId)));
if (game.replaceEvent(castEvent, this)) {
return false;
}
}
handlePhyrexianManaCosts(game, controller);
// Kicking a spell is always optional.
if (!getModes().choose(game, this)) {
return false;
}
// 2. From single addTarget/setChoice, it's a preffered method for tests (process it in normal choose dialogs like human player)
if (controller.isTestsMode()) {
if (!controller.addTargets(this, game)) {
return false;
}
}
for (UUID modeId : this.getModes().getSelectedModes()) {
this.getModes().setActiveMode(modeId);
if (sourceObject != null && this.getAbilityType() != AbilityType.TRIGGERED) {
// triggered abilities check this already in playerImpl.triggerAbility
sourceObject.adjustTargets(this, game);
}
if (!getTargets().isEmpty()) {
Outcome outcome = getEffects().getOutcome(this);
// only activated abilities can be canceled by human user (not triggered)
boolean canCancel = this instanceof ActivatedAbility && controller.isHuman();
if (!getTargets().chooseTargets(outcome, this.controllerId, this, noMana, game, canCancel)) {
// was canceled during targer selection
return false;
}
}
}
// this is a hack to prevent mana abilities with mana costs from causing endless loops - pay other costs first
if (this instanceof ActivatedManaAbilityImpl && !costs.pay(this, game, this, controllerId, noMana, null)) {
logger.debug("activate mana ability failed - non mana costs");
return false;
}
// fused spell contains 3 abilities (fused, left, right)
// fused cost added to fused ability, so no need cost modification for other parts
boolean needCostModification = !CardUtil.isFusedPartAbility(this, game);
// 20101001 - 601.2e
if (needCostModification && sourceObject != null) {
// still needed for CostAdjuster objects (to handle some types of dynamic costs)
sourceObject.adjustCosts(this, game);
game.getContinuousEffects().costModification(this, game);
}
UUID activatorId = controllerId;
if ((this instanceof ActivatedAbilityImpl) && ((ActivatedAbilityImpl) this).getActivatorId() != null) {
activatorId = ((ActivatedAbilityImpl) this).getActivatorId();
}
// 20100716 - 601.2f (noMana is not used here, because mana costs were cleared for this ability before adding additional costs and applying cost modification effects)
if (!manaCostsToPay.pay(this, game, this, activatorId, false, null)) {
// cancel during mana payment
return false;
}
// 20100716 - 601.2g
if (!costs.pay(this, game, this, activatorId, noMana, null)) {
logger.debug("activate failed - non mana costs");
return false;
}
// inform about x costs now, so canceled announcements are not shown in the log
if ((announceString != null) && (!announceString.equals(""))) {
game.informPlayers(announceString);
}
if (variableManaCost != null) {
int xValue = getManaCostsToPay().getX();
game.informPlayers(controller.getLogName() + " announces a value of " + xValue + " for " + variableManaCost.getText());
}
activated = true;
return true;
}
use of mage.abilities.costs.mana.VariableManaCost in project mage by magefree.
the class AbilityImpl method handleOtherXCosts.
/**
* Handles the setting of non mana X costs
*
* @param controller
* @param game
* @return announce message
*/
protected String handleOtherXCosts(Game game, Player controller) {
StringBuilder announceString = new StringBuilder();
for (VariableCost variableCost : this.costs.getVariableCosts()) {
if (!(variableCost instanceof VariableManaCost) && !((Cost) variableCost).isPaid()) {
int xValue = variableCost.announceXValue(this, game);
Cost fixedCost = variableCost.getFixedCostsFromAnnouncedValue(xValue);
if (fixedCost != null) {
costs.add(fixedCost);
}
// set the xcosts to paid
// no x events - rules from Unbound Flourishing:
// - Spells with additional costs that include X won't be affected by Unbound Flourishing. X must be in the spell's mana cost.
variableCost.setAmount(xValue, xValue, false);
((Cost) variableCost).setPaid();
String message = controller.getLogName() + " announces a value of " + xValue + " (" + variableCost.getActionText() + ')';
announceString.append(message);
}
}
return announceString.toString();
}
use of mage.abilities.costs.mana.VariableManaCost in project mage by magefree.
the class SpellAbility method getConvertedXManaCost.
public int getConvertedXManaCost(Card card) {
int xMultiplier = 0;
int amount = 0;
if (card == null) {
return 0;
}
// mana cost instances
for (ManaCost manaCost : card.getManaCost()) {
if (manaCost instanceof VariableManaCost) {
xMultiplier = ((VariableManaCost) manaCost).getXInstancesCount();
break;
}
}
// mana cost final X value
boolean hasNonManaXCost = false;
for (Cost cost : getCosts()) {
if (cost instanceof VariableCost) {
hasNonManaXCost = true;
amount = ((VariableCost) cost).getAmount();
break;
}
}
if (!hasNonManaXCost) {
amount = getManaCostsToPay().getX();
}
return amount * xMultiplier;
}
use of mage.abilities.costs.mana.VariableManaCost in project mage by magefree.
the class UnboundFlourishingTest method test_VariableManaCost.
@Test
public void test_VariableManaCost() {
// VariableManaCost contains:
// - number of {X} instances (1, 2, 3)
// - final X value after all replace events
// - total number of pays
// getAmount() must return final X value
// setAmount() must setup final X value
// test example: {X}{X}, X=3, double X effect from replace event
int xInstancesCount = 2;
int xAnnouncedValue = 3;
int xMultiplier = 2;
VariableManaCost cost = new VariableManaCost(VariableCostType.NORMAL, xInstancesCount);
cost.setAmount(xAnnouncedValue * xMultiplier, xAnnouncedValue * xInstancesCount, false);
Assert.assertEquals("instances count", xInstancesCount, cost.getXInstancesCount());
Assert.assertEquals("boosted X value", xAnnouncedValue * xMultiplier, cost.getAmount());
}
Aggregations