use of mage.abilities.costs.mana.ManaCost in project mage by magefree.
the class ConvokeEffect method getManaOptions.
@Override
public ManaOptions getManaOptions(Ability source, Game game, ManaCost unpaid) {
ManaOptions options = new ManaOptions();
FilterControlledCreaturePermanent filterBasic = new FilterControlledCreaturePermanent();
// each creature can give {1} or color mana
game.getBattlefield().getActivePermanents(filterBasic, source.getControllerId(), source.getSourceId(), game).stream().filter(permanent -> !permanent.isTapped()).forEach(permanent -> {
ManaOptions permMana = new ManaOptions();
permMana.add(Mana.GenericMana(1));
for (ObjectColor color : permanent.getColor(game).getColors()) {
if (color.isBlack())
permMana.add(Mana.BlackMana(1));
if (color.isBlue())
permMana.add(Mana.BlueMana(1));
if (color.isGreen())
permMana.add(Mana.GreenMana(1));
if (color.isRed())
permMana.add(Mana.RedMana(1));
if (color.isWhite())
permMana.add(Mana.WhiteMana(1));
}
options.addMana(permMana);
});
options.removeDuplicated();
return options;
}
use of mage.abilities.costs.mana.ManaCost in project mage by magefree.
the class DrainPowerEffect method apply.
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
Player targetPlayer = game.getPlayer(source.getFirstTarget());
if (targetPlayer != null) {
List<Permanent> ignorePermanents = new ArrayList<>();
Map<Permanent, List<ActivatedManaAbilityImpl>> manaAbilitiesMap = new HashMap<>();
TargetPermanent target = null;
while (true) {
targetPlayer.setPayManaMode(true);
manaAbilitiesMap.clear();
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, targetPlayer.getId(), game)) {
if (!ignorePermanents.contains(permanent)) {
List<ActivatedManaAbilityImpl> manaAbilities = new ArrayList<>();
abilitySearch: for (Ability ability : permanent.getAbilities()) {
if (ability instanceof ActivatedAbility && ability.getAbilityType() == AbilityType.MANA) {
ActivatedManaAbilityImpl manaAbility = (ActivatedManaAbilityImpl) ability;
if (manaAbility.canActivate(targetPlayer.getId(), game).canActivate()) {
// so it's necessary to filter them out manually - might be buggy in some fringe cases
for (ManaCost manaCost : manaAbility.getManaCosts()) {
if (!targetPlayer.getManaPool().getMana().includesMana(manaCost.getMana())) {
continue abilitySearch;
}
}
manaAbilities.add(manaAbility);
}
}
}
if (!manaAbilities.isEmpty()) {
manaAbilitiesMap.put(permanent, manaAbilities);
}
}
}
if (manaAbilitiesMap.isEmpty()) {
break;
}
List<Permanent> permList = new ArrayList<>(manaAbilitiesMap.keySet());
Permanent permanent;
if (permList.size() > 1 || target != null) {
FilterLandPermanent filter2 = new FilterLandPermanent("land you control to tap for mana (remaining: " + permList.size() + ')');
filter2.add(new PermanentInListPredicate(permList));
target = new TargetPermanent(1, 1, filter2, true);
while (!target.isChosen() && target.canChoose(source.getSourceId(), targetPlayer.getId(), game) && targetPlayer.canRespond()) {
targetPlayer.chooseTarget(Outcome.Neutral, target, source, game);
}
permanent = game.getPermanent(target.getFirstTarget());
} else {
permanent = permList.get(0);
}
if (permanent != null) {
int i = 0;
for (ActivatedManaAbilityImpl manaAbility : manaAbilitiesMap.get(permanent)) {
i++;
if (manaAbilitiesMap.get(permanent).size() <= i || targetPlayer.chooseUse(Outcome.Neutral, "Activate mana ability \"" + manaAbility.getRule() + "\" of " + permanent.getLogName() + "? (Choose \"no\" to activate next mana ability)", source, game)) {
boolean originalCanUndo = manaAbility.isUndoPossible();
// prevents being able to undo Drain Power
manaAbility.setUndoPossible(false);
if (targetPlayer.activateAbility(manaAbility, game)) {
ignorePermanents.add(permanent);
}
// resets undoPossible to its original state
manaAbility.setUndoPossible(originalCanUndo);
break;
}
}
}
}
targetPlayer.setPayManaMode(false);
// 106.12. One card (Drain Power) causes one player to lose unspent mana and another to add “the mana lost this way.” (Note that these may be the same player.)
// This empties the former player's mana pool and causes the mana emptied this way to be put into the latter player's mana pool. Which permanents, spells, and/or
// abilities produced that mana are unchanged, as are any restrictions or additional effects associated with any of that mana.
List<ManaPoolItem> manaItems = targetPlayer.getManaPool().getManaItems();
targetPlayer.getManaPool().emptyPool(game);
for (ManaPoolItem manaPoolItem : manaItems) {
controller.getManaPool().addMana(manaPoolItem.isConditional() ? manaPoolItem.getConditionalMana() : manaPoolItem.getMana(), game, source, Duration.EndOfTurn.equals(manaPoolItem.getDuration()));
}
return true;
}
return false;
}
use of mage.abilities.costs.mana.ManaCost in project mage by magefree.
the class RiseOfTheHobgoblinsEffect method apply.
@Override
public boolean apply(Game game, Ability source) {
Player you = game.getPlayer(source.getControllerId());
ManaCosts<ManaCost> cost = new ManaCostsImpl<>("{X}");
if (you != null && you.chooseUse(Outcome.Neutral, "Do you want to to pay {X}?", source, game)) {
int costX = you.announceXMana(0, Integer.MAX_VALUE, "Announce the value for {X}", game, source);
cost.add(new GenericManaCost(costX));
if (cost.pay(source, game, source, source.getControllerId(), false, null)) {
Token token = new GoblinSoldierToken();
return token.putOntoBattlefield(costX, game, source, source.getControllerId());
}
}
return false;
}
use of mage.abilities.costs.mana.ManaCost in project mage by magefree.
the class AbilityImpl method handleManaXCosts.
/**
* Handles X mana costs and sets manaCostsToPay.
*
* @param game
* @param noMana
* @param controller
* @return variableManaCost for posting to log later
*/
protected VariableManaCost handleManaXCosts(Game game, boolean noMana, Player controller) {
// 20210723 - 601.2b
// If the spell has alternative or additional costs that will
// be paid as it’s being cast such as buyback or kicker costs (see rules 118.8 and 118.9),
// the player announces their intentions to pay any or all of those costs (see rule 601.2f).
// A player can’t apply two alternative methods of casting or two alternative costs to a
// single spell. 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. If the value of that variable is defined in the text of the spell by a choice
// that player would make later in the announcement or resolution of the spell, that player
// makes that choice at this time instead of that later time.
// TODO: Handle announcing other variable costs here like: RemoveVariableCountersSourceCost
VariableManaCost variableManaCost = null;
for (ManaCost cost : manaCostsToPay) {
if (cost instanceof VariableManaCost) {
if (variableManaCost == null) {
variableManaCost = (VariableManaCost) cost;
} else {
// only one VariableManCost per spell (or is it possible to have more?)
logger.error("Variable mana cost allowes only in one instance per ability: " + this);
}
}
}
if (variableManaCost != null) {
if (!variableManaCost.isPaid()) {
// should only happen for human players
int xValue;
int xValueMultiplier = handleManaXMultiplier(game, 1);
if (!noMana || variableManaCost.getCostType().canUseAnnounceOnFreeCast()) {
xValue = controller.announceXMana(variableManaCost.getMinX(), variableManaCost.getMaxX(), xValueMultiplier, "Announce the value for " + variableManaCost.getText(), game, this);
int amountMana = xValue * variableManaCost.getXInstancesCount();
StringBuilder manaString = threadLocalBuilder.get();
if (variableManaCost.getFilter() == null || variableManaCost.getFilter().isGeneric()) {
manaString.append('{').append(amountMana).append('}');
} else {
String manaSymbol = null;
if (variableManaCost.getFilter().isBlack()) {
if (variableManaCost.getFilter().isRed()) {
manaSymbol = "B/R";
} else {
manaSymbol = "B";
}
} else if (variableManaCost.getFilter().isRed()) {
manaSymbol = "R";
} else if (variableManaCost.getFilter().isBlue()) {
manaSymbol = "U";
} else if (variableManaCost.getFilter().isGreen()) {
manaSymbol = "G";
} else if (variableManaCost.getFilter().isWhite()) {
manaSymbol = "W";
}
if (manaSymbol == null) {
throw new UnsupportedOperationException("ManaFilter is not supported: " + this);
}
for (int i = 0; i < amountMana; i++) {
manaString.append('{').append(manaSymbol).append('}');
}
}
manaCostsToPay.add(new ManaCostsImpl(manaString.toString()));
manaCostsToPay.setX(xValue * xValueMultiplier, amountMana);
}
variableManaCost.setPaid();
}
}
return variableManaCost;
}
use of mage.abilities.costs.mana.ManaCost in project mage by magefree.
the class AbilityImpl method handlePhyrexianManaCosts.
/**
* 601.2b If a cost that will be paid as the spell is being cast includes
* Phyrexian mana symbols, the player announces whether they intend to pay 2
* life or the corresponding colored mana cost for each of those symbols.
*/
private void handlePhyrexianManaCosts(Game game, Player controller) {
Iterator<ManaCost> costIterator = manaCostsToPay.iterator();
while (costIterator.hasNext()) {
ManaCost cost = costIterator.next();
if (!cost.isPhyrexian()) {
continue;
}
PayLifeCost payLifeCost = new PayLifeCost(2);
if (payLifeCost.canPay(this, this, controller.getId(), game) && controller.chooseUse(Outcome.LoseLife, "Pay 2 life instead of " + cost.getText().replace("/P", "") + '?', this, game)) {
costIterator.remove();
costs.add(payLifeCost);
manaCostsToPay.incrPhyrexianPaid();
}
}
}
Aggregations