* Some rework of handling of mana effects.

This commit is contained in:
LevelX2 2018-05-13 22:52:14 +02:00
parent 25b10c4d67
commit 21e5591e29
254 changed files with 1449 additions and 1399 deletions

View file

@ -42,7 +42,7 @@ import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.Effect;
import mage.abilities.effects.Effects;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DynamicManaEffect;
import mage.abilities.effects.mana.DynamicManaEffect;
import mage.abilities.effects.common.ManaEffect;
import mage.abilities.mana.ActivatedManaAbilityImpl;
import mage.cards.Card;

View file

@ -30,8 +30,8 @@ package mage.abilities.decorator;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.condition.Condition;
import mage.abilities.effects.common.BasicManaEffect;
import mage.abilities.effects.common.ManaEffect;
import mage.abilities.effects.mana.BasicManaEffect;
import mage.choices.ChoiceColor;
import mage.game.Game;
import mage.players.Player;
@ -73,31 +73,7 @@ public class ConditionalManaEffect extends ManaEffect {
if (controller == null) {
return false;
}
if (condition.apply(game, source)) {
effect.setTargetPointer(this.targetPointer);
} else if (otherwiseEffect != null) {
otherwiseEffect.setTargetPointer(this.targetPointer);
}
Mana mana = getMana(game, source);
if (mana == null) {
return false;
}
if (mana.getAny() > 0) {
int amount = mana.getAny();
ChoiceColor choice = new ChoiceColor(true);
Mana createdMana = null;
if (controller.choose(outcome, choice, game)) {
createdMana = choice.getMana(amount);
}
if (createdMana == null) {
return false;
}
mana = createdMana;
// because the mana type is now choosen, fire the event with the mana information
checkToFirePossibleEvents(mana, game, source);
}
controller.getManaPool().addMana(mana, game, source);
controller.getManaPool().addMana(getMana(game, source), game, source);
return true;
}
@ -107,12 +83,25 @@ public class ConditionalManaEffect extends ManaEffect {
}
@Override
public Mana getMana(Game game, Ability source) {
Mana mana = null;
public Mana produceMana(boolean netMana, Game game, Ability source) {
Mana mana = new Mana();
if (condition.apply(game, source)) {
mana = effect.getMana();
mana = effect.getManaTemplate().copy();
} else if (otherwiseEffect != null) {
mana = otherwiseEffect.getMana();
mana = otherwiseEffect.getManaTemplate().copy();
}
if (mana.getAny() > 0) {
int amount = mana.getAny();
Player controller = game.getPlayer(source.getControllerId());
if (controller == null) {
return mana;
}
ChoiceColor choice = new ChoiceColor(true);
if (controller.choose(outcome, choice, game)) {
mana.setAny(0);
mana.add(choice.getMana(amount));
}
checkToFirePossibleEvents(mana, game, source);
}
return mana;
}

View file

@ -48,7 +48,7 @@ public class OpponentsLostLifeCount implements DynamicValue {
public int calculate(Game game, UUID controllerId) {
PlayerLostLifeWatcher watcher = (PlayerLostLifeWatcher) game.getState().getWatchers().get(PlayerLostLifeWatcher.class.getSimpleName());
if (watcher != null) {
return watcher.getAllOppLifeLost(controllerId);
return watcher.getAllOppLifeLost(controllerId, game);
}
return 0;
}

View file

@ -1,49 +0,0 @@
package mage.abilities.effects.common;
import java.util.UUID;
import mage.Mana;
import mage.abilities.Ability;
import mage.choices.ChoiceColor;
import mage.game.Game;
import mage.players.Player;
/**
*
* Created by Galatolol
*/
public class AddManaOfAnyColorToManaPoolTargetPlayerEffect extends ManaEffect {
public AddManaOfAnyColorToManaPoolTargetPlayerEffect(String textManaPoolOwner) {
super();
this.staticText = (textManaPoolOwner.equals("their") ? "that player adds " : "add ") + "one mana of any color" + " to " + textManaPoolOwner + " mana pool";
}
public AddManaOfAnyColorToManaPoolTargetPlayerEffect(final AddManaOfAnyColorToManaPoolTargetPlayerEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
UUID playerId = (UUID) game.getState().getValue(source.getSourceId() + "_player");
Player player = game.getPlayer(playerId);
ChoiceColor choice = new ChoiceColor();
if (player != null && player.choose(outcome, choice, game)) {
Mana mana = choice.getMana(1);
checkToFirePossibleEvents(mana, game, source);
player.getManaPool().addMana(mana, game, source);
return true;
}
return false;
}
@Override
public AddManaOfAnyColorToManaPoolTargetPlayerEffect copy() {
return new AddManaOfAnyColorToManaPoolTargetPlayerEffect(this);
}
@Override
public Mana getMana(Game game, Ability source) {
return null;
}
}

View file

@ -24,10 +24,11 @@
* 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 java.util.ArrayList;
import java.util.List;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.costs.Cost;
@ -45,26 +46,72 @@ import mage.game.events.ManaEvent;
*/
public abstract class ManaEffect extends OneShotEffect {
protected Mana createdMana;
public ManaEffect() {
super(Outcome.PutManaInPool);
createdMana = null;
}
public ManaEffect(final ManaEffect effect) {
super(effect);
this.createdMana = effect.createdMana == null ? null : effect.createdMana.copy();
}
public abstract Mana getMana(Game game, Ability source);
/**
* Creates the mana the effect can produce or if that already has happened
* returns the mana the effect has created during its process of resolving
*
* @param game
* @param source
* @return
*/
public Mana getMana(Game game, Ability source) {
if (createdMana == null) {
return createdMana = produceMana(false, game, source);
}
return createdMana;
}
/**
* Only used for mana effects that decide which kind of mana is produced during resolution of the effect.
*
* Returns the currently available max mana variations the effect can
* produce
*
* @param game
* @param source
* @return
*/
public List<Mana> getNetMana(Game game, Ability source) {
List<Mana> netMana = new ArrayList<>();
Mana mana = produceMana(true, game, source);
if (mana != null) {
netMana.add(mana);
}
return netMana;
}
/**
* Produced the mana the effect can produce
*
* @param netMana true - produce the hypotetical possible mana for check of
* possible castable spells
* @param game
* @param source
* @return
*/
public abstract Mana produceMana(boolean netMana, Game game, Ability source);
/**
* Only used for mana effects that decide which kind of mana is produced
* during resolution of the effect.
*
* @param mana
* @param game
* @param source
*/
public void checkToFirePossibleEvents(Mana mana, Game game, Ability source) {
if (source.getAbilityType()==AbilityType.MANA) {
for (Cost cost: source.getCosts()) {
if (source.getAbilityType() == AbilityType.MANA) {
for (Cost cost : source.getCosts()) {
if (cost instanceof TapSourceCost) {
ManaEvent event = new ManaEvent(GameEvent.EventType.TAPPED_FOR_MANA, source.getSourceId(), source.getSourceId(), source.getControllerId(), mana);
if (!game.replaceEvent(event)) {

View file

@ -3,10 +3,11 @@
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package mage.abilities.effects.common;
package mage.abilities.effects.mana;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.effects.common.ManaEffect;
import mage.abilities.mana.builder.ConditionalManaBuilder;
import mage.game.Game;
import mage.players.Player;
@ -42,16 +43,16 @@ public class AddConditionalColorlessManaEffect extends ManaEffect {
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player != null) {
player.getManaPool().addMana(getMana(game, source), game, source);
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
controller.getManaPool().addMana(getMana(game, source), game, source);
return true;
}
return false;
}
@Override
public Mana getMana(Game game, Ability source) {
public Mana produceMana(boolean netMana, Game game, Ability source) {
return manaBuilder.setMana(Mana.ColorlessMana(amount), source, game).build();
}

View file

@ -3,10 +3,11 @@
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package mage.abilities.effects.common;
package mage.abilities.effects.mana;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.effects.common.ManaEffect;
import mage.abilities.mana.builder.ConditionalManaBuilder;
import mage.game.Game;
import mage.players.Player;
@ -49,7 +50,8 @@ public class AddConditionalManaEffect extends ManaEffect {
}
@Override
public Mana getMana(Game game, Ability source) {
public Mana produceMana(boolean netMana, Game game, Ability source) {
return manaBuilder.setMana(mana, source, game).build();
}
}

View file

@ -25,12 +25,14 @@
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.abilities.effects.common;
package mage.abilities.effects.mana;
import mage.ConditionalMana;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.common.ManaEffect;
import mage.abilities.mana.builder.ConditionalManaBuilder;
import mage.choices.ChoiceColor;
import mage.game.Game;
@ -84,39 +86,44 @@ public class AddConditionalManaOfAnyColorEffect extends ManaEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller == null) {
return false;
if (controller != null) {
checkToFirePossibleEvents(getMana(game, source), game, source);
controller.getManaPool().addMana(getMana(game, source), game, source);
return true;
}
return false;
}
@Override
public Mana produceMana(boolean netMana, Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller == null) {
return null;
}
ConditionalMana mana = null;
int value = amount.calculate(game, source, this);
boolean result = false;
ChoiceColor choice = new ChoiceColor(true);
for (int i = 0; i < value; i++) {
controller.choose(outcome, choice, game);
if (choice.getChoice() == null) {
return false;
controller.choose(outcome, choice, game);
}
Mana mana = choice.getMana(1);
if (mana != null) {
mana = manaBuilder.setMana(mana, source, game).build();
if (choice.getChoice() == null) {
return null;
}
if (mana != null) {
checkToFirePossibleEvents(mana, game, source);
controller.getManaPool().addMana(mana, game, source);
result = true;
}
if (!oneChoice) {
if (oneChoice) {
mana = new ConditionalMana(manaBuilder.setMana(choice.getMana(value), source, game).build());
break;
} else {
if (mana == null) {
mana = new ConditionalMana(manaBuilder.setMana(choice.getMana(1), source, game).build());
} else {
mana.add(choice.getMana(1));
}
choice.clearChoice();
}
}
return result;
}
return mana;
@Override
public Mana getMana(Game game, Ability source) {
//TODO: TAP_FOR_MANA Event does not support currently to get an amount > 1 of conditional mana
return null;
}
}

View file

@ -25,10 +25,13 @@
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.abilities.effects.common;
package mage.abilities.effects.mana;
import java.util.ArrayList;
import java.util.List;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.effects.common.ManaEffect;
import mage.choices.ChoiceColor;
import mage.game.Game;
import mage.game.permanent.Permanent;
@ -53,14 +56,12 @@ public class AddManaAnyColorAttachedControllerEffect extends ManaEffect {
public boolean apply(Game game, Ability source) {
Permanent enchantment = game.getPermanent(source.getSourceId());
if (enchantment != null) {
Permanent land = game.getPermanent(enchantment.getAttachedTo());
if (land != null) {
Player player = game.getPlayer(land.getControllerId());
ChoiceColor choice = new ChoiceColor();
if (player != null && player.choose(outcome, choice, game)) {
Mana mana = choice.getMana(1);
checkToFirePossibleEvents(mana, game, source);
player.getManaPool().addMana(mana, game, source);
Permanent permanentattachedTo = game.getPermanent(enchantment.getAttachedTo());
if (permanentattachedTo != null) {
Player player = game.getPlayer(permanentattachedTo.getControllerId());
if (player != null) {
checkToFirePossibleEvents(getMana(game, source), game, source);
player.getManaPool().addMana(getMana(game, source), game, source);
return true;
}
}
@ -74,8 +75,30 @@ public class AddManaAnyColorAttachedControllerEffect extends ManaEffect {
}
@Override
public Mana getMana(Game game, Ability source) {
return null;
public Mana produceMana(boolean netMana, Game game, Ability source) {
Permanent enchantment = game.getPermanent(source.getSourceId());
if (enchantment != null) {
Permanent land = game.getPermanent(enchantment.getAttachedTo());
if (land != null) {
Player player = game.getPlayer(land.getControllerId());
ChoiceColor choice = new ChoiceColor();
if (player != null && player.choose(outcome, choice, game)) {
return choice.getMana(1);
}
}
}
return new Mana();
}
@Override
public List<Mana> getNetMana(Game game, Ability source) {
ArrayList<Mana> netMana = new ArrayList<>();
netMana.add(Mana.GreenMana(1));
netMana.add(Mana.WhiteMana(1));
netMana.add(Mana.BlueMana(1));
netMana.add(Mana.RedMana(1));
netMana.add(Mana.BlackMana(1));
return netMana;
}
}

View file

@ -0,0 +1,54 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package mage.abilities.effects.mana;
import mage.Mana;
import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.effects.common.ManaEffect;
import mage.constants.ColoredManaSymbol;
import mage.game.Game;
import mage.players.Player;
/**
*
* @author LevelX2
*/
public class AddManaChosenColorEffect extends ManaEffect {
public AddManaChosenColorEffect() {
super();
staticText = "Add one mana of the chosen color";
}
public AddManaChosenColorEffect(final AddManaChosenColorEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player != null) {
player.getManaPool().addMana(getMana(game, source), game, source);
}
return true;
}
@Override
public Mana produceMana(boolean netMana, Game game, Ability source) {
ObjectColor color = (ObjectColor) game.getState().getValue(source.getSourceId() + "_color");
if (color != null) {
return new Mana(ColoredManaSymbol.lookup(color.toString().charAt(0)));
} else {
return null;
}
}
@Override
public AddManaChosenColorEffect copy() {
return new AddManaChosenColorEffect(this);
}
}

View file

@ -25,14 +25,16 @@
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.abilities.effects.common;
package mage.abilities.effects.mana;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.common.ManaEffect;
import mage.constants.ColoredManaSymbol;
import mage.game.Game;
import mage.players.Player;
@ -90,6 +92,17 @@ public class AddManaInAnyCombinationEffect extends ManaEffect {
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player != null) {
checkToFirePossibleEvents(getMana(game, source), game, source);
player.getManaPool().addMana(getMana(game, source), game, source);
return true;
}
return false;
}
@Override
public Mana produceMana(boolean netMana, Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player != null) {
Mana mana = new Mana();
@ -111,16 +124,17 @@ public class AddManaInAnyCombinationEffect extends ManaEffect {
}
}
}
checkToFirePossibleEvents(mana, game, source);
player.getManaPool().addMana(mana, game, source);
return true;
return mana;
}
return false;
return null;
}
@Override
public Mana getMana(Game game, Ability source) {
return null;
public List<Mana> getNetMana(Game game, Ability source) {
ArrayList<Mana> netMana = new ArrayList<>();
netMana.add(new Mana(0, 0, 0, 0, 0, 0, amount.calculate(game, source, this), 0));
return netMana;
}
private String setText() {

View file

@ -25,7 +25,7 @@
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.abilities.effects.common;
package mage.abilities.effects.mana;
import mage.Mana;
import mage.abilities.Ability;
@ -91,7 +91,7 @@ public class AddManaOfAnyColorEffect extends BasicManaEffect {
}
@Override
public Mana getMana() {
public Mana getManaTemplate() {
return new Mana(0, 0, 0, 0, 0, 0, amount, 0);
}

View file

@ -25,10 +25,11 @@
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.abilities.effects.common;
package mage.abilities.effects.mana;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.effects.common.ManaEffect;
import mage.choices.Choice;
import mage.choices.ChoiceColor;
import mage.game.Game;
@ -58,6 +59,24 @@ public class AddManaOfAnyTypeProducedEffect extends ManaEffect {
if (targetController == null) {
return false;
}
checkToFirePossibleEvents(getMana(game, source), game, source);
targetController.getManaPool().addMana(getMana(game, source), game, source);
return true;
}
return false;
}
@Override
public Mana produceMana(boolean netMana, Game game, Ability source) {
if (netMana) {
return null;
}
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
if (permanent != null) {
Player targetController = game.getPlayer(permanent.getControllerId());
if (targetController == null) {
return null;
}
Mana types = (Mana) this.getValue("mana");
Choice choice = new ChoiceColor(true);
choice.getChoices().clear();
@ -80,15 +99,16 @@ public class AddManaOfAnyTypeProducedEffect extends ManaEffect {
if (types.getColorless() > 0) {
choice.getChoices().add("Colorless");
}
Mana newMana = new Mana();
if (!choice.getChoices().isEmpty()) {
if (choice.getChoices().size() == 1) {
choice.setChoice(choice.getChoices().iterator().next());
} else {
if (!targetController.choose(outcome, choice, game)) {
return false;
return null;
}
}
Mana newMana = new Mana();
switch (choice.getChoice()) {
case "Black":
newMana.setBlack(1);
@ -109,13 +129,10 @@ public class AddManaOfAnyTypeProducedEffect extends ManaEffect {
newMana.setColorless(1);
break;
}
checkToFirePossibleEvents(newMana, game, source);
targetController.getManaPool().addMana(newMana, game, source);
}
return true;
return newMana;
}
return false;
return null;
}
@Override
@ -123,8 +140,4 @@ public class AddManaOfAnyTypeProducedEffect extends ManaEffect {
return new AddManaOfAnyTypeProducedEffect(this);
}
@Override
public Mana getMana(Game game, Ability source) {
return null;
}
}

View file

@ -4,7 +4,7 @@
* and open the template in the editor.
*/
package mage.abilities.effects.common;
package mage.abilities.effects.mana;
import mage.Mana;
import mage.abilities.Ability;

View file

@ -3,11 +3,11 @@
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package mage.abilities.effects.common;
package mage.abilities.effects.mana;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.effects.common.ManaEffect;
import mage.game.Game;
import mage.players.Player;
@ -15,28 +15,30 @@ import mage.players.Player;
*
* @author LevelX2
*/
public class AddManaToManaPoolTargetControllerEffect extends ManaEffect {
protected Mana mana;
protected boolean emptyOnlyOnTurnsEnd;
public AddManaToManaPoolTargetControllerEffect(Mana mana, String textManaPoolOwner) {
this(mana, textManaPoolOwner, false);
}
/**
* Adds mana to the mana pool of target pointer player
*
*
* @param mana mana that will be added to the pool
* @param textManaPoolOwner text that references to the mana pool owner (e.g. "damaged player's")
* @param emptyOnTurnsEnd if set, the mana will empty only on end of turnstep
*
*/
* @param textManaPoolOwner text that references to the mana pool owner
* (e.g. "damaged player's")
* @param emptyOnTurnsEnd if set, the mana will empty only on end of
* turnstep
*
*/
public AddManaToManaPoolTargetControllerEffect(Mana mana, String textManaPoolOwner, boolean emptyOnTurnsEnd) {
super();
this.mana = mana;
this.emptyOnlyOnTurnsEnd = emptyOnTurnsEnd;
this.staticText = (textManaPoolOwner.equals("their")?"that player adds ":"add ") + mana.toString() + " to " + textManaPoolOwner + " mana pool";
this.staticText = (textManaPoolOwner.equals("their") ? "that player adds " : "add ") + mana.toString() + " to " + textManaPoolOwner + " mana pool";
}
public AddManaToManaPoolTargetControllerEffect(final AddManaToManaPoolTargetControllerEffect effect) {
@ -54,15 +56,17 @@ public class AddManaToManaPoolTargetControllerEffect extends ManaEffect {
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(getTargetPointer().getFirst(game, source));
if (player != null) {
player.getManaPool().addMana(mana, game, source, emptyOnlyOnTurnsEnd);
player.getManaPool().addMana(getMana(game, source), game, source, emptyOnlyOnTurnsEnd);
return true;
}
return false;
}
@Override
public Mana getMana(Game game, Ability source) {
return mana;
public Mana produceMana(boolean netMana, Game game, Ability source) {
if (netMana) {
return null;
}
return mana.copy();
}
}

View file

@ -1,29 +1,31 @@
package mage.abilities.effects.common;
package mage.abilities.effects.mana;
import mage.ConditionalMana;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.effects.common.ManaEffect;
import mage.game.Game;
public class BasicManaEffect extends ManaEffect {
protected Mana mana;
protected Mana manaTemplate;
public BasicManaEffect(Mana mana) {
super();
this.mana = mana;
this.manaTemplate = mana;
staticText = "add " + mana.toString();
}
public BasicManaEffect(ConditionalMana conditionalMana) {
super();
this.mana = conditionalMana;
staticText = "add " + mana.toString() + " " + conditionalMana.getDescription();
this.manaTemplate = conditionalMana;
staticText = "add " + manaTemplate.toString() + " " + conditionalMana.getDescription();
}
public BasicManaEffect(final BasicManaEffect effect) {
super(effect);
this.mana = effect.mana.copy();
this.manaTemplate = effect.manaTemplate.copy();
}
@Override
@ -33,16 +35,17 @@ public class BasicManaEffect extends ManaEffect {
@Override
public boolean apply(Game game, Ability source) {
game.getPlayer(source.getControllerId()).getManaPool().addMana(mana, game, source);
game.getPlayer(source.getControllerId()).getManaPool().addMana(getMana(game, source), game, source);
return true;
}
public Mana getMana() {
return mana;
public Mana getManaTemplate() {
return manaTemplate;
}
@Override
public Mana getMana(Game game, Ability source) {
return mana;
public Mana produceMana(boolean netMana, Game game, Ability source) {
return manaTemplate.copy();
}
}

View file

@ -3,14 +3,17 @@
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package mage.abilities.effects.common;
package mage.abilities.effects.mana;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import mage.MageObject;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.costs.Cost;
import mage.abilities.effects.common.ManaEffect;
import mage.constants.Outcome;
import mage.game.Game;
import mage.players.Player;
@ -69,6 +72,24 @@ public class DoUnlessAnyPlayerPaysManaEffect extends ManaEffect {
return false;
}
@Override
public List<Mana> getNetMana(Game game, Ability source) {
if (cost.canPay(source, source.getSourceId(), source.getControllerId(), game)) {
return manaEffect.getNetMana(game, source);
}
return new ArrayList<>();
}
@Override
public Mana getMana(Game game, Ability source) {
return manaEffect.getMana(game, source);
}
@Override
public Mana produceMana(boolean netMana, Game game, Ability source) {
return manaEffect.produceMana(netMana, game, source);
}
protected Player getPayingPlayer(Game game, Ability source) {
return game.getPlayer(source.getControllerId());
}
@ -81,11 +102,6 @@ public class DoUnlessAnyPlayerPaysManaEffect extends ManaEffect {
return manaEffect.getText(mode) + " unless any player pays " + cost.getText();
}
@Override
public Mana getMana(Game game, Ability source) {
return manaEffect.getMana(game, source);
}
@Override
public ManaEffect copy() {
return new DoUnlessAnyPlayerPaysManaEffect(this);

View file

@ -25,7 +25,7 @@
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.abilities.effects.common;
package mage.abilities.effects.mana;
import mage.Mana;
import mage.abilities.Ability;
@ -64,10 +64,10 @@ public class DynamicManaEffect extends BasicManaEffect {
* @param mana
* @param amount
* @param text
* @param oneChoice is all mana from the same colour or if false the player
* can choose different colours
* @param oneChoice is all manaTemplate from the same colour or if false the
* player can choose different colours
* @param netAmount a dynamic value that calculates the possible available
* mana (e.g. if you have to pay by removing counters from source)
* manaTemplate (e.g. if you have to pay by removing counters from source)
*/
public DynamicManaEffect(Mana mana, DynamicValue amount, String text, boolean oneChoice, DynamicValue netAmount) {
super(mana);
@ -96,9 +96,8 @@ public class DynamicManaEffect extends BasicManaEffect {
@Override
public boolean apply(Game game, Ability source) {
Mana computedMana = computeMana(false, game, source);
checkToFirePossibleEvents(computedMana, game, source);
game.getPlayer(source.getControllerId()).getManaPool().addMana(computedMana, game, source);
checkToFirePossibleEvents(getMana(game, source), game, source);
game.getPlayer(source.getControllerId()).getManaPool().addMana(getMana(game, source), game, source);
return true;
}
@ -111,33 +110,29 @@ public class DynamicManaEffect extends BasicManaEffect {
}
@Override
public Mana getMana(Game game, Ability source) {
return null;
}
public Mana computeMana(boolean netMana, Game game, Ability source) {
public Mana produceMana(boolean netMana, Game game, Ability source) {
Mana computedMana = new Mana();
int count;
if (netMana && netAmount != null) {
// calculate the maximum available mana
// calculate the maximum available manaTemplate
count = netAmount.calculate(game, source, this);
} else {
count = amount.calculate(game, source, this);
}
if (mana.getBlack() > 0) {
if (manaTemplate.getBlack() > 0) {
computedMana.setBlack(count);
} else if (mana.getBlue() > 0) {
} else if (manaTemplate.getBlue() > 0) {
computedMana.setBlue(count);
} else if (mana.getGreen() > 0) {
} else if (manaTemplate.getGreen() > 0) {
computedMana.setGreen(count);
} else if (mana.getRed() > 0) {
} else if (manaTemplate.getRed() > 0) {
computedMana.setRed(count);
} else if (mana.getWhite() > 0) {
} else if (manaTemplate.getWhite() > 0) {
computedMana.setWhite(count);
} else if (mana.getColorless() > 0) {
} else if (manaTemplate.getColorless() > 0) {
computedMana.setColorless(count);
} else if (mana.getAny() > 0) {
} else if (manaTemplate.getAny() > 0) {
if (netMana) {
computedMana.setAny(count);
} else {

View file

@ -29,8 +29,8 @@ package mage.abilities.mana;
import mage.abilities.condition.Condition;
import mage.abilities.costs.Cost;
import mage.abilities.effects.common.AddConditionalColorlessManaEffect;
import mage.abilities.effects.common.BasicManaEffect;
import mage.abilities.effects.mana.AddConditionalColorlessManaEffect;
import mage.abilities.effects.mana.BasicManaEffect;
import mage.constants.Zone;
import mage.game.Game;
@ -38,7 +38,7 @@ public class ActivateIfConditionManaAbility extends ActivatedManaAbilityImpl {
public ActivateIfConditionManaAbility(Zone zone, BasicManaEffect effect, Cost cost, Condition condition) {
super(zone, effect, cost);
this.netMana.add(effect.getMana());
this.netMana.add(effect.getManaTemplate());
this.condition = condition;
}

View file

@ -29,8 +29,8 @@ package mage.abilities.mana;
import mage.Mana;
import mage.abilities.costs.Cost;
import mage.abilities.effects.common.AddManaOfAnyColorEffect;
import mage.abilities.effects.common.BasicManaEffect;
import mage.abilities.effects.mana.AddManaOfAnyColorEffect;
import mage.abilities.effects.mana.BasicManaEffect;
import mage.constants.Zone;
import mage.game.Game;
@ -42,7 +42,7 @@ public class ActivateOncePerTurnManaAbility extends ActivatedManaAbilityImpl {
public ActivateOncePerTurnManaAbility(Zone zone, BasicManaEffect effect, Cost cost) {
super(zone, effect, cost);
this.netMana.add(effect.getMana());
this.netMana.add(effect.getManaTemplate());
this.maxActivationsPerTurn = 1;
}

View file

@ -33,6 +33,7 @@ import java.util.UUID;
import mage.Mana;
import mage.abilities.ActivatedAbilityImpl;
import mage.abilities.costs.Cost;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.ManaEffect;
import mage.constants.AbilityType;
import mage.constants.AsThoughEffectType;
@ -95,6 +96,13 @@ public abstract class ActivatedManaAbilityImpl extends ActivatedAbilityImpl impl
*/
@Override
public List<Mana> getNetMana(Game game) {
if (netMana.isEmpty()) {
for (Effect effect : getEffects()) {
if (effect instanceof ManaEffect) {
netMana.addAll(((ManaEffect) effect).getNetMana(game, this));
}
}
}
return netMana;
}

View file

@ -105,6 +105,18 @@ class AnyColorLandsProduceManaEffect extends ManaEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
checkToFirePossibleEvents(getMana(game, source), game, source);
controller.getManaPool().addMana(getMana(game, source), game, source);
return true;
}
return false;
}
@Override
public Mana produceMana(boolean netMana, Game game, Ability source) {
Mana mana = new Mana();
Mana types = getManaTypes(game, source);
Choice choice = new ChoiceColor(true);
choice.getChoices().clear();
@ -143,12 +155,11 @@ class AnyColorLandsProduceManaEffect extends ManaEffect {
if (choice.getChoices().size() == 1) {
choice.setChoice(choice.getChoices().iterator().next());
} else {
if (!player.choose(outcome, choice, game)) {
return false;
if (player == null || !player.choose(outcome, choice, game)) {
return null;
}
}
if (choice.getChoice() != null) {
Mana mana = new Mana();
switch (choice.getChoice()) {
case "Black":
mana.setBlack(1);
@ -169,16 +180,9 @@ class AnyColorLandsProduceManaEffect extends ManaEffect {
mana.setColorless(1);
break;
}
checkToFirePossibleEvents(mana, game, source);
player.getManaPool().addMana(mana, game, source);
}
}
return true;
}
@Override
public Mana getMana(Game game, Ability source) {
return null;
return mana;
}
private Mana getManaTypes(Game game, Ability source) {
@ -205,6 +209,7 @@ class AnyColorLandsProduceManaEffect extends ManaEffect {
return types;
}
@Override
public List<Mana> getNetMana(Game game, Ability source) {
List<Mana> netManas = new ArrayList<>();
Mana types = getManaTypes(game, source);

View file

@ -30,7 +30,7 @@ package mage.abilities.mana;
import mage.Mana;
import mage.abilities.costs.Cost;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.effects.common.AddManaOfAnyColorEffect;
import mage.abilities.effects.mana.AddManaOfAnyColorEffect;
import mage.constants.Zone;
public class AnyColorManaAbility extends ActivatedManaAbilityImpl {

View file

@ -82,6 +82,18 @@ class AnyColorPermanentTypesManaEffect extends ManaEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
checkToFirePossibleEvents(getMana(game, source), game, source);
controller.getManaPool().addMana(getMana(game, source), game, source);
return true;
}
return false;
}
@Override
public Mana produceMana(boolean netMana, Game game, Ability source) {
Mana mana = new Mana();
Mana types = getManaTypes(game, source);
Choice choice = new ChoiceColor(true);
choice.getChoices().clear();
@ -121,11 +133,11 @@ class AnyColorPermanentTypesManaEffect extends ManaEffect {
choice.setChoice(choice.getChoices().iterator().next());
} else {
if (!player.choose(outcome, choice, game)) {
return false;
return mana;
}
}
if (choice.getChoice() != null) {
Mana mana = new Mana();
switch (choice.getChoice()) {
case "Black":
mana.setBlack(1);
@ -146,16 +158,9 @@ class AnyColorPermanentTypesManaEffect extends ManaEffect {
mana.setColorless(1);
break;
}
checkToFirePossibleEvents(mana, game, source);
player.getManaPool().addMana(mana, game, source);
}
}
return true;
}
@Override
public Mana getMana(Game game, Ability source) {
return null;
return mana;
}
private Mana getManaTypes(Game game, Ability source) {
@ -167,18 +172,18 @@ class AnyColorPermanentTypesManaEffect extends ManaEffect {
return types;
}
inManaTypeCalculation = true;
ObjectColor permanentColor;
List<Permanent> permanents = game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game);
for (Permanent permanent : permanents) {
permanentColor = permanent.getColor(game);
if(permanentColor.isColorless())
if (permanentColor.isColorless()) {
types.add(Mana.ColorlessMana(1));
else{
} else {
List<ObjectColor> permanentColors = permanent.getColor(game).getColors();
for (ObjectColor color : permanentColors){
for (ObjectColor color : permanentColors) {
types.add(new Mana(color.getOneColoredManaSymbol()));
}
}
@ -187,6 +192,7 @@ class AnyColorPermanentTypesManaEffect extends ManaEffect {
return types;
}
@Override
public List<Mana> getNetMana(Game game, Ability source) {
List<Mana> netManas = new ArrayList<>();
Mana types = getManaTypes(game, source);

View file

@ -29,7 +29,7 @@
package mage.abilities.mana;
import mage.Mana;
import mage.abilities.effects.common.BasicManaEffect;
import mage.abilities.effects.mana.BasicManaEffect;
import mage.constants.ColoredManaSymbol;
/**

View file

@ -29,7 +29,7 @@
package mage.abilities.mana;
import mage.Mana;
import mage.abilities.effects.common.BasicManaEffect;
import mage.abilities.effects.mana.BasicManaEffect;
import mage.constants.ColoredManaSymbol;
/**

View file

@ -28,7 +28,7 @@
package mage.abilities.mana;
import mage.Mana;
import mage.abilities.effects.common.BasicManaEffect;
import mage.abilities.effects.mana.BasicManaEffect;
/**
*

View file

@ -122,6 +122,18 @@ class CommanderIdentityManaEffect extends ManaEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
checkToFirePossibleEvents(getMana(game, source), game, source);
controller.getManaPool().addMana(getMana(game, source), game, source);
return true;
}
return false;
}
@Override
public Mana produceMana(boolean netMana, Game game, Ability source) {
Mana mana = new Mana();
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
Choice choice = new ChoiceImpl();
@ -152,10 +164,10 @@ class CommanderIdentityManaEffect extends ManaEffect {
choice.setChoice(choice.getChoices().iterator().next());
} else {
if (!controller.choose(outcome, choice, game)) {
return false;
return mana;
}
}
Mana mana = new Mana();
switch (choice.getChoice()) {
case "Black":
mana.setBlack(1);
@ -173,16 +185,10 @@ class CommanderIdentityManaEffect extends ManaEffect {
mana.setWhite(1);
break;
}
checkToFirePossibleEvents(mana, game, source);
controller.getManaPool().addMana(mana, game, source);
return true;
}
}
return false;
return mana;
}
@Override
public Mana getMana(Game game, Ability source) {
return null;
}
}

View file

@ -33,7 +33,7 @@ import mage.abilities.costs.Cost;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.common.AddConditionalManaOfAnyColorEffect;
import mage.abilities.effects.mana.AddConditionalManaOfAnyColorEffect;
import mage.abilities.mana.builder.ConditionalManaBuilder;
import mage.constants.Zone;
import mage.game.Game;

View file

@ -8,7 +8,7 @@ package mage.abilities.mana;
import mage.Mana;
import mage.abilities.costs.Cost;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.effects.common.AddConditionalManaEffect;
import mage.abilities.effects.mana.AddConditionalManaEffect;
import mage.abilities.mana.builder.ConditionalManaBuilder;
import mage.constants.Zone;

View file

@ -8,7 +8,7 @@ package mage.abilities.mana;
import mage.Mana;
import mage.abilities.costs.Cost;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.effects.common.AddConditionalColorlessManaEffect;
import mage.abilities.effects.mana.AddConditionalColorlessManaEffect;
import mage.abilities.mana.builder.ConditionalManaBuilder;
import mage.constants.Zone;

View file

@ -33,7 +33,7 @@ import mage.Mana;
import mage.abilities.costs.Cost;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.effects.common.DynamicManaEffect;
import mage.abilities.effects.mana.DynamicManaEffect;
import mage.constants.Zone;
import mage.game.Game;
@ -111,7 +111,7 @@ public class DynamicManaAbility extends ActivatedManaAbilityImpl {
if (game != null) {
// TODO: effects from replacement effects like Mana Reflection are not considered yet
// TODO: effects that need a X payment (e.g. Mage-Ring Network) return always 0
newNetMana.add(manaEffect.computeMana(true, game, this));
newNetMana.addAll(manaEffect.getNetMana(game, this));
}
return newNetMana;
}

View file

@ -29,7 +29,7 @@
package mage.abilities.mana;
import mage.Mana;
import mage.abilities.effects.common.BasicManaEffect;
import mage.abilities.effects.mana.BasicManaEffect;
import mage.constants.ColoredManaSymbol;
/**

View file

@ -29,7 +29,7 @@
package mage.abilities.mana;
import mage.Mana;
import mage.abilities.effects.common.BasicManaEffect;
import mage.abilities.effects.mana.BasicManaEffect;
import mage.constants.ColoredManaSymbol;
/**

View file

@ -30,9 +30,8 @@ package mage.abilities.mana;
import java.util.List;
import mage.Mana;
import mage.abilities.costs.Cost;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.BasicManaEffect;
import mage.abilities.effects.common.ManaEffect;
import mage.abilities.effects.mana.BasicManaEffect;
import mage.constants.Zone;
import mage.game.Game;
@ -79,15 +78,8 @@ public class SimpleManaAbility extends ActivatedManaAbilityImpl {
@Override
public List<Mana> getNetMana(Game game) {
if (netMana.isEmpty() && predictable) {
for (Effect effect : getEffects()) {
if (effect instanceof ManaEffect) {
Mana effectMana = ((ManaEffect) effect).getMana(game, this);
if (effectMana != null) {
netMana.add(effectMana);
}
}
}
if (predictable) {
return super.getNetMana(game);
}
return netMana;
}

View file

@ -32,7 +32,6 @@ import java.util.List;
import mage.Mana;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DynamicManaEffect;
import mage.abilities.effects.common.ManaEffect;
import mage.constants.AbilityType;
import mage.constants.Zone;
@ -72,20 +71,14 @@ public abstract class TriggeredManaAbility extends TriggeredAbilityImpl implemen
*/
@Override
public List<Mana> getNetMana(Game game) {
if (!getEffects().isEmpty()) {
Effect effect = getEffects().get(0);
if (effect != null && game != null) {
ArrayList<Mana> newNetMana = new ArrayList<>();
if (effect instanceof DynamicManaEffect) {
// TODO: effects from replacement effects like Mana Reflection are not considered yet
// TODO: effects that need a X payment (e.g. Mage-Ring Network) return always 0
newNetMana.add(((DynamicManaEffect) effect).computeMana(true, game, this));
} else if (effect instanceof Effect) {
newNetMana.add(((ManaEffect) effect).getMana(game, this));
if (game != null) {
ArrayList<Mana> newNetMana = new ArrayList<>();
for (Effect effect : getEffects()) {
if (effect instanceof ManaEffect) {
newNetMana.addAll(((ManaEffect) effect).getNetMana(game, this));
}
return newNetMana;
}
return newNetMana;
}
return netMana;
}

View file

@ -29,7 +29,7 @@
package mage.abilities.mana;
import mage.Mana;
import mage.abilities.effects.common.BasicManaEffect;
import mage.abilities.effects.mana.BasicManaEffect;
import mage.constants.ColoredManaSymbol;
/**

View file

@ -12,6 +12,7 @@ import mage.constants.TargetController;
import mage.filter.common.*;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.filter.predicate.mageobject.MulticoloredPredicate;
import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.filter.predicate.mageobject.SupertypePredicate;
import mage.filter.predicate.permanent.AnotherPredicate;
@ -377,10 +378,18 @@ public final class StaticFilters {
static {
FILTER_SPELL.setLockedFilter(true);
}
public static final FilterSpell FILTER_A_SPELL = new FilterSpell("a spell");
public static final FilterSpell FILTER_SPELL_A = new FilterSpell("a spell");
static {
FILTER_A_SPELL.setLockedFilter(true);
FILTER_SPELL_A.setLockedFilter(true);
}
public static final FilterSpell FILTER_SPELL_A_MULTICOLORED = new FilterSpell("a multicolored spell");
static {
FILTER_SPELL_A_MULTICOLORED.add(new MulticoloredPredicate());
FILTER_SPELL_A_MULTICOLORED.setLockedFilter(true);
}
public static final FilterSpell FILTER_INSTANT_OR_SORCERY_SPELL = new FilterSpell("instant or sorcery spell");

View file

@ -1386,7 +1386,7 @@ public abstract class GameImpl implements Game, Serializable {
} catch (Exception ex) {
logger.fatal("Game exception gameId: " + getId(), ex);
if ((ex instanceof NullPointerException)
&& errorContinueCounter == 1 && ex.getStackTrace() != null) {
&& errorContinueCounter == 0 && ex.getStackTrace() != null) {
logger.fatal(ex.getStackTrace());
}
this.fireErrorEvent("Game exception occurred: ", ex);

View file

@ -31,7 +31,7 @@ import mage.constants.CardType;
import mage.abilities.Ability;
import mage.abilities.costs.common.SacrificeSourceCost;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.effects.common.AddManaOfAnyColorEffect;
import mage.abilities.effects.mana.AddManaOfAnyColorEffect;
import mage.abilities.mana.SimpleManaAbility;
import mage.constants.Zone;

View file

@ -32,7 +32,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import mage.abilities.costs.common.SacrificeSourceCost;
import mage.abilities.effects.common.AddManaOfAnyColorEffect;
import mage.abilities.effects.mana.AddManaOfAnyColorEffect;
import mage.abilities.mana.SimpleManaAbility;
import mage.constants.CardType;
import mage.constants.Zone;

View file

@ -33,7 +33,7 @@ import java.util.List;
import mage.abilities.Ability;
import mage.abilities.costs.common.SacrificeSourceCost;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.effects.common.AddManaOfAnyColorEffect;
import mage.abilities.effects.mana.AddManaOfAnyColorEffect;
import mage.abilities.mana.SimpleManaAbility;
import mage.constants.CardType;
import mage.constants.SubType;

View file

@ -78,11 +78,11 @@ public class PlayerLostLifeWatcher extends Watcher {
return amountOfLifeLostThisTurn.getOrDefault(playerId, 0);
}
public int getAllOppLifeLost(UUID playerId) {
public int getAllOppLifeLost(UUID playerId, Game game) {
int amount = 0;
for (UUID player : this.amountOfLifeLostThisTurn.keySet()) {
if (!player.equals(playerId)) {
amount += this.amountOfLifeLostThisTurn.get(player);
for (UUID opponentId : this.amountOfLifeLostThisTurn.keySet()) {
if (game.getOpponents(playerId).contains(opponentId)) {
amount += this.amountOfLifeLostThisTurn.get(playerId);
}
}
return amount;