forked from External/mage
* apply regex to change public copy constructors to protected * cleanup code using now protected constructors * fix manaBuilder weird casting of Mana into ConditionalMana
198 lines
7.5 KiB
Java
198 lines
7.5 KiB
Java
package mage.abilities.keyword;
|
||
|
||
import java.util.UUID;
|
||
|
||
import mage.Mana;
|
||
import mage.abilities.Ability;
|
||
import mage.abilities.SpecialAction;
|
||
import mage.abilities.common.SimpleStaticAbility;
|
||
import mage.abilities.costs.Cost;
|
||
import mage.abilities.costs.mana.ActivationManaAbilityStep;
|
||
import mage.abilities.costs.mana.AlternateManaPaymentAbility;
|
||
import mage.abilities.costs.mana.ManaCost;
|
||
import mage.abilities.effects.OneShotEffect;
|
||
import mage.abilities.mana.ManaOptions;
|
||
import mage.constants.*;
|
||
import mage.filter.FilterPlayer;
|
||
import mage.game.Game;
|
||
import mage.game.stack.Spell;
|
||
import mage.players.ManaPool;
|
||
import mage.players.Player;
|
||
import mage.target.Target;
|
||
import mage.target.TargetPlayer;
|
||
import mage.util.ManaUtil;
|
||
|
||
/**
|
||
* 702.131. Assist
|
||
* <p>
|
||
* 702.131a Assist is a static ability that modifies the rules of paying for the
|
||
* spell with assist (see rules 601.2g-h). If the total cost to cast a spell
|
||
* with assist includes a generic mana component, before you activate mana
|
||
* abilities while casting it, you may choose another player. That player has a
|
||
* chance to activate mana abilities. Once that player chooses not to activate
|
||
* any more mana abilities, you have a chance to activate mana abilities. Before
|
||
* you begin to pay the total cost of the spell, the player you chose may pay
|
||
* for any amount of the generic mana in the spell’s total cost.
|
||
*
|
||
* @author emerald000, JayDi85
|
||
*/
|
||
public class AssistAbility extends SimpleStaticAbility implements AlternateManaPaymentAbility {
|
||
|
||
private static final FilterPlayer filter = new FilterPlayer("another player");
|
||
|
||
static {
|
||
filter.add(TargetController.NOT_YOU.getPlayerPredicate());
|
||
}
|
||
|
||
public AssistAbility() {
|
||
super(Zone.ALL, null);
|
||
this.setRuleAtTheTop(true);
|
||
}
|
||
|
||
protected AssistAbility(final AssistAbility ability) {
|
||
super(ability);
|
||
}
|
||
|
||
@Override
|
||
public AssistAbility copy() {
|
||
return new AssistAbility(this);
|
||
}
|
||
|
||
@Override
|
||
public String getRule() {
|
||
return "Assist <i>(Another player can help pay the generic mana of this spell's cost.)</i>";
|
||
}
|
||
|
||
@Override
|
||
public ActivationManaAbilityStep useOnActivationManaAbilityStep() {
|
||
return ActivationManaAbilityStep.BEFORE;
|
||
}
|
||
|
||
@Override
|
||
public void addSpecialAction(Ability source, Game game, ManaCost unpaid) {
|
||
Player controller = game.getPlayer(source.getControllerId());
|
||
if (controller != null
|
||
&& source.getAbilityType() == AbilityType.SPELL
|
||
&& unpaid.getMana().getGeneric() >= 1
|
||
&& game.getState().getValue(source.getSourceId().toString() + game.getState().getZoneChangeCounter(source.getSourceId()) + "_assisted") == null) {
|
||
SpecialAction specialAction = new AssistSpecialAction(unpaid, this);
|
||
specialAction.setControllerId(source.getControllerId());
|
||
specialAction.setSourceId(source.getSourceId());
|
||
Target target = new TargetPlayer(1, 1, true, filter);
|
||
specialAction.addTarget(target);
|
||
if (specialAction.canActivate(source.getControllerId(), game).canActivate()) {
|
||
game.getState().getSpecialActions().add(specialAction);
|
||
}
|
||
}
|
||
}
|
||
|
||
@Override
|
||
public ManaOptions getManaOptions(Ability source, Game game, ManaCost unpaid) {
|
||
ManaOptions options = new ManaOptions();
|
||
if (unpaid.getMana().getGeneric() == 0) {
|
||
// nothing to pay
|
||
return options;
|
||
}
|
||
|
||
// AI can't use assist (can't ask another player to help), maybe in teammode it can be enabled, but tests must works all the time
|
||
// Outcome.AIDontUseIt
|
||
Player controller = game.getPlayer(source.getControllerId());
|
||
if (controller != null && controller.isComputer()) {
|
||
return options;
|
||
}
|
||
|
||
// search opponents who can help with generic pay
|
||
int opponentCanPayMax = 0;
|
||
for (UUID opponentId : game.getOpponents(source.getControllerId())) {
|
||
Player opponent = game.getPlayer(opponentId);
|
||
if (opponent != null) {
|
||
// basic and pool, but no coditional mana
|
||
ManaOptions availableMana = opponent.getManaAvailable(game);
|
||
// availableMana.addMana(opponent.getManaPool().getMana());
|
||
for (Mana mana : availableMana) {
|
||
if (mana.count() > 0) {
|
||
opponentCanPayMax = Math.max(opponentCanPayMax, mana.count());
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if (opponentCanPayMax > 0) {
|
||
options.addMana(Mana.GenericMana(Math.min(unpaid.getMana().getGeneric(), opponentCanPayMax)));
|
||
}
|
||
|
||
return options;
|
||
}
|
||
}
|
||
|
||
class AssistSpecialAction extends SpecialAction {
|
||
|
||
AssistSpecialAction(ManaCost unpaid, AlternateManaPaymentAbility manaAbility) {
|
||
super(Zone.ALL, manaAbility);
|
||
this.abilityType = AbilityType.SPECIAL_MANA_PAYMENT;
|
||
setRuleVisible(false);
|
||
this.addEffect(new AssistEffect(unpaid));
|
||
}
|
||
|
||
AssistSpecialAction(final AssistSpecialAction ability) {
|
||
super(ability);
|
||
}
|
||
|
||
@Override
|
||
public AssistSpecialAction copy() {
|
||
return new AssistSpecialAction(this);
|
||
}
|
||
}
|
||
|
||
class AssistEffect extends OneShotEffect {
|
||
|
||
private final ManaCost unpaid;
|
||
|
||
AssistEffect(ManaCost unpaid) {
|
||
super(Outcome.Benefit);
|
||
this.unpaid = unpaid;
|
||
this.staticText = "Assist <i>(Another player can help pay the generic mana of this spell's cost.)</i>";
|
||
}
|
||
|
||
AssistEffect(final AssistEffect effect) {
|
||
super(effect);
|
||
this.unpaid = effect.unpaid;
|
||
}
|
||
|
||
@Override
|
||
public AssistEffect copy() {
|
||
return new AssistEffect(this);
|
||
}
|
||
|
||
@Override
|
||
public boolean apply(Game game, Ability source) {
|
||
Player controller = game.getPlayer(source.getControllerId());
|
||
Player targetPlayer = game.getPlayer(this.getTargetPointer().getFirst(game, source));
|
||
Spell spell = game.getStack().getSpell(source.getSourceId());
|
||
if (controller != null && spell != null && targetPlayer != null) {
|
||
// AI can't assist other players, maybe for teammates only (but tests must work as normal)
|
||
int amountToPay = 0;
|
||
if (!targetPlayer.isComputer()) {
|
||
amountToPay = targetPlayer.announceXMana(0, unpaid.getMana().getGeneric(),
|
||
"How much mana to pay as assist for " + controller.getName() + "?", game, source);
|
||
}
|
||
|
||
if (amountToPay > 0) {
|
||
Cost cost = ManaUtil.createManaCost(amountToPay, false);
|
||
if (cost.pay(source, game, source, targetPlayer.getId(), false)) {
|
||
ManaPool manaPool = controller.getManaPool();
|
||
manaPool.addMana(Mana.ColorlessMana(amountToPay), game, source);
|
||
manaPool.unlockManaType(ManaType.COLORLESS); // it's unlock mana for one use/click, but it can gives more
|
||
game.informPlayers(targetPlayer.getLogName() + " paid {" + amountToPay + "} for " + controller.getLogName());
|
||
game.getState().setValue(source.getSourceId().toString() + game.getState().getZoneChangeCounter(source.getSourceId()) + "_assisted", true);
|
||
}
|
||
|
||
// assist must be used before activating mana abilities, so no need to switch step after usage
|
||
// (mana and other special abilities can be used after assist)
|
||
//spell.setCurrentActivatingManaAbilitiesStep(ActivationManaAbilityStep.NORMAL);
|
||
}
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
}
|