mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 11:48:02 +00:00
last call to gui eliminated in game code, will try to extract module next
This commit is contained in:
2
.gitattributes
vendored
2
.gitattributes
vendored
@@ -15132,7 +15132,6 @@ forge-gui/src/main/java/forge/game/spellability/AbilityManaPart.java svneol=nati
|
||||
forge-gui/src/main/java/forge/game/spellability/AbilityStatic.java svneol=native#text/plain
|
||||
forge-gui/src/main/java/forge/game/spellability/AbilitySub.java svneol=native#text/plain
|
||||
forge-gui/src/main/java/forge/game/spellability/AbilityTriggered.java svneol=native#text/plain
|
||||
forge-gui/src/main/java/forge/game/spellability/HumanPlaySpellAbility.java svneol=native#text/plain
|
||||
forge-gui/src/main/java/forge/game/spellability/ISpellAbility.java -text
|
||||
forge-gui/src/main/java/forge/game/spellability/OptionalCost.java -text
|
||||
forge-gui/src/main/java/forge/game/spellability/Spell.java svneol=native#text/plain
|
||||
@@ -15448,6 +15447,7 @@ forge-gui/src/main/java/forge/gui/menus/MenuUtil.java -text
|
||||
forge-gui/src/main/java/forge/gui/package-info.java svneol=native#text/plain
|
||||
forge-gui/src/main/java/forge/gui/player/HumanCostDecision.java -text
|
||||
forge-gui/src/main/java/forge/gui/player/HumanPlay.java -text
|
||||
forge-gui/src/main/java/forge/gui/player/HumanPlaySpellAbility.java -text
|
||||
forge-gui/src/main/java/forge/gui/player/LobbyPlayerHuman.java -text
|
||||
forge-gui/src/main/java/forge/gui/player/PlayerControllerHuman.java -text
|
||||
forge-gui/src/main/java/forge/gui/player/TargetSelection.java svneol=native#text/plain
|
||||
|
||||
@@ -20,7 +20,6 @@ import forge.game.spellability.AbilityManaPart;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.spellability.TargetRestrictions;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.gui.GuiChoose;
|
||||
|
||||
public class ManaEffect extends SpellAbilityEffect {
|
||||
|
||||
@@ -50,33 +49,31 @@ public class ManaEffect extends SpellAbilityEffect {
|
||||
if (activator.isHuman()) {
|
||||
//String colorsNeeded = abMana.getExpressChoice();
|
||||
String[] colorsProduced = abMana.getComboColors().split(" ");
|
||||
|
||||
|
||||
final StringBuilder choiceString = new StringBuilder();
|
||||
List<String> colorMenu = null;
|
||||
ColorSet colorOptions = null;
|
||||
if (!abMana.isAnyMana()) {
|
||||
colorMenu = new ArrayList<String>();
|
||||
//loop through colors to make menu
|
||||
for (int nColor = 0; nColor < colorsProduced.length; nColor++) {
|
||||
colorMenu.add(forge.card.MagicColor.toLongString(colorsProduced[nColor]));
|
||||
}
|
||||
colorOptions = ColorSet.fromNames(colorsProduced);
|
||||
}
|
||||
else {
|
||||
colorMenu = MagicColor.Constant.ONLY_COLORS;
|
||||
colorOptions = ColorSet.fromNames(MagicColor.Constant.ONLY_COLORS);
|
||||
}
|
||||
for (int nMana = 1; nMana <= amount; nMana++) {
|
||||
String choice = "";
|
||||
Object o = GuiChoose.one("Select Mana to Produce", colorMenu);
|
||||
if (o == null) {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append("AbilityFactoryMana::manaResolve() - Human color mana choice is empty for ");
|
||||
sb.append(card.getName());
|
||||
throw new RuntimeException(sb.toString());
|
||||
} else {
|
||||
choice = MagicColor.toShortString((String) o);
|
||||
if (nMana != 1) {
|
||||
choiceString.append(" ");
|
||||
}
|
||||
choiceString.append(choice);
|
||||
byte chosenColor = activator.getController().chooseColor("Select Mana to Produce", sa, colorOptions);
|
||||
if (chosenColor == 0) {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append("AbilityFactoryMana::manaResolve() - Human color mana choice is empty for ");
|
||||
sb.append(card.getName());
|
||||
throw new RuntimeException(sb.toString());
|
||||
} else {
|
||||
choice = MagicColor.toShortString(chosenColor);
|
||||
if (nMana != 1) {
|
||||
choiceString.append(" ");
|
||||
}
|
||||
choiceString.append(choice);
|
||||
}
|
||||
}
|
||||
abMana.setExpressChoice(choiceString.toString());
|
||||
}
|
||||
@@ -116,26 +113,26 @@ public class ManaEffect extends SpellAbilityEffect {
|
||||
choice = colorsNeeded;
|
||||
}
|
||||
else {
|
||||
List<String> colorMenu = null;
|
||||
ColorSet colorMenu = null;
|
||||
if (colorsNeeded.length() > 1 && colorsNeeded.length() < 5) {
|
||||
colorMenu = new ArrayList<String>();
|
||||
byte mask = 0;
|
||||
//loop through colors to make menu
|
||||
for (int nChar = 0; nChar < colorsNeeded.length(); nChar++) {
|
||||
colorMenu.add(forge.card.MagicColor.toLongString(colorsNeeded.substring(nChar, nChar + 1)));
|
||||
mask |= forge.card.MagicColor.fromName(colorsNeeded.substring(nChar, nChar + 1));
|
||||
}
|
||||
colorMenu = ColorSet.fromMask(mask);
|
||||
}
|
||||
else {
|
||||
colorMenu = MagicColor.Constant.ONLY_COLORS;
|
||||
colorMenu = ColorSet.fromNames(MagicColor.Constant.ONLY_COLORS);
|
||||
}
|
||||
String s = GuiChoose.one("Select Mana to Produce", colorMenu);
|
||||
if (s == null) {
|
||||
byte val = act.getController().chooseColor("Select Mana to Produce", sa, colorMenu);
|
||||
if (0 == val) {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append("AbilityFactoryMana::manaResolve() - Human color mana choice is empty for ");
|
||||
sb.append(card.getName());
|
||||
throw new RuntimeException(sb.toString());
|
||||
} else {
|
||||
choice = MagicColor.toShortString(s);
|
||||
}
|
||||
choice = MagicColor.toShortString(val);
|
||||
}
|
||||
abMana.setExpressChoice(choice);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package forge.game.ability.effects;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import forge.card.ColorSet;
|
||||
import forge.card.MagicColor;
|
||||
import forge.game.ability.AbilityUtils;
|
||||
import forge.game.ability.SpellAbilityEffect;
|
||||
@@ -10,7 +11,6 @@ import forge.game.card.CardUtil;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.spellability.AbilityManaPart;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.gui.GuiChoose;
|
||||
|
||||
public class ManaReflectedEffect extends SpellAbilityEffect {
|
||||
|
||||
@@ -65,7 +65,7 @@ public class ManaReflectedEffect extends SpellAbilityEffect {
|
||||
baseMana = MagicColor.toShortString(colors.iterator().next());
|
||||
} else {
|
||||
if (player.isHuman()) {
|
||||
baseMana = GuiChoose.one("Select Mana to Produce", colors);
|
||||
baseMana = MagicColor.toShortString(player.getController().chooseColor("Select Mana to Produce", sa, ColorSet.fromNames(colors)));
|
||||
} else {
|
||||
// AI doesn't really have anything here yet
|
||||
baseMana = sa.getManaPart().getExpressChoice();
|
||||
|
||||
@@ -52,7 +52,6 @@ import forge.game.cost.PaymentDecision;
|
||||
import forge.game.mana.ManaCostBeingPaid;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.spellability.Ability;
|
||||
import forge.game.spellability.HumanPlaySpellAbility;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.spellability.TargetRestrictions;
|
||||
import forge.game.zone.ZoneType;
|
||||
|
||||
@@ -1,233 +1,236 @@
|
||||
/*
|
||||
* Forge: Play Magic: the Gathering.
|
||||
* Copyright (C) 2011 Forge Team
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package forge.game.spellability;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
import forge.card.CardType;
|
||||
import forge.game.Game;
|
||||
import forge.game.GameObject;
|
||||
import forge.game.ability.AbilityUtils;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.cost.CostPartMana;
|
||||
import forge.game.cost.CostPayment;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.player.PlayerController;
|
||||
import forge.game.zone.Zone;
|
||||
import forge.gui.player.HumanCostDecision;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* SpellAbility_Requirements class.
|
||||
* </p>
|
||||
*
|
||||
* @author Forge
|
||||
* @version $Id$
|
||||
*/
|
||||
public class HumanPlaySpellAbility {
|
||||
private final SpellAbility ability;
|
||||
private final CostPayment payment;
|
||||
|
||||
public HumanPlaySpellAbility(final SpellAbility sa, final CostPayment cp) {
|
||||
this.ability = sa;
|
||||
this.payment = cp;
|
||||
}
|
||||
|
||||
public final void playAbility(boolean mayChooseTargets, boolean isFree, boolean skipStack) {
|
||||
final Player human = ability.getActivatingPlayer();
|
||||
final Game game = ability.getActivatingPlayer().getGame();
|
||||
|
||||
// used to rollback
|
||||
Zone fromZone = null;
|
||||
int zonePosition = 0;
|
||||
|
||||
final Card c = this.ability.getSourceCard();
|
||||
if (this.ability instanceof Spell && !c.isCopiedSpell()) {
|
||||
fromZone = game.getZoneOf(c);
|
||||
zonePosition = fromZone.getCards().indexOf(c);
|
||||
this.ability.setSourceCard(game.getAction().moveToStack(c));
|
||||
}
|
||||
|
||||
// freeze Stack. No abilities should go onto the stack while I'm filling requirements.
|
||||
game.getStack().freezeStack();
|
||||
|
||||
// This line makes use of short-circuit evaluation of boolean values, that is each subsequent argument
|
||||
// is only executed or evaluated if the first argument does not suffice to determine the value of the expression
|
||||
boolean prerequisitesMet = this.announceValuesLikeX()
|
||||
&& this.announceType()
|
||||
&& (!mayChooseTargets || setupTargets()) // if you can choose targets, then do choose them.
|
||||
&& (isFree || this.payment.payCost(new HumanCostDecision(human, ability, ability.getSourceCard())));
|
||||
|
||||
if (!prerequisitesMet) {
|
||||
if (!ability.isTrigger()) {
|
||||
rollbackAbility(fromZone, zonePosition);
|
||||
if (ability.isMadness()) {
|
||||
// if a player failed to play madness cost, move the card to graveyard
|
||||
game.getAction().moveToGraveyard(c);
|
||||
ability.setMadness(false);
|
||||
} else if (ability.getSourceCard().isBestowed()) {
|
||||
ability.getSourceCard().unanimateBestow();
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (isFree || this.payment.isFullyPaid()) {
|
||||
if (skipStack) {
|
||||
AbilityUtils.resolve(this.ability);
|
||||
}
|
||||
else {
|
||||
this.enusureAbilityHasDescription(this.ability);
|
||||
this.ability.getActivatingPlayer().getManaPool().clearManaPaid(this.ability, false);
|
||||
game.getStack().addAndUnfreeze(this.ability);
|
||||
}
|
||||
|
||||
// no worries here. The same thread must resolve, and by this moment ability will have been resolved already
|
||||
// Triggers haven't resolved yet ??
|
||||
if (mayChooseTargets) {
|
||||
clearTargets(ability);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final boolean setupTargets() {
|
||||
// Skip to paying if parent ability doesn't target and has no subAbilities.
|
||||
// (or trigger case where its already targeted)
|
||||
SpellAbility currentAbility = ability;
|
||||
final Card source = ability.getSourceCard();
|
||||
do {
|
||||
TargetRestrictions tgt = currentAbility.getTargetRestrictions();
|
||||
if (tgt != null && tgt.doesTarget()) {
|
||||
clearTargets(currentAbility);
|
||||
Player targetingPlayer = ability.hasParam("TargetingPlayer") ?
|
||||
AbilityUtils.getDefinedPlayers(source, ability.getParam("TargetingPlayer"), currentAbility).get(0) : ability.getActivatingPlayer();
|
||||
|
||||
if (!targetingPlayer.getController().chooseTargetsFor(currentAbility))
|
||||
return false;
|
||||
}
|
||||
final SpellAbility subAbility = currentAbility.getSubAbility();
|
||||
if (subAbility != null) {
|
||||
// This is necessary for "TargetsWithDefinedController$ ParentTarget"
|
||||
((AbilitySub) subAbility).setParent(currentAbility);
|
||||
}
|
||||
currentAbility = subAbility;
|
||||
} while (currentAbility != null);
|
||||
return true;
|
||||
}
|
||||
|
||||
public final void clearTargets(SpellAbility ability) {
|
||||
TargetRestrictions tg = ability.getTargetRestrictions();
|
||||
if (tg != null) {
|
||||
ability.resetTargets();
|
||||
tg.calculateStillToDivide(ability.getParam("DividedAsYouChoose"), ability.getSourceCard(), ability);
|
||||
}
|
||||
}
|
||||
|
||||
private void rollbackAbility(Zone fromZone, int zonePosition) {
|
||||
// cancel ability during target choosing
|
||||
final Game game = ability.getActivatingPlayer().getGame();
|
||||
|
||||
if (fromZone != null) { // and not a copy
|
||||
// add back to where it came from
|
||||
game.getAction().moveTo(fromZone, ability.getSourceCard(), zonePosition >= 0 ? Integer.valueOf(zonePosition) : null);
|
||||
}
|
||||
|
||||
clearTargets(ability);
|
||||
|
||||
this.ability.resetOnceResolved();
|
||||
this.payment.refundPayment();
|
||||
game.getStack().clearFrozen();
|
||||
}
|
||||
|
||||
private boolean announceValuesLikeX() {
|
||||
// Announcing Requirements like Choosing X or Multikicker
|
||||
// SA Params as comma delimited list
|
||||
String announce = ability.getParam("Announce");
|
||||
if (announce != null) {
|
||||
for(String aVar : announce.split(",")) {
|
||||
String varName = aVar.trim();
|
||||
|
||||
boolean isX = "X".equalsIgnoreCase(varName);
|
||||
CostPartMana manaCost = ability.getPayCosts().getCostMana();
|
||||
boolean allowZero = !ability.hasParam("XCantBe0") && (!isX || manaCost == null || manaCost.canXbe0());
|
||||
|
||||
Integer value = ability.getActivatingPlayer().getController().announceRequirements(ability, varName, allowZero);
|
||||
if (value == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ability.setSVar(varName, value.toString());
|
||||
if ("Multikicker".equals(varName)) {
|
||||
ability.getSourceCard().setKickerMagnitude(value);
|
||||
}
|
||||
else {
|
||||
ability.getSourceCard().setSVar(varName, value.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean announceType() {
|
||||
// Announcing Requirements like choosing creature type or number
|
||||
String announce = ability.getParam("AnnounceType");
|
||||
PlayerController pc = ability.getActivatingPlayer().getController();
|
||||
if (announce != null) {
|
||||
for(String aVar : announce.split(",")) {
|
||||
String varName = aVar.trim();
|
||||
if ("CreatureType".equals(varName)) {
|
||||
String choice = pc.chooseSomeType("Creature", ability, CardType.getCreatureTypes(), new ArrayList<String>());
|
||||
ability.getSourceCard().setChosenType(choice);
|
||||
}
|
||||
if ("ChooseNumber".equals(varName)) {
|
||||
int min = Integer.parseInt(ability.getParam("Min"));
|
||||
int max = Integer.parseInt(ability.getParam("Max"));
|
||||
int i = ability.getActivatingPlayer().getController().chooseNumber(ability,
|
||||
"Choose a number", min, max);
|
||||
ability.getSourceCard().setChosenNumber(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void enusureAbilityHasDescription(SpellAbility ability) {
|
||||
if (!StringUtils.isBlank(ability.getStackDescription())) {
|
||||
return;
|
||||
}
|
||||
|
||||
// For older abilities that don't setStackDescription set it here
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append(ability.getSourceCard().getName());
|
||||
if (ability.getTargetRestrictions() != null) {
|
||||
final Iterable<GameObject> targets = ability.getTargets().getTargets();
|
||||
if (!Iterables.isEmpty(targets)) {
|
||||
sb.append(" - Targeting ");
|
||||
for (final GameObject o : targets) {
|
||||
sb.append(o.toString()).append(" ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ability.setStackDescription(sb.toString());
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Forge: Play Magic: the Gathering.
|
||||
* Copyright (C) 2011 Forge Team
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package forge.gui.player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
import forge.card.CardType;
|
||||
import forge.game.Game;
|
||||
import forge.game.GameObject;
|
||||
import forge.game.ability.AbilityUtils;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.cost.CostPartMana;
|
||||
import forge.game.cost.CostPayment;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.player.PlayerController;
|
||||
import forge.game.spellability.AbilitySub;
|
||||
import forge.game.spellability.Spell;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.spellability.TargetRestrictions;
|
||||
import forge.game.zone.Zone;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* SpellAbility_Requirements class.
|
||||
* </p>
|
||||
*
|
||||
* @author Forge
|
||||
* @version $Id: HumanPlaySpellAbility.java 24317 2014-01-17 08:32:39Z Max mtg $
|
||||
*/
|
||||
public class HumanPlaySpellAbility {
|
||||
private final SpellAbility ability;
|
||||
private final CostPayment payment;
|
||||
|
||||
public HumanPlaySpellAbility(final SpellAbility sa, final CostPayment cp) {
|
||||
this.ability = sa;
|
||||
this.payment = cp;
|
||||
}
|
||||
|
||||
public final void playAbility(boolean mayChooseTargets, boolean isFree, boolean skipStack) {
|
||||
final Player human = ability.getActivatingPlayer();
|
||||
final Game game = ability.getActivatingPlayer().getGame();
|
||||
|
||||
// used to rollback
|
||||
Zone fromZone = null;
|
||||
int zonePosition = 0;
|
||||
|
||||
final Card c = this.ability.getSourceCard();
|
||||
if (this.ability instanceof Spell && !c.isCopiedSpell()) {
|
||||
fromZone = game.getZoneOf(c);
|
||||
zonePosition = fromZone.getCards().indexOf(c);
|
||||
this.ability.setSourceCard(game.getAction().moveToStack(c));
|
||||
}
|
||||
|
||||
// freeze Stack. No abilities should go onto the stack while I'm filling requirements.
|
||||
game.getStack().freezeStack();
|
||||
|
||||
// This line makes use of short-circuit evaluation of boolean values, that is each subsequent argument
|
||||
// is only executed or evaluated if the first argument does not suffice to determine the value of the expression
|
||||
boolean prerequisitesMet = this.announceValuesLikeX()
|
||||
&& this.announceType()
|
||||
&& (!mayChooseTargets || setupTargets()) // if you can choose targets, then do choose them.
|
||||
&& (isFree || this.payment.payCost(new HumanCostDecision(human, ability, ability.getSourceCard())));
|
||||
|
||||
if (!prerequisitesMet) {
|
||||
if (!ability.isTrigger()) {
|
||||
rollbackAbility(fromZone, zonePosition);
|
||||
if (ability.isMadness()) {
|
||||
// if a player failed to play madness cost, move the card to graveyard
|
||||
game.getAction().moveToGraveyard(c);
|
||||
ability.setMadness(false);
|
||||
} else if (ability.getSourceCard().isBestowed()) {
|
||||
ability.getSourceCard().unanimateBestow();
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (isFree || this.payment.isFullyPaid()) {
|
||||
if (skipStack) {
|
||||
AbilityUtils.resolve(this.ability);
|
||||
}
|
||||
else {
|
||||
this.enusureAbilityHasDescription(this.ability);
|
||||
this.ability.getActivatingPlayer().getManaPool().clearManaPaid(this.ability, false);
|
||||
game.getStack().addAndUnfreeze(this.ability);
|
||||
}
|
||||
|
||||
// no worries here. The same thread must resolve, and by this moment ability will have been resolved already
|
||||
// Triggers haven't resolved yet ??
|
||||
if (mayChooseTargets) {
|
||||
clearTargets(ability);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final boolean setupTargets() {
|
||||
// Skip to paying if parent ability doesn't target and has no subAbilities.
|
||||
// (or trigger case where its already targeted)
|
||||
SpellAbility currentAbility = ability;
|
||||
final Card source = ability.getSourceCard();
|
||||
do {
|
||||
TargetRestrictions tgt = currentAbility.getTargetRestrictions();
|
||||
if (tgt != null && tgt.doesTarget()) {
|
||||
clearTargets(currentAbility);
|
||||
Player targetingPlayer = ability.hasParam("TargetingPlayer") ?
|
||||
AbilityUtils.getDefinedPlayers(source, ability.getParam("TargetingPlayer"), currentAbility).get(0) : ability.getActivatingPlayer();
|
||||
|
||||
if (!targetingPlayer.getController().chooseTargetsFor(currentAbility))
|
||||
return false;
|
||||
}
|
||||
final SpellAbility subAbility = currentAbility.getSubAbility();
|
||||
if (subAbility != null) {
|
||||
// This is necessary for "TargetsWithDefinedController$ ParentTarget"
|
||||
((AbilitySub) subAbility).setParent(currentAbility);
|
||||
}
|
||||
currentAbility = subAbility;
|
||||
} while (currentAbility != null);
|
||||
return true;
|
||||
}
|
||||
|
||||
public final void clearTargets(SpellAbility ability) {
|
||||
TargetRestrictions tg = ability.getTargetRestrictions();
|
||||
if (tg != null) {
|
||||
ability.resetTargets();
|
||||
tg.calculateStillToDivide(ability.getParam("DividedAsYouChoose"), ability.getSourceCard(), ability);
|
||||
}
|
||||
}
|
||||
|
||||
private void rollbackAbility(Zone fromZone, int zonePosition) {
|
||||
// cancel ability during target choosing
|
||||
final Game game = ability.getActivatingPlayer().getGame();
|
||||
|
||||
if (fromZone != null) { // and not a copy
|
||||
// add back to where it came from
|
||||
game.getAction().moveTo(fromZone, ability.getSourceCard(), zonePosition >= 0 ? Integer.valueOf(zonePosition) : null);
|
||||
}
|
||||
|
||||
clearTargets(ability);
|
||||
|
||||
this.ability.resetOnceResolved();
|
||||
this.payment.refundPayment();
|
||||
game.getStack().clearFrozen();
|
||||
}
|
||||
|
||||
private boolean announceValuesLikeX() {
|
||||
// Announcing Requirements like Choosing X or Multikicker
|
||||
// SA Params as comma delimited list
|
||||
String announce = ability.getParam("Announce");
|
||||
if (announce != null) {
|
||||
for(String aVar : announce.split(",")) {
|
||||
String varName = aVar.trim();
|
||||
|
||||
boolean isX = "X".equalsIgnoreCase(varName);
|
||||
CostPartMana manaCost = ability.getPayCosts().getCostMana();
|
||||
boolean allowZero = !ability.hasParam("XCantBe0") && (!isX || manaCost == null || manaCost.canXbe0());
|
||||
|
||||
Integer value = ability.getActivatingPlayer().getController().announceRequirements(ability, varName, allowZero);
|
||||
if (value == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ability.setSVar(varName, value.toString());
|
||||
if ("Multikicker".equals(varName)) {
|
||||
ability.getSourceCard().setKickerMagnitude(value);
|
||||
}
|
||||
else {
|
||||
ability.getSourceCard().setSVar(varName, value.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean announceType() {
|
||||
// Announcing Requirements like choosing creature type or number
|
||||
String announce = ability.getParam("AnnounceType");
|
||||
PlayerController pc = ability.getActivatingPlayer().getController();
|
||||
if (announce != null) {
|
||||
for(String aVar : announce.split(",")) {
|
||||
String varName = aVar.trim();
|
||||
if ("CreatureType".equals(varName)) {
|
||||
String choice = pc.chooseSomeType("Creature", ability, CardType.getCreatureTypes(), new ArrayList<String>());
|
||||
ability.getSourceCard().setChosenType(choice);
|
||||
}
|
||||
if ("ChooseNumber".equals(varName)) {
|
||||
int min = Integer.parseInt(ability.getParam("Min"));
|
||||
int max = Integer.parseInt(ability.getParam("Max"));
|
||||
int i = ability.getActivatingPlayer().getController().chooseNumber(ability,
|
||||
"Choose a number", min, max);
|
||||
ability.getSourceCard().setChosenNumber(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void enusureAbilityHasDescription(SpellAbility ability) {
|
||||
if (!StringUtils.isBlank(ability.getStackDescription())) {
|
||||
return;
|
||||
}
|
||||
|
||||
// For older abilities that don't setStackDescription set it here
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append(ability.getSourceCard().getName());
|
||||
if (ability.getTargetRestrictions() != null) {
|
||||
final Iterable<GameObject> targets = ability.getTargets().getTargets();
|
||||
if (!Iterables.isEmpty(targets)) {
|
||||
sb.append(" - Targeting ");
|
||||
for (final GameObject o : targets) {
|
||||
sb.append(o.toString()).append(" ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ability.setStackDescription(sb.toString());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user