mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 20:28:00 +00:00
merge latest trunk
This commit is contained in:
@@ -1631,6 +1631,7 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
public final ManaCost getManaCost() {
|
||||
return this.getCharacteristics().getManaCost();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -9194,7 +9195,7 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
System.out.println("Trying to sacrifice immutables: " + this);
|
||||
return false;
|
||||
}
|
||||
if (source != null && !getController().isOpponentOf(source.getActivatingPlayer())
|
||||
if (source != null && getController().isOpponentOf(source.getActivatingPlayer())
|
||||
&& getController().hasKeyword("Spells and abilities your opponents control can't cause you to sacrifice permanents.")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import forge.card.ability.effects.ChangeZoneAllEffect;
|
||||
import forge.card.ability.effects.ChangeZoneEffect;
|
||||
import forge.card.ability.effects.ManaEffect;
|
||||
import forge.card.ability.effects.ManaReflectedEffect;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.cardfactory.CardFactory;
|
||||
import forge.card.cost.Cost;
|
||||
import forge.card.spellability.AbilityActivated;
|
||||
import forge.card.spellability.AbilityManaPart;
|
||||
@@ -50,7 +50,7 @@ public class AbilityApiBased extends AbilityActivated {
|
||||
public AbilityActivated getCopy() {
|
||||
Target tgt = getTarget() == null ? null : new Target(getTarget());
|
||||
AbilityActivated res = new AbilityApiBased(api, getSourceCard(), getPayCosts(), tgt, params);
|
||||
CardFactoryUtil.copySpellAbility(this, res);
|
||||
CardFactory.copySpellAbility(this, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import java.util.List;
|
||||
|
||||
import forge.Card;
|
||||
import forge.CardLists;
|
||||
import forge.CardPredicates;
|
||||
import forge.card.ability.AbilityUtils;
|
||||
import forge.card.ability.SpellAbilityAi;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
@@ -21,42 +22,8 @@ public class SacrificeAi extends SpellAbilityAi {
|
||||
|
||||
@Override
|
||||
protected boolean canPlayAI(AIPlayer ai, SpellAbility sa) {
|
||||
boolean chance = sacrificeTgtAI(ai, sa);
|
||||
|
||||
// Some additional checks based on what is being sacrificed, and who is
|
||||
// sacrificing
|
||||
final Target tgt = sa.getTarget();
|
||||
if (tgt != null) {
|
||||
final String valid = sa.getParam("SacValid");
|
||||
String num = sa.getParam("Amount");
|
||||
num = (num == null) ? "1" : num;
|
||||
final int amount = AbilityUtils.calculateAmount(sa.getSourceCard(), num, sa);
|
||||
|
||||
List<Card> list =
|
||||
CardLists.getValidCards(ai.getOpponent().getCardsIn(ZoneType.Battlefield), valid.split(","), sa.getActivatingPlayer(), sa.getSourceCard());
|
||||
|
||||
if (list.size() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final Card source = sa.getSourceCard();
|
||||
if (num.equals("X") && source.getSVar(num).equals("Count$xPaid")) {
|
||||
// Set PayX here to maximum value.
|
||||
final int xPay = Math.min(ComputerUtilMana.determineLeftoverMana(sa, ai), amount);
|
||||
source.setSVar("PayX", Integer.toString(xPay));
|
||||
}
|
||||
|
||||
final int half = (amount / 2) + (amount % 2); // Half of amount
|
||||
// rounded up
|
||||
|
||||
// If the Human has at least half rounded up of the amount to be
|
||||
// sacrificed, cast the spell
|
||||
if (list.size() < half) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return chance;
|
||||
return sacrificeTgtAI(ai, sa);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -83,16 +50,49 @@ public class SacrificeAi extends SpellAbilityAi {
|
||||
|
||||
private boolean sacrificeTgtAI(final Player ai, final SpellAbility sa) {
|
||||
|
||||
final Card card = sa.getSourceCard();
|
||||
final Card source = sa.getSourceCard();
|
||||
final Target tgt = sa.getTarget();
|
||||
final boolean destroy = sa.hasParam("Destroy");
|
||||
|
||||
Player opp = ai.getOpponent();
|
||||
if (tgt != null) {
|
||||
tgt.resetTargets();
|
||||
if (opp.canBeTargetedBy(sa)) {
|
||||
tgt.addTarget(opp);
|
||||
return true;
|
||||
if (!opp.canBeTargetedBy(sa)) {
|
||||
return false;
|
||||
}
|
||||
tgt.addTarget(opp);
|
||||
final String valid = sa.getParam("SacValid");
|
||||
String num = sa.getParam("Amount");
|
||||
num = (num == null) ? "1" : num;
|
||||
final int amount = AbilityUtils.calculateAmount(sa.getSourceCard(), num, sa);
|
||||
|
||||
List<Card> list =
|
||||
CardLists.getValidCards(ai.getOpponent().getCardsIn(ZoneType.Battlefield), valid.split(","), sa.getActivatingPlayer(), sa.getSourceCard());
|
||||
if (!destroy) {
|
||||
list = CardLists.filter(list, CardPredicates.canBeSacrificedBy(sa));
|
||||
} else {
|
||||
if (!CardLists.getKeyword(list, "Indestructible").isEmpty()) {
|
||||
// human can choose to destroy indestructibles
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (list.size() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (num.equals("X") && source.getSVar(num).equals("Count$xPaid")) {
|
||||
// Set PayX here to maximum value.
|
||||
final int xPay = Math.min(ComputerUtilMana.determineLeftoverMana(sa, ai), amount);
|
||||
source.setSVar("PayX", Integer.toString(xPay));
|
||||
}
|
||||
|
||||
final int half = (amount / 2) + (amount % 2); // Half of amount
|
||||
// rounded up
|
||||
|
||||
// If the Human has at least half rounded up of the amount to be
|
||||
// sacrificed, cast the spell
|
||||
if (!sa.isTrigger() && list.size() < half) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -109,9 +109,8 @@ public class SacrificeAi extends SpellAbilityAi {
|
||||
// TODO: Cast if the type is favorable: my "worst" valid is
|
||||
// worse than his "worst" valid
|
||||
final String num = sa.hasParam("Amount") ? sa.getParam("Amount") : "1";
|
||||
int amount = AbilityUtils.calculateAmount(card, num, sa);
|
||||
int amount = AbilityUtils.calculateAmount(source, num, sa);
|
||||
|
||||
final Card source = sa.getSourceCard();
|
||||
if (num.equals("X") && source.getSVar(num).equals("Count$xPaid")) {
|
||||
// Set PayX here to maximum value.
|
||||
amount = Math.min(ComputerUtilMana.determineLeftoverMana(sa, ai), amount);
|
||||
|
||||
@@ -1,18 +1,31 @@
|
||||
package forge.card.ability.ai;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import forge.Card;
|
||||
import forge.CardLists;
|
||||
import forge.Singletons;
|
||||
import forge.card.ability.SpellAbilityAi;
|
||||
import forge.card.spellability.AbilitySub;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.game.player.AIPlayer;
|
||||
import forge.game.zone.ZoneType;
|
||||
|
||||
public class UntapAllAi extends SpellAbilityAi {
|
||||
|
||||
@Override
|
||||
protected boolean canPlayAI(AIPlayer aiPlayer, SpellAbility sa) {
|
||||
// check SubAbilities DoTrigger?
|
||||
final Card source = sa.getSourceCard();
|
||||
|
||||
final AbilitySub abSub = sa.getSubAbility();
|
||||
if (abSub != null) {
|
||||
return true;
|
||||
String valid = "";
|
||||
List<Card> list = Singletons.getModel().getGame().getCardsIn(ZoneType.Battlefield);
|
||||
if (sa.hasParam("ValidCards")) {
|
||||
valid = sa.getParam("ValidCards");
|
||||
}
|
||||
list = CardLists.getValidCards(list, valid.split(","), source.getController(), source);
|
||||
return !list.isEmpty();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import forge.Command;
|
||||
import forge.Singletons;
|
||||
import forge.card.ability.AbilityUtils;
|
||||
import forge.card.ability.SpellAbilityEffect;
|
||||
import forge.card.cardfactory.CardFactory;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.Target;
|
||||
@@ -122,7 +123,7 @@ public class CloneEffect extends SpellAbilityEffect {
|
||||
stateToCopy = cardToCopy.getCurState();
|
||||
}
|
||||
|
||||
CardFactoryUtil.copyState(cardToCopy, stateToCopy, tgtCard);
|
||||
CardFactory.copyState(cardToCopy, stateToCopy, tgtCard);
|
||||
// must call this before addAbilityFactoryAbilities so cloned added abilities are handled correctly
|
||||
addExtraCharacteristics(tgtCard, sa, origSVars);
|
||||
CardFactoryUtil.addAbilityFactoryAbilities(tgtCard);
|
||||
@@ -140,7 +141,7 @@ public class CloneEffect extends SpellAbilityEffect {
|
||||
tgtCard.addAlternateState(CardCharacteristicName.Flipped);
|
||||
tgtCard.setState(CardCharacteristicName.Flipped);
|
||||
}
|
||||
CardFactoryUtil.copyState(cardToCopy, CardCharacteristicName.Flipped, tgtCard);
|
||||
CardFactory.copyState(cardToCopy, CardCharacteristicName.Flipped, tgtCard);
|
||||
addExtraCharacteristics(tgtCard, sa, origSVars);
|
||||
CardFactoryUtil.addAbilityFactoryAbilities(tgtCard);
|
||||
for (int i = 0; i < tgtCard.getStaticAbilityStrings().size(); i++) {
|
||||
|
||||
@@ -12,6 +12,7 @@ import forge.Command;
|
||||
import forge.Singletons;
|
||||
import forge.card.ability.AbilityUtils;
|
||||
import forge.card.ability.SpellAbilityEffect;
|
||||
import forge.card.cardfactory.CardFactory;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.mana.ManaCost;
|
||||
import forge.card.spellability.Ability;
|
||||
@@ -82,7 +83,7 @@ public class CopyPermanentEffect extends SpellAbilityEffect {
|
||||
if (!c.isToken() || c.isCopiedToken()) {
|
||||
// copy creature and put it onto the battlefield
|
||||
|
||||
copy = Singletons.getModel().getCardFactory().getCard(CardDb.getCard(c), sa.getActivatingPlayer());
|
||||
copy = CardFactory.getCard(CardDb.getCard(c), sa.getActivatingPlayer());
|
||||
|
||||
// when copying something stolen:
|
||||
copy.addController(controller);
|
||||
@@ -90,7 +91,7 @@ public class CopyPermanentEffect extends SpellAbilityEffect {
|
||||
copy.setToken(true);
|
||||
copy.setCopiedToken(true);
|
||||
} else { // isToken()
|
||||
copy = CardFactoryUtil.copyStats(c);
|
||||
copy = CardFactory.copyStats(c);
|
||||
|
||||
copy.setName(c.getName());
|
||||
copy.setImageFilename(c.getImageFilename());
|
||||
|
||||
@@ -5,9 +5,9 @@ import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import forge.Card;
|
||||
import forge.Singletons;
|
||||
import forge.card.ability.AbilityUtils;
|
||||
import forge.card.ability.SpellAbilityEffect;
|
||||
import forge.card.cardfactory.CardFactory;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.game.player.Player;
|
||||
import forge.gui.GuiChoose;
|
||||
@@ -99,7 +99,7 @@ public class CopySpellAbilityEffect extends SpellAbilityEffect {
|
||||
for (final SpellAbility chosenSAcopy : chosenSAs) {
|
||||
chosenSAcopy.setActivatingPlayer(controller);
|
||||
for (int i = 0; i < amount; i++) {
|
||||
Singletons.getModel().getCardFactory().copySpellontoStack(card, chosenSAcopy.getSourceCard(), chosenSAcopy, true);
|
||||
CardFactory.copySpellontoStack(card, chosenSAcopy.getSourceCard(), chosenSAcopy, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -115,7 +115,7 @@ public class CopySpellAbilityEffect extends SpellAbilityEffect {
|
||||
|
||||
chosenSA.setActivatingPlayer(controller);
|
||||
for (int i = 0; i < amount; i++) {
|
||||
Singletons.getModel().getCardFactory().copySpellontoStack(card, chosenSA.getSourceCard(), chosenSA, true);
|
||||
CardFactory.copySpellontoStack(card, chosenSA.getSourceCard(), chosenSA, true);
|
||||
}
|
||||
}
|
||||
} // end resolve
|
||||
|
||||
@@ -150,7 +150,7 @@ public class PlayEffect extends SpellAbilityEffect {
|
||||
source.clearRemembered();
|
||||
}
|
||||
if (sa.hasParam("CopyCard")) {
|
||||
tgtCard = Singletons.getModel().getCardFactory().getCard(CardDb.getCard(tgtCard), sa.getActivatingPlayer());
|
||||
tgtCard = CardDb.getCard(tgtCard).toForgeCard(sa.getActivatingPlayer());
|
||||
// when copying something stolen:
|
||||
tgtCard.addController(sa.getActivatingPlayer());
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@ package forge.card.ability.effects;
|
||||
import java.util.List;
|
||||
|
||||
import forge.Card;
|
||||
import forge.CardLists;
|
||||
import forge.CardPredicates;
|
||||
import forge.Singletons;
|
||||
import forge.card.ability.AbilityUtils;
|
||||
import forge.card.ability.SpellAbilityEffect;
|
||||
@@ -51,6 +53,9 @@ public class SacrificeEffect extends SpellAbilityEffect {
|
||||
for (final Player p : tgts) {
|
||||
List<Card> battlefield = p.getCardsIn(ZoneType.Battlefield);
|
||||
List<Card> validTargets = AbilityUtils.filterListByType(battlefield, valid, sa);
|
||||
if (!destroy) {
|
||||
validTargets = CardLists.filter(validTargets, CardPredicates.canBeSacrificedBy(sa));
|
||||
}
|
||||
|
||||
if (sa.hasParam("Random")) {
|
||||
choosenToSacrifice = Aggregates.random(validTargets, Math.min(amount, validTargets.size()));
|
||||
|
||||
@@ -27,6 +27,7 @@ import forge.CardCharacteristicName;
|
||||
import forge.CardColor;
|
||||
import forge.CardUtil;
|
||||
import forge.Color;
|
||||
import forge.card.CardCharacteristics;
|
||||
import forge.card.CardRules;
|
||||
import forge.card.CardSplitType;
|
||||
import forge.card.ICardFace;
|
||||
@@ -39,12 +40,9 @@ import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.SpellPermanent;
|
||||
import forge.card.spellability.Target;
|
||||
import forge.card.trigger.TriggerHandler;
|
||||
import forge.error.BugReporter;
|
||||
import forge.game.player.Player;
|
||||
import forge.gui.GuiUtils;
|
||||
import forge.item.CardDb;
|
||||
import forge.item.IPaperCard;
|
||||
import forge.properties.NewConstants;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -65,33 +63,6 @@ import forge.properties.NewConstants;
|
||||
* @version $Id$
|
||||
*/
|
||||
public class CardFactory {
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Constructor for CardFactory.
|
||||
* </p>
|
||||
*
|
||||
* @param file
|
||||
* a {@link java.io.File} object.
|
||||
*/
|
||||
private final CardStorageReader reader;
|
||||
|
||||
public CardFactory() {
|
||||
|
||||
GuiUtils.checkEDT("CardFactory$constructor", false);
|
||||
reader = new CardStorageReader(NewConstants.CARD_DATA_DIR.defaultLoc, true);
|
||||
try {
|
||||
// this fills in our map of card names to Card instances.
|
||||
final List<CardRules> listCardRules = reader.loadCards();
|
||||
CardDb.setup(listCardRules.iterator());
|
||||
|
||||
} catch (final Exception ex) {
|
||||
BugReporter.reportException(ex);
|
||||
}
|
||||
|
||||
} // constructor
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* copyCard.
|
||||
@@ -101,15 +72,15 @@ public class CardFactory {
|
||||
* a {@link forge.Card} object.
|
||||
* @return a {@link forge.Card} object.
|
||||
*/
|
||||
public final Card copyCard(final Card in) {
|
||||
public final static Card copyCard(final Card in) {
|
||||
final CardCharacteristicName curState = in.getCurState();
|
||||
if (in.isInAlternateState()) {
|
||||
in.setState(CardCharacteristicName.Original);
|
||||
}
|
||||
final Card out = this.getCard(CardDb.getCard(in), in.getOwner());
|
||||
final Card out = getCard(CardDb.getCard(in), in.getOwner());
|
||||
out.setUniqueNumber(in.getUniqueNumber());
|
||||
|
||||
CardFactoryUtil.copyCharacteristics(in, out);
|
||||
CardFactory.copyCharacteristics(in, out);
|
||||
if (in.hasAlternateState()) {
|
||||
for (final CardCharacteristicName state : in.getStates()) {
|
||||
in.setState(state);
|
||||
@@ -117,7 +88,7 @@ public class CardFactory {
|
||||
out.addAlternateState(state);
|
||||
}
|
||||
out.setState(state);
|
||||
CardFactoryUtil.copyCharacteristics(in, out);
|
||||
CardFactory.copyCharacteristics(in, out);
|
||||
}
|
||||
in.setState(curState);
|
||||
out.setState(curState);
|
||||
@@ -154,7 +125,7 @@ public class CardFactory {
|
||||
* @param bCopyDetails
|
||||
* a boolean.
|
||||
*/
|
||||
public final void copySpellontoStack(final Card source, final Card original, final SpellAbility sa,
|
||||
public final static void copySpellontoStack(final Card source, final Card original, final SpellAbility sa,
|
||||
final boolean bCopyDetails) {
|
||||
//Player originalController = original.getController();
|
||||
Player controller = sa.getActivatingPlayer();
|
||||
@@ -240,7 +211,7 @@ public class CardFactory {
|
||||
* @return a {@link forge.Card} instance, owned by owner; or the special
|
||||
* blankCard
|
||||
*/
|
||||
public final Card getCard(final IPaperCard cp, final Player owner) {
|
||||
public final static Card getCard(final IPaperCard cp, final Player owner) {
|
||||
|
||||
//System.out.println(cardName);
|
||||
CardRules cardRules = cp.getRules();
|
||||
@@ -435,4 +406,110 @@ public class CardFactory {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Copies stats like power, toughness, etc.
|
||||
* </p>
|
||||
*
|
||||
* @param sim
|
||||
* a {@link java.lang.Object} object.
|
||||
* @return a {@link forge.Card} object.
|
||||
*/
|
||||
public static Card copyStats(final Card sim) {
|
||||
final Card c = new Card();
|
||||
|
||||
c.setFlipCard(sim.isFlipCard());
|
||||
c.setDoubleFaced(sim.isDoubleFaced());
|
||||
c.setCurSetCode(sim.getCurSetCode());
|
||||
|
||||
final CardCharacteristicName origState = sim.getCurState();
|
||||
for (final CardCharacteristicName state : sim.getStates()) {
|
||||
c.addAlternateState(state);
|
||||
c.setState(state);
|
||||
sim.setState(state);
|
||||
CardFactory.copyCharacteristics(sim, c);
|
||||
}
|
||||
|
||||
sim.setState(origState);
|
||||
c.setState(origState);
|
||||
c.setRules(sim.getRules());
|
||||
|
||||
return c;
|
||||
} // copyStats()
|
||||
|
||||
/**
|
||||
* Copy characteristics.
|
||||
*
|
||||
* @param from
|
||||
* the from
|
||||
* @param to
|
||||
* the to
|
||||
*/
|
||||
private static void copyCharacteristics(final Card from, final Card to) {
|
||||
to.setBaseAttack(from.getBaseAttack());
|
||||
to.setBaseDefense(from.getBaseDefense());
|
||||
to.setBaseLoyalty(from.getBaseLoyalty());
|
||||
to.setBaseAttackString(from.getBaseAttackString());
|
||||
to.setBaseDefenseString(from.getBaseDefenseString());
|
||||
to.setIntrinsicKeyword(from.getIntrinsicKeyword());
|
||||
to.setName(from.getName());
|
||||
to.setType(from.getCharacteristics().getType());
|
||||
to.setText(from.getSpellText());
|
||||
to.setManaCost(from.getManaCost());
|
||||
to.setColor(from.getColor());
|
||||
to.setSVars(from.getSVars());
|
||||
to.setIntrinsicAbilities(from.getIntrinsicAbilities());
|
||||
|
||||
to.setImageFilename(from.getImageFilename());
|
||||
to.setTriggers(from.getTriggers());
|
||||
to.setReplacementEffects(from.getReplacementEffects());
|
||||
to.setStaticAbilityStrings(from.getStaticAbilityStrings());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy characteristics.
|
||||
*
|
||||
* @param from
|
||||
* the from
|
||||
* @param stateToCopy
|
||||
* the state to copy
|
||||
* @param to
|
||||
* the to
|
||||
*/
|
||||
public static void copyState(final Card from, final CardCharacteristicName stateToCopy, final Card to) {
|
||||
|
||||
// copy characteristics not associated with a state
|
||||
to.setBaseLoyalty(from.getBaseLoyalty());
|
||||
to.setBaseAttackString(from.getBaseAttackString());
|
||||
to.setBaseDefenseString(from.getBaseDefenseString());
|
||||
to.setText(from.getSpellText());
|
||||
|
||||
// get CardCharacteristics for desired state
|
||||
CardCharacteristics characteristics = from.getState(stateToCopy);
|
||||
to.getCharacteristics().copy(characteristics);
|
||||
// handle triggers and replacement effect through Card class interface
|
||||
to.setTriggers(characteristics.getTriggers());
|
||||
to.setReplacementEffects(characteristics.getReplacementEffects());
|
||||
}
|
||||
|
||||
public static void copySpellAbility(SpellAbility from, SpellAbility to) {
|
||||
to.setDescription(from.getDescription());
|
||||
to.setStackDescription(from.getDescription());
|
||||
|
||||
if (from.getSubAbility() != null) {
|
||||
to.setSubAbility(from.getSubAbility().getCopy());
|
||||
}
|
||||
if (from.getRestrictions() != null) {
|
||||
to.setRestrictions(from.getRestrictions());
|
||||
}
|
||||
if (from.getConditions() != null) {
|
||||
to.setConditions(from.getConditions());
|
||||
}
|
||||
|
||||
for (String sVar : from.getSVars()) {
|
||||
to.setSVar(sVar, from.getSVar(sVar));
|
||||
}
|
||||
}
|
||||
|
||||
} // end class AbstractCardFactory
|
||||
|
||||
@@ -48,7 +48,7 @@ class CardFactoryArtifacts {
|
||||
public AbilityActivated getCopy() {
|
||||
AbilityActivated res = new AbilityGrindstone(getSourceCard(),
|
||||
getPayCosts(), getTarget() == null ? null : new Target(getTarget()));
|
||||
CardFactoryUtil.copySpellAbility(this, res);
|
||||
CardFactory.copySpellAbility(this, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -118,7 +118,7 @@ class CardFactoryArtifacts {
|
||||
public AbilityActivated getCopy() {
|
||||
AbilityActivated res = new AbilityScrollRack(getSourceCard(),
|
||||
getPayCosts(), getTarget() == null ? null : new Target(getTarget()));
|
||||
CardFactoryUtil.copySpellAbility(this, res);
|
||||
CardFactory.copySpellAbility(this, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -261,7 +261,7 @@ class CardFactoryArtifacts {
|
||||
public AbilityActivated getCopy() {
|
||||
AbilityActivated res = new AbilityTemporalAperture(getSourceCard(),
|
||||
getPayCosts(), getTarget() == null ? null : new Target(getTarget()));
|
||||
CardFactoryUtil.copySpellAbility(this, res);
|
||||
CardFactory.copySpellAbility(this, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,6 @@ import forge.Constant;
|
||||
import forge.CounterType;
|
||||
import forge.GameEntity;
|
||||
import forge.Singletons;
|
||||
import forge.card.CardCharacteristics;
|
||||
import forge.card.ability.AbilityFactory;
|
||||
import forge.card.ability.AbilityUtils;
|
||||
import forge.card.ability.ApiType;
|
||||
@@ -146,7 +145,7 @@ public class CardFactoryUtil {
|
||||
public AbilityActivated getCopy() {
|
||||
AbilityActivated res = new AbilityUnearth(getSourceCard(),
|
||||
getPayCosts(), getTarget() == null ? null : new Target(getTarget()));
|
||||
CardFactoryUtil.copySpellAbility(this, res);
|
||||
CardFactory.copySpellAbility(this, res);
|
||||
final SpellAbilityRestriction restrict = new SpellAbilityRestriction();
|
||||
restrict.setZone(ZoneType.Graveyard);
|
||||
restrict.setSorcerySpeed(true);
|
||||
@@ -359,7 +358,7 @@ public class CardFactoryUtil {
|
||||
public AbilityActivated getCopy() {
|
||||
AbilityActivated res = new AbilityTransmute(getSourceCard(),
|
||||
getPayCosts(), getTarget() == null ? null : new Target(getTarget()));
|
||||
CardFactoryUtil.copySpellAbility(this, res);
|
||||
CardFactory.copySpellAbility(this, res);
|
||||
res.getRestrictions().setZone(ZoneType.Hand);
|
||||
return res;
|
||||
}
|
||||
@@ -2488,7 +2487,7 @@ public class CardFactoryUtil {
|
||||
|
||||
final int multiplier = controller.getTokenDoublersMagnitude();
|
||||
for (int i = 0; i < multiplier; i++) {
|
||||
Card temp = CardFactoryUtil.copyStats(c);
|
||||
Card temp = CardFactory.copyStats(c);
|
||||
|
||||
for (final String kw : intrinsicKeywords) {
|
||||
temp.addIntrinsicKeyword(kw);
|
||||
@@ -2669,112 +2668,6 @@ public class CardFactoryUtil {
|
||||
|| (c == CounterType.TIME);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Copies stats like power, toughness, etc.
|
||||
* </p>
|
||||
*
|
||||
* @param sim
|
||||
* a {@link java.lang.Object} object.
|
||||
* @return a {@link forge.Card} object.
|
||||
*/
|
||||
public static Card copyStats(final Card sim) {
|
||||
final Card c = new Card();
|
||||
|
||||
c.setFlipCard(sim.isFlipCard());
|
||||
c.setDoubleFaced(sim.isDoubleFaced());
|
||||
c.setCurSetCode(sim.getCurSetCode());
|
||||
|
||||
final CardCharacteristicName origState = sim.getCurState();
|
||||
for (final CardCharacteristicName state : sim.getStates()) {
|
||||
c.addAlternateState(state);
|
||||
c.setState(state);
|
||||
sim.setState(state);
|
||||
CardFactoryUtil.copyCharacteristics(sim, c);
|
||||
}
|
||||
|
||||
sim.setState(origState);
|
||||
c.setState(origState);
|
||||
c.setRules(sim.getRules());
|
||||
|
||||
return c;
|
||||
} // copyStats()
|
||||
|
||||
/**
|
||||
* Copy characteristics.
|
||||
*
|
||||
* @param from
|
||||
* the from
|
||||
* @param to
|
||||
* the to
|
||||
*/
|
||||
public static void copyCharacteristics(final Card from, final Card to) {
|
||||
to.setBaseAttack(from.getBaseAttack());
|
||||
to.setBaseDefense(from.getBaseDefense());
|
||||
to.setBaseLoyalty(from.getBaseLoyalty());
|
||||
to.setBaseAttackString(from.getBaseAttackString());
|
||||
to.setBaseDefenseString(from.getBaseDefenseString());
|
||||
to.setIntrinsicKeyword(from.getIntrinsicKeyword());
|
||||
to.setName(from.getName());
|
||||
to.setType(from.getCharacteristics().getType());
|
||||
to.setText(from.getSpellText());
|
||||
to.setManaCost(from.getManaCost());
|
||||
to.setColor(from.getColor());
|
||||
to.setSVars(from.getSVars());
|
||||
to.setIntrinsicAbilities(from.getIntrinsicAbilities());
|
||||
|
||||
to.setImageFilename(from.getImageFilename());
|
||||
to.setTriggers(from.getTriggers());
|
||||
to.setReplacementEffects(from.getReplacementEffects());
|
||||
to.setStaticAbilityStrings(from.getStaticAbilityStrings());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy characteristics.
|
||||
*
|
||||
* @param from
|
||||
* the from
|
||||
* @param stateToCopy
|
||||
* the state to copy
|
||||
* @param to
|
||||
* the to
|
||||
*/
|
||||
public static void copyState(final Card from, final CardCharacteristicName stateToCopy, final Card to) {
|
||||
|
||||
// copy characteristics not associated with a state
|
||||
to.setBaseLoyalty(from.getBaseLoyalty());
|
||||
to.setBaseAttackString(from.getBaseAttackString());
|
||||
to.setBaseDefenseString(from.getBaseDefenseString());
|
||||
to.setText(from.getSpellText());
|
||||
|
||||
// get CardCharacteristics for desired state
|
||||
CardCharacteristics characteristics = from.getState(stateToCopy);
|
||||
to.getCharacteristics().copy(characteristics);
|
||||
// handle triggers and replacement effect through Card class interface
|
||||
to.setTriggers(characteristics.getTriggers());
|
||||
to.setReplacementEffects(characteristics.getReplacementEffects());
|
||||
}
|
||||
|
||||
public static void copySpellAbility(SpellAbility from, SpellAbility to) {
|
||||
to.setDescription(from.getDescription());
|
||||
to.setStackDescription(from.getDescription());
|
||||
|
||||
if (from.getSubAbility() != null) {
|
||||
to.setSubAbility(from.getSubAbility().getCopy());
|
||||
}
|
||||
if (from.getRestrictions() != null) {
|
||||
to.setRestrictions(from.getRestrictions());
|
||||
}
|
||||
if (from.getConditions() != null) {
|
||||
to.setConditions(from.getConditions());
|
||||
}
|
||||
|
||||
for (String sVar : from.getSVars()) {
|
||||
to.setSVar(sVar, from.getSVar(sVar));
|
||||
}
|
||||
}
|
||||
|
||||
public static void correctAbilityChainSourceCard(final SpellAbility sa, final Card card) {
|
||||
|
||||
sa.setSourceCard(card);
|
||||
|
||||
@@ -28,7 +28,7 @@ import forge.card.ability.effects.ChangeZoneAllEffect;
|
||||
import forge.card.ability.effects.ChangeZoneEffect;
|
||||
import forge.card.ability.effects.ManaEffect;
|
||||
import forge.card.ability.effects.ManaReflectedEffect;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.cardfactory.CardFactory;
|
||||
import forge.game.player.AIPlayer;
|
||||
|
||||
/**
|
||||
@@ -109,7 +109,7 @@ public final class AbilitySub extends SpellAbility implements java.io.Serializab
|
||||
public AbilitySub getCopy() {
|
||||
Target t = getTarget() == null ? null : new Target(getTarget());
|
||||
AbilitySub res = new AbilitySub(api, getSourceCard(), t, params);
|
||||
CardFactoryUtil.copySpellAbility(this, res);
|
||||
CardFactory.copySpellAbility(this, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
@@ -148,6 +148,9 @@ public class InputControl extends MyObservable implements java.io.Serializable {
|
||||
* @return a {@link forge.control.input.Input} object.
|
||||
*/
|
||||
public final Input getActualInput() {
|
||||
if ( !game.hasMulliganned() )
|
||||
return new InputMulligan();
|
||||
|
||||
final PhaseHandler handler = game.getPhaseHandler();
|
||||
final PhaseType phase = handler.getPhase();
|
||||
final Player playerTurn = handler.getPlayerTurn();
|
||||
|
||||
@@ -174,7 +174,6 @@ public class InputMulligan extends Input {
|
||||
}
|
||||
|
||||
ga.checkStateEffects();
|
||||
Singletons.getModel().getMatch().getInput().clearInput();
|
||||
|
||||
Player next = game.getPhaseHandler().getPlayerTurn();
|
||||
|
||||
@@ -187,7 +186,9 @@ public class InputMulligan extends Input {
|
||||
VField nextField = CMatchUI.SINGLETON_INSTANCE.getFieldViewFor(next);
|
||||
SDisplayUtil.showTab(nextField);
|
||||
|
||||
game.getPhaseHandler().nextPhase();
|
||||
game.setMulliganned(true);
|
||||
Singletons.getModel().getMatch().getInput().clearInput();
|
||||
Singletons.getModel().getMatch().getInput().resetInput();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -19,6 +19,8 @@ import forge.Singletons;
|
||||
import forge.deck.generate.Generate2ColorDeck;
|
||||
import forge.deck.generate.Generate3ColorDeck;
|
||||
import forge.deck.generate.Generate5ColorDeck;
|
||||
import forge.deck.generate.GenerateColoredDeckBase;
|
||||
import forge.deck.generate.GenerateMonoColorDeck;
|
||||
import forge.deck.generate.GenerateThemeDeck;
|
||||
import forge.game.player.PlayerType;
|
||||
import forge.item.CardDb;
|
||||
@@ -67,7 +69,7 @@ public class DeckgenUtil {
|
||||
* @return {@link forge.deck.Deck}
|
||||
*/
|
||||
public static Deck buildColorDeck(final String[] selection, PlayerType pt) {
|
||||
ItemPoolView<CardPrinted> cards = null;
|
||||
|
||||
final Deck deck;
|
||||
|
||||
// Replace "random" with "AI" for deck generation code
|
||||
@@ -75,22 +77,20 @@ public class DeckgenUtil {
|
||||
selection[i] = COLOR_VALS.get(selection[i]);
|
||||
}
|
||||
|
||||
// 2, 3, and 5 colors.
|
||||
if (selection.length == 2) {
|
||||
final Generate2ColorDeck gen = new Generate2ColorDeck(
|
||||
selection[0], selection[1]);
|
||||
cards = gen.get2ColorDeck(60, pt);
|
||||
GenerateColoredDeckBase gen = null;
|
||||
|
||||
if (selection.length == 1) {
|
||||
gen = new GenerateMonoColorDeck(selection[0]);
|
||||
} else if (selection.length == 2) {
|
||||
gen = new Generate2ColorDeck(selection[0], selection[1]);
|
||||
} else if (selection.length == 3) {
|
||||
gen = new Generate3ColorDeck(selection[0], selection[1], selection[2]);
|
||||
} else {
|
||||
gen = new Generate5ColorDeck();
|
||||
}
|
||||
else if (selection.length == 3) {
|
||||
final Generate3ColorDeck gen = new Generate3ColorDeck(
|
||||
selection[0], selection[1], selection[2]);
|
||||
cards = gen.get3ColorDeck(60, pt);
|
||||
}
|
||||
else {
|
||||
final Generate5ColorDeck gen = new Generate5ColorDeck();
|
||||
cards = gen.get5ColorDeck(60, pt);
|
||||
}
|
||||
|
||||
|
||||
ItemPoolView<CardPrinted> cards = gen == null ? null : gen.getDeck(60, pt);
|
||||
|
||||
// After generating card lists, build deck.
|
||||
deck = new Deck();
|
||||
deck.getMain().addAll(cards);
|
||||
@@ -132,8 +132,8 @@ public class DeckgenUtil {
|
||||
|
||||
/** @return {@link forge.deck.Deck} */
|
||||
public static Deck getRandomColorDeck(PlayerType pt) {
|
||||
final int[] colorCount = new int[] {2, 3, 5};
|
||||
final int count = colorCount[(int) (Math.round(Math.random() * 2))];
|
||||
final int[] colorCount = new int[] {1, 2, 3, 5};
|
||||
final int count = colorCount[MyRandom.getRandom().nextInt(colorCount.length)];
|
||||
final String[] selection = new String[count];
|
||||
|
||||
// A simulated selection of "random 1" will trigger the AI selection process.
|
||||
@@ -288,14 +288,7 @@ public class DeckgenUtil {
|
||||
public static boolean colorCheck(final String[] colors0) {
|
||||
boolean result = true;
|
||||
|
||||
if (colors0.length == 1) {
|
||||
JOptionPane.showMessageDialog(null,
|
||||
"Sorry, single color generated decks aren't supported yet."
|
||||
+ "\n\rPlease choose at least one more color for this deck.",
|
||||
"Generate deck: 1 color", JOptionPane.ERROR_MESSAGE);
|
||||
result = false;
|
||||
}
|
||||
else if (colors0.length == 4) {
|
||||
if (colors0.length == 4) {
|
||||
JOptionPane.showMessageDialog(null,
|
||||
"Sorry, four color generated decks aren't supported yet."
|
||||
+ "\n\rPlease use 2, 3, or 5 colors for this deck.",
|
||||
|
||||
@@ -76,7 +76,7 @@ public class Generate2ColorDeck extends GenerateColoredDeckBase {
|
||||
}
|
||||
|
||||
|
||||
public final ItemPoolView<CardPrinted> get2ColorDeck(final int size, final PlayerType pt) {
|
||||
public final ItemPoolView<CardPrinted> getDeck(final int size, final PlayerType pt) {
|
||||
addCreaturesAndSpells(size, cmcLevels, cmcAmounts, pt);
|
||||
|
||||
// Add lands
|
||||
|
||||
@@ -75,7 +75,7 @@ public class Generate3ColorDeck extends GenerateColoredDeckBase {
|
||||
* the pt
|
||||
* @return a {@link forge.CardList} object.
|
||||
*/
|
||||
public final ItemPoolView<CardPrinted> get3ColorDeck(final int size, final PlayerType pt) {
|
||||
public final ItemPoolView<CardPrinted> getDeck(final int size, final PlayerType pt) {
|
||||
addCreaturesAndSpells(size, cmcLevels, cmcAmounts, pt);
|
||||
|
||||
// Add lands
|
||||
|
||||
@@ -65,7 +65,7 @@ public class Generate5ColorDeck extends GenerateColoredDeckBase {
|
||||
* a PlayerType
|
||||
* @return a {@link forge.CardList} object.
|
||||
*/
|
||||
public final ItemPoolView<CardPrinted> get5ColorDeck(final int size, final PlayerType pt) {
|
||||
public final ItemPoolView<CardPrinted> getDeck(final int size, final PlayerType pt) {
|
||||
addCreaturesAndSpells(size, cmcLevels, cmcAmounts, pt);
|
||||
|
||||
// Add lands
|
||||
|
||||
@@ -40,6 +40,7 @@ import forge.game.player.PlayerType;
|
||||
import forge.item.CardDb;
|
||||
import forge.item.CardPrinted;
|
||||
import forge.item.ItemPool;
|
||||
import forge.item.ItemPoolView;
|
||||
import forge.properties.ForgePreferences.FPref;
|
||||
import forge.util.Aggregates;
|
||||
import forge.util.MyRandom;
|
||||
@@ -88,6 +89,9 @@ public abstract class GenerateColoredDeckBase {
|
||||
addCmcAdjusted(spells, spellCnt, cmcLevels, cmcAmounts);
|
||||
}
|
||||
|
||||
public ItemPoolView<CardPrinted> getDeck(final int size, final PlayerType pt) {
|
||||
return null; // all but theme deck do override this method
|
||||
}
|
||||
|
||||
protected void addSome(int cnt, List<CardPrinted> source) {
|
||||
for (int i = 0; i < cnt; i++) {
|
||||
|
||||
94
src/main/java/forge/deck/generate/GenerateMonoColorDeck.java
Normal file
94
src/main/java/forge/deck/generate/GenerateMonoColorDeck.java
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* 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.deck.generate;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import forge.card.ColorSet;
|
||||
import forge.card.MagicColor;
|
||||
import forge.deck.generate.GenerateDeckUtil.FilterCMC;
|
||||
import forge.game.player.PlayerType;
|
||||
import forge.item.CardPrinted;
|
||||
import forge.item.ItemPoolView;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Generate2ColorDeck class.
|
||||
* </p>
|
||||
*
|
||||
* @author Forge
|
||||
* @version $Id: Generate2ColorDeck.java 19765 2013-02-20 03:01:37Z myk $
|
||||
*/
|
||||
public class GenerateMonoColorDeck extends GenerateColoredDeckBase {
|
||||
@Override protected final float getLandsPercentage() { return 0.39f; }
|
||||
@Override protected final float getCreatPercentage() { return 0.36f; }
|
||||
@Override protected final float getSpellPercentage() { return 0.25f; }
|
||||
|
||||
final List<FilterCMC> cmcLevels = Arrays.asList(
|
||||
new GenerateDeckUtil.FilterCMC(0, 2),
|
||||
new GenerateDeckUtil.FilterCMC(3, 4),
|
||||
new GenerateDeckUtil.FilterCMC(5, 6),
|
||||
new GenerateDeckUtil.FilterCMC(7, 20));
|
||||
final int[] cmcAmounts = {10, 8, 5, 3};
|
||||
|
||||
// mana curve of the card pool
|
||||
// 20x 0 - 2
|
||||
// 16x 3 - 4
|
||||
// 12x 5 - 6
|
||||
// 4x 7 - 20
|
||||
// = 52x - card pool (before further random filtering)
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Constructor for Generate2ColorDeck.
|
||||
* </p>
|
||||
*
|
||||
* @param clr1
|
||||
* a {@link java.lang.String} object.
|
||||
* @param clr2
|
||||
* a {@link java.lang.String} object.
|
||||
*/
|
||||
public GenerateMonoColorDeck(final String clr1) {
|
||||
|
||||
if (clr1.equals("AI")) {
|
||||
int color1 = r.nextInt(5);
|
||||
colors = ColorSet.fromMask(MagicColor.WHITE << color1);
|
||||
} else {
|
||||
colors = ColorSet.fromNames(clr1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public final ItemPoolView<CardPrinted> getDeck(final int size, final PlayerType pt) {
|
||||
addCreaturesAndSpells(size, cmcLevels, cmcAmounts, pt);
|
||||
|
||||
// Add lands
|
||||
int numLands = (int) (getLandsPercentage() * size);
|
||||
|
||||
tmpDeck.append("numLands:").append(numLands).append("\n");
|
||||
|
||||
addBasicLand(numLands);
|
||||
tmpDeck.append("DeckSize:").append(tDeck.countAll()).append("\n");
|
||||
|
||||
adjustDeckSize(size);
|
||||
tmpDeck.append("DeckSize:").append(tDeck.countAll()).append("\n");
|
||||
|
||||
return tDeck;
|
||||
}
|
||||
}
|
||||
@@ -38,6 +38,7 @@ import forge.GameEntity;
|
||||
import forge.card.CardSplitType;
|
||||
import forge.card.CardType;
|
||||
import forge.card.ability.effects.AttachEffect;
|
||||
import forge.card.cardfactory.CardFactory;
|
||||
import forge.card.cost.Cost;
|
||||
import forge.card.mana.ManaCost;
|
||||
import forge.card.replacement.ReplacementEffect;
|
||||
@@ -159,7 +160,7 @@ public class GameAction {
|
||||
if (zoneFrom.is(ZoneType.Battlefield)) {
|
||||
c.setFlipStaus(false);
|
||||
}
|
||||
copied = forge.Singletons.getModel().getCardFactory().copyCard(c);
|
||||
copied = CardFactory.copyCard(c);
|
||||
copied.setUnearthed(c.isUnearthed());
|
||||
copied.setTapped(false);
|
||||
for (final Trigger trigger : copied.getTriggers()) {
|
||||
@@ -671,7 +672,7 @@ public class GameAction {
|
||||
if (p != null && p.is(ZoneType.Battlefield)) {
|
||||
lastKnownInfo = CardUtil.getLKICopy(c);
|
||||
c.clearCounters(); // remove all counters
|
||||
library.add(forge.Singletons.getModel().getCardFactory().copyCard(c), libPosition);
|
||||
library.add(CardFactory.copyCard(c), libPosition);
|
||||
} else {
|
||||
c.clearCounters(); // remove all counters
|
||||
library.add(c, libPosition);
|
||||
|
||||
@@ -73,6 +73,9 @@ public class GameActionPlay {
|
||||
* a {@link forge.card.spellability.SpellAbility} object.
|
||||
*/
|
||||
public final void playSpellAbilityForFree(final SpellAbility sa) {
|
||||
final Card source = sa.getSourceCard();
|
||||
setSplitCardState(source, sa); // Split card support
|
||||
|
||||
if (sa.getPayCosts() != null) {
|
||||
if (sa.getApi() == ApiType.Charm && !sa.isWrapper()) {
|
||||
CharmEffect.makeChoices(sa);
|
||||
@@ -180,23 +183,20 @@ public class GameActionPlay {
|
||||
List<Card> untappedCreats = CardLists.filter(spell.getActivatingPlayer().getCardsIn(ZoneType.Battlefield), CardPredicates.Presets.CREATURES);
|
||||
untappedCreats = CardLists.filter(untappedCreats, CardPredicates.Presets.UNTAPPED);
|
||||
|
||||
if (untappedCreats.size() != 0) {
|
||||
if (!untappedCreats.isEmpty()) {
|
||||
final List<Card> choices = new ArrayList<Card>();
|
||||
for (final Card c : untappedCreats) {
|
||||
choices.add(c);
|
||||
}
|
||||
choices.addAll(untappedCreats);
|
||||
ArrayList<String> usableColors = new ArrayList<String>();
|
||||
ManaCostBeingPaid newCost = new ManaCostBeingPaid(originalCost.toString());
|
||||
Card tapForConvoke = null;
|
||||
if (sa.getActivatingPlayer().isHuman()) {
|
||||
tapForConvoke = GuiChoose.oneOrNone("Tap for Convoke? " + newCost.toString(),
|
||||
choices);
|
||||
tapForConvoke = GuiChoose.oneOrNone("Tap for Convoke? " + newCost.toString(), choices);
|
||||
} else {
|
||||
// TODO: AI to choose a creature to tap would go here
|
||||
// Probably along with deciding how many creatures to
|
||||
// tap
|
||||
}
|
||||
while (tapForConvoke != null && untappedCreats.size() != 0) {
|
||||
while (tapForConvoke != null && !untappedCreats.isEmpty()) {
|
||||
final Card workingCard = (Card) tapForConvoke;
|
||||
usableColors = GameActionPlay.getConvokableColors(workingCard, newCost);
|
||||
|
||||
@@ -223,7 +223,7 @@ public class GameActionPlay {
|
||||
sa.addTappedForConvoke(workingCard);
|
||||
choices.remove(workingCard);
|
||||
untappedCreats.remove(workingCard);
|
||||
if ((choices.size() < 2) || (newCost.getConvertedManaCost() == 0)) {
|
||||
if (choices.isEmpty() || (newCost.getConvertedManaCost() == 0)) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
@@ -239,7 +239,7 @@ public class GameActionPlay {
|
||||
}
|
||||
|
||||
// will only be null if user cancelled.
|
||||
if (tapForConvoke != null) {
|
||||
if (!sa.getTappedForConvoke().isEmpty()) {
|
||||
// Convoked creats are tapped here with triggers
|
||||
// suppressed,
|
||||
// Then again when payment is done(In
|
||||
|
||||
@@ -23,16 +23,12 @@ import forge.CardUtil;
|
||||
import forge.Singletons;
|
||||
import forge.card.trigger.TriggerHandler;
|
||||
import forge.card.trigger.TriggerType;
|
||||
import forge.control.input.Input;
|
||||
import forge.control.input.InputControl;
|
||||
import forge.control.input.InputMulligan;
|
||||
import forge.deck.CardPool;
|
||||
import forge.deck.Deck;
|
||||
import forge.deck.DeckSection;
|
||||
import forge.error.BugReporter;
|
||||
import forge.game.event.FlipCoinEvent;
|
||||
import forge.game.phase.PhaseHandler;
|
||||
import forge.game.phase.PhaseType;
|
||||
import forge.game.player.AIPlayer;
|
||||
import forge.game.player.LobbyPlayer;
|
||||
import forge.game.player.Player;
|
||||
@@ -195,8 +191,6 @@ public class GameNew {
|
||||
removedAnteCards.put(player, myRemovedAnteCards);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (rAICards.size() > 0) {
|
||||
String message = buildFourColumnList("AI deck contains the following cards that it can't play or may be buggy:", rAICards);
|
||||
if (GameType.Quest == game.getType()) {
|
||||
@@ -215,7 +209,116 @@ public class GameNew {
|
||||
JOptionPane.showMessageDialog(null, ante.toString(), "", JOptionPane.INFORMATION_MESSAGE);
|
||||
}
|
||||
|
||||
GameNew.actuateGame(match, game, false);
|
||||
// Deciding which cards go to ante
|
||||
if (preferences.getPrefBoolean(FPref.UI_ANTE)) {
|
||||
final String nl = System.getProperty("line.separator");
|
||||
final StringBuilder msg = new StringBuilder();
|
||||
for (final Player p : game.getPlayers()) {
|
||||
|
||||
final List<Card> lib = p.getCardsIn(ZoneType.Library);
|
||||
Predicate<Card> goodForAnte = Predicates.not(CardPredicates.Presets.BASIC_LANDS);
|
||||
Card ante = Aggregates.random(Iterables.filter(lib, goodForAnte));
|
||||
if (ante == null) {
|
||||
throw new RuntimeException(p + " library is empty.");
|
||||
}
|
||||
game.getGameLog().add("Ante", p + " anted " + ante, 0);
|
||||
VAntes.SINGLETON_INSTANCE.addAnteCard(p, ante);
|
||||
game.getAction().moveTo(ZoneType.Ante, ante);
|
||||
msg.append(p.getName()).append(" ante: ").append(ante).append(nl);
|
||||
}
|
||||
JOptionPane.showMessageDialog(null, msg, "Ante", JOptionPane.INFORMATION_MESSAGE);
|
||||
}
|
||||
|
||||
determineFirstTurnPlayer(match.getLastGameOutcome(), game);
|
||||
|
||||
// Draw <handsize> cards
|
||||
for (final Player p1 : game.getPlayers()) {
|
||||
p1.drawCards(p1.getMaxHandSize());
|
||||
}
|
||||
|
||||
Thread thGame = new GameInputUpdatesThread(match, game);
|
||||
thGame.setName("Game input updater");
|
||||
thGame.start();
|
||||
}
|
||||
|
||||
// ultimate of Karn the Liberated
|
||||
public static void restartGame(final MatchController match, final GameState game, final Player startingTurn, Map<Player, List<Card>> playerLibraries) {
|
||||
|
||||
Map<LobbyPlayer, PlayerStartConditions> players = match.getPlayers();
|
||||
Map<Player, PlayerStartConditions> playersConditions = new HashMap<Player, PlayerStartConditions>();
|
||||
|
||||
for (Player p : game.getPlayers()) {
|
||||
playersConditions.put(p, players.get(p.getLobbyPlayer()));
|
||||
}
|
||||
|
||||
game.setMulliganned(false);
|
||||
match.getInput().clearInput();
|
||||
|
||||
//Card.resetUniqueNumber();
|
||||
// need this code here, otherwise observables fail
|
||||
forge.card.trigger.Trigger.resetIDs();
|
||||
TriggerHandler trigHandler = game.getTriggerHandler();
|
||||
trigHandler.clearTriggerSettings();
|
||||
trigHandler.clearDelayedTrigger();
|
||||
trigHandler.cleanUpTemporaryTriggers();
|
||||
trigHandler.suppressMode(TriggerType.ChangesZone);
|
||||
|
||||
game.getStack().reset();
|
||||
GameAction action = game.getAction();
|
||||
|
||||
|
||||
for (Entry<Player, PlayerStartConditions> p : playersConditions.entrySet()) {
|
||||
final Player player = p.getKey();
|
||||
player.setStartingLife(p.getValue().getStartingLife());
|
||||
player.setNumLandsPlayed(0);
|
||||
putCardsOnBattlefield(player, p.getValue().getCardsOnBattlefield(player));
|
||||
|
||||
PlayerZone library = player.getZone(ZoneType.Library);
|
||||
List<Card> newLibrary = playerLibraries.get(player);
|
||||
for (Card c : newLibrary) {
|
||||
action.moveTo(library, c);
|
||||
}
|
||||
|
||||
player.shuffle();
|
||||
player.getZone(ZoneType.Battlefield).updateObservers();
|
||||
player.updateObservers();
|
||||
player.getZone(ZoneType.Hand).updateObservers();
|
||||
}
|
||||
|
||||
trigHandler.clearSuppression(TriggerType.ChangesZone);
|
||||
|
||||
PhaseHandler phaseHandler = game.getPhaseHandler();
|
||||
phaseHandler.setPlayerTurn(startingTurn);
|
||||
|
||||
// Draw <handsize> cards
|
||||
for (final Player p : game.getPlayers()) {
|
||||
p.drawCards(p.getMaxHandSize());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for this method.
|
||||
* @param match
|
||||
* @param game
|
||||
*/
|
||||
private static void determineFirstTurnPlayer(final GameOutcome lastGameOutcome, final GameState game) {
|
||||
// Only cut/coin toss if it's the first game of the match
|
||||
Player goesFirst;
|
||||
Player humanPlayer = Singletons.getControl().getPlayer();
|
||||
boolean isFirstGame = lastGameOutcome == null;
|
||||
if (isFirstGame) {
|
||||
goesFirst = GameNew.seeWhoPlaysFirstDice(game);
|
||||
} else {
|
||||
|
||||
goesFirst = lastGameOutcome.isWinner(humanPlayer.getLobbyPlayer()) ? humanPlayer.getOpponent() : humanPlayer;
|
||||
}
|
||||
String message = goesFirst + ( isFirstGame ? " has won the coin toss." : " lost the last game.");
|
||||
boolean willPlay = goesFirst.getController().getWillPlayOnFirstTurn(message);
|
||||
if ( goesFirst != humanPlayer ) {
|
||||
JOptionPane.showMessageDialog(null, message + "\nComputer Going First", "You are drawing", JOptionPane.INFORMATION_MESSAGE);
|
||||
}
|
||||
goesFirst = willPlay ? goesFirst : goesFirst.getOpponent();
|
||||
game.getPhaseHandler().setPlayerTurn(goesFirst);
|
||||
}
|
||||
|
||||
private static void initVariantsZones(final Player player, final PlayerStartConditions psc) {
|
||||
@@ -283,128 +386,6 @@ public class GameNew {
|
||||
|
||||
}
|
||||
|
||||
// ultimate of Karn the Liberated
|
||||
public static void restartGame(final MatchController match, final GameState game, final Player startingTurn, Map<Player, List<Card>> playerLibraries) {
|
||||
|
||||
Map<LobbyPlayer, PlayerStartConditions> players = match.getPlayers();
|
||||
Map<Player, PlayerStartConditions> playersConditions = new HashMap<Player, PlayerStartConditions>();
|
||||
|
||||
for (Player p : game.getPlayers()) {
|
||||
playersConditions.put(p, players.get(p.getLobbyPlayer()));
|
||||
}
|
||||
|
||||
match.getInput().clearInput();
|
||||
|
||||
//Card.resetUniqueNumber();
|
||||
// need this code here, otherwise observables fail
|
||||
forge.card.trigger.Trigger.resetIDs();
|
||||
TriggerHandler trigHandler = game.getTriggerHandler();
|
||||
trigHandler.clearTriggerSettings();
|
||||
trigHandler.clearDelayedTrigger();
|
||||
trigHandler.cleanUpTemporaryTriggers();
|
||||
trigHandler.suppressMode(TriggerType.ChangesZone);
|
||||
|
||||
game.getStack().reset();
|
||||
GameAction action = game.getAction();
|
||||
|
||||
|
||||
for (Entry<Player, PlayerStartConditions> p : playersConditions.entrySet()) {
|
||||
final Player player = p.getKey();
|
||||
player.setStartingLife(p.getValue().getStartingLife());
|
||||
player.setNumLandsPlayed(0);
|
||||
putCardsOnBattlefield(player, p.getValue().getCardsOnBattlefield(player));
|
||||
|
||||
PlayerZone library = player.getZone(ZoneType.Library);
|
||||
List<Card> newLibrary = playerLibraries.get(player);
|
||||
for (Card c : newLibrary) {
|
||||
action.moveTo(library, c);
|
||||
}
|
||||
|
||||
player.shuffle();
|
||||
player.getZone(ZoneType.Battlefield).updateObservers();
|
||||
player.updateObservers();
|
||||
player.getZone(ZoneType.Hand).updateObservers();
|
||||
}
|
||||
|
||||
trigHandler.clearSuppression(TriggerType.ChangesZone);
|
||||
|
||||
PhaseHandler phaseHandler = game.getPhaseHandler();
|
||||
phaseHandler.setPlayerTurn(startingTurn);
|
||||
|
||||
GameNew.actuateGame(match, game, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* This must be separated from the newGame method since life totals and
|
||||
* player details could be adjusted before the game is started.
|
||||
*
|
||||
* That process (also cleanup and observer updates) should be done in
|
||||
* newGame, then when all is ready, call this function.
|
||||
* @param isRestartedGame Whether the actuated game is the first start or a restart
|
||||
*/
|
||||
private static void actuateGame(final MatchController match, final GameState game, boolean isRestartedGame) {
|
||||
if (!isRestartedGame) {
|
||||
// Deciding which cards go to ante
|
||||
if (preferences.getPrefBoolean(FPref.UI_ANTE)) {
|
||||
final String nl = System.getProperty("line.separator");
|
||||
final StringBuilder msg = new StringBuilder();
|
||||
for (final Player p : game.getPlayers()) {
|
||||
|
||||
final List<Card> lib = p.getCardsIn(ZoneType.Library);
|
||||
Predicate<Card> goodForAnte = Predicates.not(CardPredicates.Presets.BASIC_LANDS);
|
||||
Card ante = Aggregates.random(Iterables.filter(lib, goodForAnte));
|
||||
if (ante == null) {
|
||||
throw new RuntimeException(p + " library is empty.");
|
||||
}
|
||||
game.getGameLog().add("Ante", p + " anted " + ante, 0);
|
||||
VAntes.SINGLETON_INSTANCE.addAnteCard(p, ante);
|
||||
game.getAction().moveTo(ZoneType.Ante, ante);
|
||||
msg.append(p.getName()).append(" ante: ").append(ante).append(nl);
|
||||
}
|
||||
JOptionPane.showMessageDialog(null, msg, "Ante", JOptionPane.INFORMATION_MESSAGE);
|
||||
}
|
||||
|
||||
GameOutcome lastGameOutcome = match.getLastGameOutcome();
|
||||
// Only cut/coin toss if it's the first game of the match
|
||||
Player goesFirst;
|
||||
Player humanPlayer = Singletons.getControl().getPlayer();
|
||||
boolean isFirstGame = lastGameOutcome == null;
|
||||
if (isFirstGame) {
|
||||
goesFirst = GameNew.seeWhoPlaysFirstDice(game);
|
||||
} else {
|
||||
|
||||
goesFirst = lastGameOutcome.isWinner(humanPlayer.getLobbyPlayer()) ? humanPlayer.getOpponent() : humanPlayer;
|
||||
}
|
||||
String message = goesFirst + ( isFirstGame ? " has won the coin toss." : " lost the last game.");
|
||||
boolean willPlay = goesFirst.getController().getWillPlayOnFirstTurn(message);
|
||||
if ( goesFirst != humanPlayer ) {
|
||||
JOptionPane.showMessageDialog(null, message + "\nComputer Going First", "You are drawing", JOptionPane.INFORMATION_MESSAGE);
|
||||
}
|
||||
goesFirst = willPlay ? goesFirst : goesFirst.getOpponent();
|
||||
game.getPhaseHandler().setPlayerTurn(goesFirst);
|
||||
}
|
||||
|
||||
// Draw <handsize> cards
|
||||
for (final Player p : game.getPlayers()) {
|
||||
p.drawCards(p.getMaxHandSize());
|
||||
}
|
||||
|
||||
|
||||
|
||||
game.getPhaseHandler().setPhaseState(PhaseType.MULLIGAN);
|
||||
|
||||
InputControl control = match.getInput();
|
||||
Input tmp = new InputMulligan();
|
||||
control.setInput(tmp);
|
||||
|
||||
|
||||
Thread thGame = new GameInputUpdatesThread(match, game);
|
||||
|
||||
match.getInput().getInput().showMessage();
|
||||
thGame.setName("Game input updater");
|
||||
thGame.start();
|
||||
} // newGame()
|
||||
|
||||
private static String buildFourColumnList(String firstLine, Iterable<CardPrinted> cAnteRemoved) {
|
||||
StringBuilder sb = new StringBuilder(firstLine);
|
||||
int i = 0;
|
||||
|
||||
@@ -666,4 +666,8 @@ public class GameState {
|
||||
// TODO Auto-generated method stub
|
||||
return actionPlay;
|
||||
}
|
||||
|
||||
public boolean mulliganned = false;
|
||||
public boolean hasMulliganned(){ return mulliganned; }
|
||||
public void setMulliganned(boolean value) { mulliganned = value; }
|
||||
}
|
||||
|
||||
@@ -48,7 +48,6 @@ import forge.game.GameActionUtil;
|
||||
import forge.game.GameState;
|
||||
import forge.game.GlobalRuleChange;
|
||||
import forge.game.ai.ComputerUtil;
|
||||
import forge.game.ai.ComputerUtilBlock;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.ai.ComputerUtilCost;
|
||||
import forge.game.player.AIPlayer;
|
||||
@@ -57,7 +56,6 @@ import forge.game.zone.PlayerZone;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.gui.GuiChoose;
|
||||
import forge.gui.GuiDialog;
|
||||
import forge.gui.GuiUtils;
|
||||
import forge.gui.framework.EDocID;
|
||||
import forge.gui.framework.SDisplayUtil;
|
||||
import forge.gui.match.views.VCombat;
|
||||
@@ -431,21 +429,8 @@ public class CombatUtil {
|
||||
if (blockers.size() <= 1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
List<Card> orderedBlockers = null;
|
||||
if (player.isHuman()) {
|
||||
GuiUtils.setPanelSelection(attacker);
|
||||
List<Card> ordered = GuiChoose.order("Choose Blocking Order", "Damaged First", 0, blockers, null, attacker);
|
||||
|
||||
orderedBlockers = new ArrayList<Card>();
|
||||
for (Object o : ordered) {
|
||||
orderedBlockers.add((Card) o);
|
||||
}
|
||||
}
|
||||
else {
|
||||
orderedBlockers = ComputerUtilBlock.orderBlockers(attacker, blockers);
|
||||
}
|
||||
combat.setBlockerList(attacker, orderedBlockers);
|
||||
List<Card> orderedBlockers = player.getController().orderBlockers(attacker, blockers);
|
||||
combat.setBlockerList(attacker, orderedBlockers);
|
||||
}
|
||||
CombatUtil.showCombat();
|
||||
// Refresh Combat Panel
|
||||
@@ -459,19 +444,7 @@ public class CombatUtil {
|
||||
continue;
|
||||
}
|
||||
|
||||
List<Card> orderedAttacker = null;
|
||||
if (blocker.getController().isHuman()) {
|
||||
GuiUtils.setPanelSelection(blocker);
|
||||
List<Card> ordered = GuiChoose.order("Choose Blocking Order", "Damaged First", 0, attackers, null, blocker);
|
||||
|
||||
orderedAttacker = new ArrayList<Card>();
|
||||
for (Object o : ordered) {
|
||||
orderedAttacker.add((Card) o);
|
||||
}
|
||||
}
|
||||
else {
|
||||
orderedAttacker = ComputerUtilBlock.orderAttackers(blocker, attackers);
|
||||
}
|
||||
List<Card> orderedAttacker = blocker.getController().getController().orderAttackers(blocker, attackers);
|
||||
combat.setAttackersBlockedByList(blocker, orderedAttacker);
|
||||
}
|
||||
CombatUtil.showCombat();
|
||||
|
||||
@@ -52,9 +52,9 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
|
||||
/** Constant <code>serialVersionUID=5207222278370963197L</code>. */
|
||||
private static final long serialVersionUID = 5207222278370963197L;
|
||||
|
||||
private PhaseType phase = PhaseType.MULLIGAN;
|
||||
private int turn = 0;
|
||||
// Start turn at 0, so first untap step will turn it to 1
|
||||
private PhaseType phase = PhaseType.UNTAP;
|
||||
private int turn = 1;
|
||||
// Start turn at 1, since first untap is where we start
|
||||
|
||||
private final transient Stack<ExtraTurn> extraTurns = new Stack<ExtraTurn>();
|
||||
private final transient Map<PhaseType, Stack<PhaseType>> extraPhases = new HashMap<PhaseType, Stack<PhaseType>>();
|
||||
@@ -262,7 +262,7 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
|
||||
break;
|
||||
|
||||
case DRAW:
|
||||
if (getTurn() == 1 || PhaseUtil.skipDraw(this.getPlayerTurn())) {
|
||||
if (getTurn() == 1 || this.getPlayerTurn().isSkippingDraw()) {
|
||||
this.setPlayersPriorityPermission(false);
|
||||
} else {
|
||||
this.getPlayerTurn().drawCards(1, true);
|
||||
|
||||
@@ -9,8 +9,6 @@ import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
|
||||
public enum PhaseType {
|
||||
MULLIGAN("Mulligan"),
|
||||
// Note: Mulligan is not part of "All Phases" which are strictly ingame phases
|
||||
UNTAP("Untap"),
|
||||
UPKEEP("Upkeep"),
|
||||
DRAW("Draw"),
|
||||
|
||||
@@ -114,28 +114,7 @@ public class PhaseUtil {
|
||||
game.getPhaseHandler().setPlayersPriorityPermission(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* skipDraw.
|
||||
* </p>
|
||||
*
|
||||
* @param player
|
||||
* a {@link forge.game.player.Player} object.
|
||||
* @return a boolean.
|
||||
*/
|
||||
public static boolean skipDraw(final Player player) {
|
||||
|
||||
if (player.hasKeyword("Skip your next draw step.")) {
|
||||
player.removeKeyword("Skip your next draw step.");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (player.hasKeyword("Skip your draw step.")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// ********* Declare Attackers ***********
|
||||
|
||||
|
||||
@@ -354,13 +354,14 @@ public class Upkeep extends Phase {
|
||||
final Command paidCommand = Command.BLANK;
|
||||
|
||||
final Ability blankAbility = Upkeep.BlankAbility(c, upkeepCost);
|
||||
blankAbility.setActivatingPlayer(controller);
|
||||
|
||||
final Ability upkeepAbility = new Ability(c, ManaCost.ZERO) {
|
||||
@Override
|
||||
public void resolve() {
|
||||
if (controller.isHuman()) {
|
||||
GameActionUtil.payCostDuringAbilityResolve(controller, blankAbility, blankAbility.getPayCosts(),
|
||||
paidCommand, unpaidCommand, null, game);
|
||||
paidCommand, unpaidCommand, this, game);
|
||||
} else { // computer
|
||||
if (ComputerUtilCost.shouldPayCost(controller, c, upkeepCost) && ComputerUtilCost.canPayCost(blankAbility, controller)) {
|
||||
ComputerUtil.playNoStack((AIPlayer)controller, blankAbility, game);
|
||||
|
||||
@@ -3241,6 +3241,20 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
|
||||
game.getStack().add(miracleTrigger);
|
||||
}
|
||||
|
||||
public boolean isSkippingDraw() {
|
||||
|
||||
if (hasKeyword("Skip your next draw step.")) {
|
||||
removeKeyword("Skip your next draw step.");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (hasKeyword("Skip your draw step.")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for this type.
|
||||
*
|
||||
|
||||
@@ -97,4 +97,7 @@ public abstract class PlayerController {
|
||||
public abstract boolean confirmAction(SpellAbility sa, String mode, String message);
|
||||
public abstract boolean getWillPlayOnFirstTurn(String message);
|
||||
public abstract boolean confirmStaticApplication(Card hostCard, GameEntity affected, String logic, String message);
|
||||
|
||||
public abstract List<Card> orderBlockers(Card attacker, List<Card> blockers);
|
||||
public abstract List<Card> orderAttackers(Card blocker, List<Card> attackers);
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import forge.game.ai.AiController;
|
||||
import forge.game.ai.AiInputBlock;
|
||||
import forge.game.ai.AiInputCommon;
|
||||
import forge.game.ai.ComputerUtil;
|
||||
import forge.game.ai.ComputerUtilBlock;
|
||||
import forge.game.ai.ComputerUtilCombat;
|
||||
import forge.gui.GuiChoose;
|
||||
|
||||
@@ -208,4 +209,14 @@ public class PlayerControllerAi extends PlayerController {
|
||||
return brains.confirmStaticApplication(hostCard, affected, logic, message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Card> orderBlockers(Card attacker, List<Card> blockers) {
|
||||
return ComputerUtilBlock.orderBlockers(attacker, blockers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Card> orderAttackers(Card blocker, List<Card> attackers) {
|
||||
return ComputerUtilBlock.orderAttackers(blocker, attackers);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import forge.game.GameType;
|
||||
import forge.game.phase.PhaseType;
|
||||
import forge.gui.GuiChoose;
|
||||
import forge.gui.GuiDialog;
|
||||
import forge.gui.GuiUtils;
|
||||
import forge.gui.match.CMatchUI;
|
||||
import forge.item.CardPrinted;
|
||||
|
||||
@@ -260,4 +261,16 @@ public class PlayerControllerHuman extends PlayerController {
|
||||
|
||||
return !playDraw.equals(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Card> orderBlockers(Card attacker, List<Card> blockers) {
|
||||
GuiUtils.setPanelSelection(attacker);
|
||||
return GuiChoose.order("Choose Blocking Order", "Damaged First", 0, blockers, null, attacker);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Card> orderAttackers(Card blocker, List<Card> attackers) {
|
||||
GuiUtils.setPanelSelection(blocker);
|
||||
return GuiChoose.order("Choose Blocking Order", "Damaged First", 0, attackers, null, blocker);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ import forge.CardPredicates.Presets;
|
||||
import forge.Command;
|
||||
import forge.Singletons;
|
||||
import forge.card.ability.AbilityUtils;
|
||||
import forge.card.cardfactory.CardFactory;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.mana.ManaCost;
|
||||
import forge.card.mana.ManaCostBeingPaid;
|
||||
@@ -608,7 +609,7 @@ public class MagicStack extends MyObservable {
|
||||
@Override
|
||||
public void execute() {
|
||||
for (int i = 0; i < sp.getSourceCard().getReplicateMagnitude(); i++) {
|
||||
Singletons.getModel().getCardFactory().copySpellontoStack(sp.getSourceCard(), sp.getSourceCard(), sp, false);
|
||||
CardFactory.copySpellontoStack(sp.getSourceCard(), sp.getSourceCard(), sp, false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -36,10 +36,12 @@ import javax.swing.border.EtchedBorder;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import forge.Card;
|
||||
import forge.CardCharacteristicName;
|
||||
import forge.CounterType;
|
||||
import forge.GameEntity;
|
||||
import forge.Singletons;
|
||||
import forge.card.CardEdition;
|
||||
import forge.card.CardSplitType;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.gui.toolbox.FLabel;
|
||||
@@ -202,10 +204,14 @@ public class CardDetailPanel extends FPanel {
|
||||
|
||||
final boolean canShowThis = card.canBeShownTo(Singletons.getControl().getPlayer());
|
||||
if (canShowThis) {
|
||||
if (card.getManaCost().toString().equals("") || card.isLand()) {
|
||||
if (card.getManaCost().isNoCost()) {
|
||||
this.nameCostLabel.setText(card.getName());
|
||||
} else {
|
||||
this.nameCostLabel.setText(card.getName() + " - " + card.getManaCost());
|
||||
String manaCost = card.getManaCost().toString();
|
||||
if ( card.getRules() != null && card.getRules().getSplitType() == CardSplitType.Split && card.getCurState() == CardCharacteristicName.Original) {
|
||||
manaCost = card.getRules().getMainPart().getManaCost().toString() + " // " + card.getRules().getOtherPart().getManaCost().toString();
|
||||
}
|
||||
this.nameCostLabel.setText(card.getName() + " - " + manaCost);
|
||||
}
|
||||
this.typeLabel.setText(GuiDisplayUtil.formatCardType(card));
|
||||
|
||||
|
||||
@@ -431,7 +431,7 @@ public final class GuiDisplayUtil {
|
||||
for (final String element : data) {
|
||||
final String[] cardinfo = element.trim().split("\\|");
|
||||
|
||||
final Card c = Singletons.getModel().getCardFactory().getCard(CardDb.instance().getCard(cardinfo[0]), player);
|
||||
final Card c = CardDb.instance().getCard(cardinfo[0]).toForgeCard(player);
|
||||
|
||||
boolean hasSetCurSet = false;
|
||||
for (final String info : cardinfo) {
|
||||
@@ -596,7 +596,7 @@ public final class GuiDisplayUtil {
|
||||
*/
|
||||
public static void devModeCardToHand() {
|
||||
final List<Player> players = Singletons.getModel().getGame().getPlayers();
|
||||
final Player p = GuiChoose.oneOrNone("Put card in play for which player?", players);
|
||||
final Player p = GuiChoose.oneOrNone("Put card in hand for which player?", players);
|
||||
if (null == p) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ public class InputProxy extends MyObservable implements Observer {
|
||||
* @param in
|
||||
* a {@link forge.control.input.Input} object.
|
||||
*/
|
||||
public void setInput(final Input in) {
|
||||
public final void setInput(final Input in) {
|
||||
valid = true;
|
||||
this.input = in;
|
||||
this.input.showMessage(); // this call may invalidate the input by the time it returns
|
||||
|
||||
@@ -106,15 +106,15 @@ public enum CDeckgen implements ICDoc {
|
||||
switch (colorCount0) {
|
||||
case 2:
|
||||
genConstructed.getMain().addAll(
|
||||
(new Generate2ColorDeck("AI", "AI")).get2ColorDeck(60, PlayerType.HUMAN));
|
||||
(new Generate2ColorDeck("AI", "AI")).getDeck(60, PlayerType.HUMAN));
|
||||
break;
|
||||
case 3:
|
||||
genConstructed.getMain().addAll(
|
||||
(new Generate3ColorDeck("AI", "AI", "AI")).get3ColorDeck(60, PlayerType.HUMAN));
|
||||
(new Generate3ColorDeck("AI", "AI", "AI")).getDeck(60, PlayerType.HUMAN));
|
||||
break;
|
||||
case 5:
|
||||
genConstructed.getMain().addAll(
|
||||
(new Generate5ColorDeck()).get5ColorDeck(60, PlayerType.HUMAN));
|
||||
(new Generate5ColorDeck()).getDeck(60, PlayerType.HUMAN));
|
||||
break;
|
||||
default:
|
||||
}
|
||||
|
||||
@@ -24,6 +24,8 @@ import java.util.List;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.table.DefaultTableCellRenderer;
|
||||
|
||||
import forge.card.CardRules;
|
||||
import forge.card.CardSplitType;
|
||||
import forge.card.mana.ManaCost;
|
||||
import forge.card.mana.ManaCostShard;
|
||||
import forge.gui.toolbox.CardFaceSymbols;
|
||||
@@ -34,7 +36,13 @@ import forge.gui.toolbox.CardFaceSymbols;
|
||||
public class ManaCostRenderer extends DefaultTableCellRenderer {
|
||||
private static final long serialVersionUID = 1770527102334163549L;
|
||||
|
||||
private ManaCost value;
|
||||
static final int elemtWidth = 13;
|
||||
static final int elemtGap = 0;
|
||||
static final int padding0 = 1;
|
||||
static final int spaceBetweenSplitCosts = 3;
|
||||
|
||||
private ManaCost v1;
|
||||
private ManaCost v2;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
@@ -46,8 +54,10 @@ public class ManaCostRenderer extends DefaultTableCellRenderer {
|
||||
@Override
|
||||
public final Component getTableCellRendererComponent(final JTable table, final Object value,
|
||||
final boolean isSelected, final boolean hasFocus, final int row, final int column) {
|
||||
this.value = (ManaCost) value;
|
||||
this.setToolTipText(this.value.toString());
|
||||
CardRules v = value instanceof CardRules ? (CardRules) value : null;
|
||||
this.v1 = v == null ? ManaCost.NO_COST : v.getMainPart().getManaCost();
|
||||
this.v2 = v == null || v.getSplitType() != CardSplitType.Split ? null : v.getOtherPart().getManaCost();
|
||||
this.setToolTipText(v2 == null ? v1.toString() : v1.toString() + " / " + v2.toString());
|
||||
return super.getTableCellRendererComponent(table, "", isSelected, hasFocus, row, column);
|
||||
}
|
||||
|
||||
@@ -60,18 +70,38 @@ public class ManaCostRenderer extends DefaultTableCellRenderer {
|
||||
public final void paint(final Graphics g) {
|
||||
super.paint(g);
|
||||
|
||||
final int elemtWidth = 13;
|
||||
final int elemtGap = 0;
|
||||
final int padding = 1;
|
||||
|
||||
float xpos = padding;
|
||||
|
||||
final int genericManaCost = this.value.getGenericCost();
|
||||
final int xManaCosts = this.value.countX();
|
||||
final boolean hasGeneric = (genericManaCost > 0) || this.value.isPureGeneric();
|
||||
final List<ManaCostShard> shards = this.value.getShards();
|
||||
|
||||
final int cellWidth = this.getWidth();
|
||||
|
||||
if ( null == v2 )
|
||||
drawCost(g, v1, padding0, cellWidth);
|
||||
else
|
||||
{
|
||||
int shards1 = v1.isPureGeneric() || v1.getGenericCost() > 0 ? 1 : 0;
|
||||
int shards2 = v2.isPureGeneric() || v2.getGenericCost() > 0 ? 1 : 0;
|
||||
shards1 += v1.getShards().size();
|
||||
shards2 += v2.getShards().size();
|
||||
|
||||
int perGlyph = (cellWidth - padding0 - spaceBetweenSplitCosts) / (shards1 + shards2);
|
||||
perGlyph = Math.min(perGlyph, elemtWidth + elemtGap);
|
||||
drawCost(g, v1, padding0, padding0 + perGlyph * shards1);
|
||||
drawCost(g, v2, cellWidth - perGlyph * shards2, cellWidth );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for this method.
|
||||
* @param g
|
||||
* @param padding
|
||||
* @param cellWidth
|
||||
*/
|
||||
private void drawCost(final Graphics g, ManaCost value, final int padding, final int cellWidth) {
|
||||
float xpos = padding;
|
||||
final int genericManaCost = value.getGenericCost();
|
||||
final int xManaCosts = value.countX();
|
||||
final boolean hasGeneric = (genericManaCost > 0) || this.v1.isPureGeneric();
|
||||
final List<ManaCostShard> shards = value.getShards();
|
||||
|
||||
|
||||
final int cntGlyphs = hasGeneric ? shards.size() + 1 : shards.size();
|
||||
final float offsetIfNoSpace = cntGlyphs > 1 ? (cellWidth - padding - elemtWidth) / (cntGlyphs - 1f)
|
||||
: elemtWidth + elemtGap;
|
||||
|
||||
@@ -33,6 +33,7 @@ import forge.Singletons;
|
||||
import forge.card.CardAiHints;
|
||||
import forge.card.CardEdition;
|
||||
import forge.card.CardRarity;
|
||||
import forge.card.CardRules;
|
||||
import forge.card.ColorSet;
|
||||
import forge.card.mana.ManaCost;
|
||||
import forge.deck.DeckBase;
|
||||
@@ -318,11 +319,14 @@ public final class SColumnUtil {
|
||||
private static final Pattern AE_FINDER = Pattern.compile("AE", Pattern.LITERAL);
|
||||
|
||||
private static ManaCost toManaCost(final InventoryItem i) {
|
||||
return i instanceof CardPrinted ? ((IPaperCard) i).getRules().getManaCost() : ManaCost.NO_COST;
|
||||
return i instanceof IPaperCard ? ((IPaperCard) i).getRules().getManaCost() : ManaCost.NO_COST;
|
||||
}
|
||||
|
||||
private static CardRules toCardRules(final InventoryItem i) {
|
||||
return i instanceof IPaperCard ? ((IPaperCard) i).getRules() : null;
|
||||
}
|
||||
|
||||
private static ColorSet toColor(final InventoryItem i) {
|
||||
return i instanceof CardPrinted ? ((IPaperCard) i).getRules().getColor() : ColorSet.getNullColor();
|
||||
return i instanceof IPaperCard ? ((IPaperCard) i).getRules().getColor() : ColorSet.getNullColor();
|
||||
}
|
||||
|
||||
private static int toPower(final InventoryItem i) {
|
||||
@@ -430,7 +434,7 @@ public final class SColumnUtil {
|
||||
private static final Function<Entry<InventoryItem, Integer>, Object> FN_COST_GET = new Function<Entry<InventoryItem, Integer>, Object>() {
|
||||
@Override
|
||||
public Object apply(final Entry<InventoryItem, Integer> from) {
|
||||
return SColumnUtil.toManaCost(from.getKey());
|
||||
return SColumnUtil.toCardRules(from.getKey());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -61,7 +61,11 @@ public class GuiDownloadPicturesLQ extends GuiDownloader {
|
||||
|
||||
for (final IPaperCard c : CardDb.instance().getUniqueCards()) {
|
||||
CardRules cardRules = c.getRules();
|
||||
this.createDLObjects(cardRules.getPictureUrl(), cardRules.getMainPart().getName());
|
||||
if (cardRules != null && cardRules.getSplitType() == CardSplitType.Split && cardRules.getOtherPart() != null) {
|
||||
this.createDLObjects(cardRules.getPictureUrl(), String.format("%s%s", cardRules.getMainPart().getName(), cardRules.getOtherPart().getName()));
|
||||
} else {
|
||||
this.createDLObjects(cardRules.getPictureUrl(), cardRules.getMainPart().getName());
|
||||
}
|
||||
|
||||
ICardCharacteristics secondSide = cardRules.getOtherPart();
|
||||
if (secondSide != null && cardRules.getSplitType() == CardSplitType.Transform) {
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
package forge.gui.home;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.FocusListener;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import forge.gui.toolbox.FSkin;
|
||||
|
||||
@@ -30,5 +33,17 @@ public class StartButton extends JButton {
|
||||
setIcon(FSkin.getIcon(FSkin.ButtonImages.IMG_BTN_START_OVER));
|
||||
}
|
||||
});
|
||||
|
||||
addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
setEnabled(false);
|
||||
|
||||
// ensure the click action can resolve before we allow the button to be clicked again
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override public void run() { setEnabled(true); }
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ import forge.Command;
|
||||
import forge.Constant;
|
||||
import forge.Constant.Preferences;
|
||||
import forge.Singletons;
|
||||
import forge.card.cardfactory.CardFactory;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.control.input.Input;
|
||||
@@ -298,7 +299,7 @@ public class CField implements ICDoc {
|
||||
faceDown.setName("Face Down");
|
||||
choices2.add(faceDown);
|
||||
} else {
|
||||
final Card faceDown = Singletons.getModel().getCardFactory().copyCard(crd);
|
||||
final Card faceDown = CardFactory.copyCard(crd);
|
||||
faceDown.setState(CardCharacteristicName.Original);
|
||||
choices2.add(faceDown);
|
||||
}
|
||||
|
||||
@@ -221,6 +221,7 @@ public class CardFaceSymbols {
|
||||
g.drawImage(image, x, y, null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* getWidth.
|
||||
@@ -239,4 +240,8 @@ public class CardFaceSymbols {
|
||||
//System.out.println(String.format("%d for %s", width, manaCost.toString()));
|
||||
return width * 14;
|
||||
}
|
||||
|
||||
public static int getHeight() {
|
||||
return 14;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ package forge.item;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
@@ -80,7 +79,7 @@ public final class CardDb {
|
||||
* @param list
|
||||
* the new up
|
||||
*/
|
||||
public static void setup(final Iterator<CardRules> list) {
|
||||
public static void setup(final Iterable<CardRules> list) {
|
||||
if (CardDb.commonCards != null) {
|
||||
throw new RuntimeException("CardDb has already been initialized, don't do it twice please");
|
||||
}
|
||||
@@ -425,9 +424,9 @@ public final class CardDb {
|
||||
uniqueSpecialCards.put(cardName, lastAdded);
|
||||
}
|
||||
|
||||
CardSorter(final Iterator<CardRules> parser) {
|
||||
while (parser.hasNext()) {
|
||||
this.addNewCard(parser.next());
|
||||
CardSorter(final Iterable<CardRules> parser) {
|
||||
for (CardRules cr : parser) {
|
||||
this.addNewCard(cr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import forge.CardUtil;
|
||||
import forge.Singletons;
|
||||
import forge.card.CardRarity;
|
||||
import forge.card.CardRules;
|
||||
import forge.card.cardfactory.CardFactory;
|
||||
import forge.game.player.Player;
|
||||
|
||||
|
||||
@@ -295,7 +296,7 @@ public final class CardPrinted implements Comparable<IPaperCard>, InventoryItemF
|
||||
*/
|
||||
@Override
|
||||
public Card toForgeCard(Player owner) {
|
||||
final Card c = Singletons.getModel().getCardFactory().getCard(this, owner);
|
||||
final Card c = CardFactory.getCard(this, owner);
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package forge.item;
|
||||
|
||||
import forge.Card;
|
||||
import forge.Singletons;
|
||||
import forge.card.CardRarity;
|
||||
import forge.card.CardRules;
|
||||
import forge.card.cardfactory.CardFactory;
|
||||
import forge.game.player.Player;
|
||||
|
||||
public class CardToken implements InventoryItemFromSet, IPaperCard {
|
||||
@@ -40,7 +40,7 @@ public class CardToken implements InventoryItemFromSet, IPaperCard {
|
||||
|
||||
@Override
|
||||
public Card toForgeCard(Player owner) {
|
||||
final Card c = Singletons.getModel().getCardFactory().getCard(this, owner);
|
||||
final Card c = CardFactory.getCard(this, owner);
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,8 +32,9 @@ import forge.card.CardBlock;
|
||||
import forge.card.EditionCollection;
|
||||
import forge.card.FatPackData;
|
||||
import forge.card.FormatCollection;
|
||||
import forge.card.cardfactory.CardFactory;
|
||||
import forge.card.cardfactory.CardStorageReader;
|
||||
import forge.deck.CardCollections;
|
||||
import forge.error.BugReporter;
|
||||
import forge.error.ExceptionHandler;
|
||||
import forge.game.GameState;
|
||||
import forge.game.GameType;
|
||||
@@ -41,8 +42,11 @@ import forge.game.MatchController;
|
||||
import forge.game.limited.GauntletMini;
|
||||
import forge.game.player.LobbyPlayer;
|
||||
import forge.gauntlet.GauntletData;
|
||||
import forge.gui.GuiUtils;
|
||||
import forge.item.CardDb;
|
||||
import forge.properties.ForgePreferences;
|
||||
import forge.properties.ForgePreferences.FPref;
|
||||
import forge.properties.NewConstants;
|
||||
import forge.quest.QuestController;
|
||||
import forge.quest.QuestWorld;
|
||||
import forge.quest.data.QuestPreferences;
|
||||
@@ -74,7 +78,6 @@ public enum FModel {
|
||||
private GauntletData gauntletData;
|
||||
private GauntletMini gauntlet;
|
||||
|
||||
private final CardFactory cardFactory;
|
||||
private final QuestController quest;
|
||||
private final CardCollections decks;
|
||||
|
||||
@@ -144,7 +147,16 @@ public enum FModel {
|
||||
this.loadDynamicGamedata();
|
||||
|
||||
// Loads all cards (using progress bar).
|
||||
this.cardFactory = new CardFactory();
|
||||
GuiUtils.checkEDT("CardFactory$constructor", false);
|
||||
final CardStorageReader reader = new CardStorageReader(NewConstants.CARD_DATA_DIR.defaultLoc, true);
|
||||
try {
|
||||
// this fills in our map of card names to Card instances.
|
||||
CardDb.setup(reader.loadCards());
|
||||
|
||||
} catch (final Exception ex) {
|
||||
BugReporter.reportException(ex);
|
||||
}
|
||||
|
||||
this.decks = new CardCollections();
|
||||
this.quest = new QuestController();
|
||||
}
|
||||
@@ -380,14 +392,6 @@ public enum FModel {
|
||||
return gameState;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for this method.
|
||||
* @return
|
||||
*/
|
||||
public CardFactory getCardFactory() {
|
||||
return cardFactory;
|
||||
}
|
||||
|
||||
public GauntletMini getGauntletMini() {
|
||||
|
||||
if (gauntlet == null) {
|
||||
|
||||
@@ -46,6 +46,7 @@ import forge.util.storage.IStorageView;
|
||||
*
|
||||
*/
|
||||
public class QuestUtilUnlockSets {
|
||||
private static int UNLOCK_COST = 4000;
|
||||
|
||||
/**
|
||||
* Consider unlocking a new expansion in limited quest format.
|
||||
@@ -66,10 +67,10 @@ public class QuestUtilUnlockSets {
|
||||
final List<ImmutablePair<CardEdition, Integer>> setPrices = new ArrayList<ImmutablePair<CardEdition, Integer>>();
|
||||
|
||||
for (CardEdition ed : getUnlockableEditions(qData)) {
|
||||
int price = 7500;
|
||||
int price = UNLOCK_COST;
|
||||
if (mapPrices.containsKey(ed.getName() + " Booster Pack")) {
|
||||
price = Math.max(new Double(60 * Math.pow(Math.sqrt(mapPrices.get(ed.getName()
|
||||
+ " Booster Pack")), 1.65)).intValue(), 7500);
|
||||
+ " Booster Pack")), 1.65)).intValue(), UNLOCK_COST);
|
||||
}
|
||||
setPrices.add(ImmutablePair.of(ed, price));
|
||||
}
|
||||
|
||||
@@ -36,10 +36,13 @@ import javax.swing.JRootPane;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import forge.Card;
|
||||
import forge.CardCharacteristicName;
|
||||
import forge.CounterType;
|
||||
import forge.ImageCache;
|
||||
import forge.Singletons;
|
||||
import forge.card.CardEdition;
|
||||
import forge.card.CardSplitType;
|
||||
import forge.card.mana.ManaCost;
|
||||
import forge.gui.CardContainer;
|
||||
import forge.gui.toolbox.CardFaceSymbols;
|
||||
import forge.properties.ForgePreferences.FPref;
|
||||
@@ -351,6 +354,17 @@ public class CardPanel extends JPanel implements CardContainer {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for this method.
|
||||
* @param g
|
||||
* @param manaCost
|
||||
*/
|
||||
private void drawManaCost(final Graphics g, ManaCost cost, int deltaY ) {
|
||||
int width = CardFaceSymbols.getWidth(cost);
|
||||
int height = CardFaceSymbols.getHeight();
|
||||
CardFaceSymbols.draw(g, cost, (this.cardXOffset + (this.cardWidth / 2)) - (width / 2), deltaY + this.cardYOffset + (this.cardHeight / 2) - height/2);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
protected final void paintChildren(final Graphics g) {
|
||||
@@ -361,10 +375,16 @@ public class CardPanel extends JPanel implements CardContainer {
|
||||
}
|
||||
|
||||
if (this.showCastingCost) {
|
||||
int width = CardFaceSymbols.getWidth(this.getGameCard().getManaCost());
|
||||
if (this.cardWidth < 200) {
|
||||
CardFaceSymbols.draw(g, this.getGameCard().getManaCost(), (this.cardXOffset + (this.cardWidth / 2))
|
||||
- (width / 2), this.cardYOffset + (this.cardHeight / 2));
|
||||
Card gameCard = this.getGameCard();
|
||||
boolean showSplitMana = gameCard.getRules() != null && gameCard.getRules().getSplitType() == CardSplitType.Split && gameCard.getCurState() == CardCharacteristicName.Original;
|
||||
if ( !showSplitMana ) {
|
||||
drawManaCost(g, gameCard.getManaCost(), 0);
|
||||
} else {
|
||||
drawManaCost(g, gameCard.getRules().getMainPart().getManaCost(), +12);
|
||||
drawManaCost(g, gameCard.getRules().getOtherPart().getManaCost(), -12);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user