Initial checkin of CostReveal

Some preparation for actual Payment occurring after all Costs have been completed.
Add Living Destiny
This commit is contained in:
Sol
2011-08-25 02:32:40 +00:00
parent 1912a951a5
commit 763d7e7870
15 changed files with 332 additions and 61 deletions

View File

@@ -490,15 +490,17 @@ public class GameAction {
CardList hand = AllZoneUtil.getPlayerHand(AllZone.getComputerPlayer());
hand = hand.getValidCards(uTypes, sa.getActivatingPlayer(), sa.getSourceCard());
if (hand.size() < numDiscard)
if (hand.size() < numDiscard){
return null;
}
CardList discard = new CardList();
CardListUtil.sortCMC(hand);
hand.reverse();
for (int i = 0; i < numDiscard; i++)
for (int i = 0; i < numDiscard; i++){
discard.add(hand.get(i));
}
return discard;
}

View File

@@ -1105,13 +1105,19 @@ public abstract class Player extends MyObservable {
*
* @param num a int.
* @param sa a {@link forge.card.spellability.SpellAbility} object.
* @return
*/
public void discardRandom(final int num, final SpellAbility sa) {
public CardList discardRandom(final int num, final SpellAbility sa) {
CardList discarded = new CardList();
for (int i = 0; i < num; i++) {
CardList list = AllZoneUtil.getPlayerHand(this);
if (list.size() != 0)
doDiscard(CardUtil.getRandom(list.toArray()), sa);
if (list.size() != 0){
Card disc = CardUtil.getRandom(list.toArray());
discarded.add(disc);
doDiscard(disc, sa);
}
}
return discarded;
}
/**

View File

@@ -1077,16 +1077,16 @@ public class AbilityFactory {
}
CardList list = new CardList();
if (calcX[0].startsWith("Sacrificed"))
if (calcX[0].startsWith("Sacrificed")) {
list = findRootAbility(ability).getPaidList("Sacrificed");
else if (calcX[0].startsWith("Discarded"))
} else if (calcX[0].startsWith("Discarded")){
list = findRootAbility(ability).getPaidList("Discarded");
else if (calcX[0].startsWith("Exiled")) {
} else if (calcX[0].startsWith("Exiled")) {
list = findRootAbility(ability).getPaidList("Exiled");
} else if (calcX[0].startsWith("Tapped")) {
list = findRootAbility(ability).getPaidList("Tapped");
} else if (calcX[0].startsWith("Revealed")) {
list = findRootAbility(ability).getPaidList("Revealed");
} else if (calcX[0].startsWith("Targeted")) {
Target t = ability.getTarget();
if (null != t) {

View File

@@ -98,6 +98,7 @@ public class Cost {
private final static String exileFromGraveStr = "ExileFromGrave<";
private final static String exileFromTopStr = "ExileFromTop<";
private final static String returnStr = "Return<";
private final static String revealStr = "Reveal<";
/**
* <p>Constructor for Cost.</p>
@@ -124,7 +125,7 @@ public class Cost {
String[] splitStr = abCostParse(parse, subStr, 4);
parse = abUpdateParse(parse, subStr);
String type = splitStr.length > 2 ? splitStr[2] : null;
String type = splitStr.length > 2 ? splitStr[2] : "CARDNAME";
String description = splitStr.length > 3 ? splitStr[3] : null;
costParts.add(new CostRemoveCounter(splitStr[0], Counters.valueOf(splitStr[1]), type, description));
@@ -212,6 +213,14 @@ public class Cost {
String description = splitStr.length > 2 ? splitStr[2] : null;
costParts.add(new CostReturn(splitStr[0], splitStr[1], description));
}
while (parse.contains(revealStr)) {
String[] splitStr = abCostParse(parse, revealStr, 3);
parse = abUpdateParse(parse, revealStr);
String description = splitStr.length > 2 ? splitStr[2] : null;
costParts.add(new CostReveal(splitStr[0], splitStr[1], description));
}
// These won't show up with multiples
if (parse.contains("Untap")) {

View File

@@ -17,9 +17,7 @@ public class CostDiscard extends CostPartWithList {
// Discard<Num/Type{/TypeDescription}>
public CostDiscard(String amount, String type, String description){
this.amount = amount;
this.type = type;
this.typeDescription = description;
super(amount, type, description);
}
@Override
@@ -101,18 +99,27 @@ public class CostDiscard extends CostPartWithList {
CardList handList = AllZoneUtil.getPlayerHand(activator);
String discType = getType();
String amount = getAmount();
resetList();
if (getThis()) {
if (!handList.contains(source)){
return false;
}
activator.discard(source, ability);
payment.setPaidManaPart(this, true);
addToList(source);
} else if (discType.equals("Hand")) {
list = handList;
activator.discardHand(ability);
payment.setPaidManaPart(this, true);
} else if (discType.equals("LastDrawn")) {
if (handList.contains(activator.getLastDrawnCard())) {
activator.discard(activator.getLastDrawnCard(), ability);
payment.setPaidManaPart(this, true);
Card lastDrawn = activator.getLastDrawnCard();
addToList(lastDrawn);
if (!handList.contains(lastDrawn)) {
return false;
}
activator.discard(lastDrawn, ability);
payment.setPaidManaPart(this, true);
} else {
Integer c = convertAmount();
@@ -128,7 +135,7 @@ public class CostDiscard extends CostPartWithList {
}
}
activator.discardRandom(c, ability);
list = activator.discardRandom(c, ability);
payment.setPaidManaPart(this, true);
} else {
String validType[] = discType.split(";");
@@ -149,6 +156,7 @@ public class CostDiscard extends CostPartWithList {
return false;
}
}
addListToHash(ability, "Discarded");
return true;
}
@@ -161,14 +169,14 @@ public class CostDiscard extends CostPartWithList {
if (type.equals("LastDrawn")){
if (!hand.contains(activator.getLastDrawnCard()))
return false;
list.add(activator.getLastDrawnCard());
addToList(activator.getLastDrawnCard());
}
else if (getThis()){
if (!hand.contains(source))
return false;
list.add(source);
addToList(source);
}
else if (type.equals("Hand")){
@@ -208,7 +216,7 @@ public class CostDiscard extends CostPartWithList {
*
* @return a {@link forge.gui.input.Input} object.
*/
public static Input input_discardCost(final String discType, final CardList handList, SpellAbility sa, final Cost_Payment payment, final CostPart part, final int nNeeded) {
public static Input input_discardCost(final String discType, final CardList handList, SpellAbility sa, final Cost_Payment payment, final CostDiscard part, final int nNeeded) {
final SpellAbility sp = sa;
Input target = new Input() {
private static final long serialVersionUID = -329993322080934435L;
@@ -217,20 +225,15 @@ public class CostDiscard extends CostPartWithList {
@Override
public void showMessage() {
boolean any = discType.equals("Any") ? true : false;
if (AllZone.getHumanHand().size() == 0) stop();
StringBuilder type = new StringBuilder("");
if (any || !discType.equals("Card")) {
if (!discType.equals("Card")) {
type.append(" ").append(discType);
}
StringBuilder sb = new StringBuilder();
sb.append("Select ");
if (any) {
sb.append("any ");
} else {
sb.append("a ").append(type.toString()).append(" ");
}
sb.append("card to discard.");
sb.append("Select a");
sb.append(part.getDescriptiveType());
sb.append(" to discard.");
if (nNeeded > 1) {
sb.append(" You have ");
sb.append(nNeeded - nDiscard);
@@ -250,6 +253,7 @@ public class CostDiscard extends CostPartWithList {
if (zone.is(Constant.Zone.Hand) && handList.contains(card)) {
// send in CardList for Typing
card.getController().discard(card, sp);
part.addToList(card);
handList.remove(card);
nDiscard++;
@@ -270,6 +274,7 @@ public class CostDiscard extends CostPartWithList {
public void done() {
stop();
part.addListToHash(sp, "Discarded");
payment.paidCost(part);
}
};

View File

@@ -32,9 +32,7 @@ public class CostExile extends CostPartWithList {
}
public CostExile(String amount, String type, String description, String from){
this.amount = amount;
this.type = type;
this.typeDescription = description;
super(amount, type, description);
if (from != null)
this.from = from;
}
@@ -173,9 +171,10 @@ public class CostExile extends CostPartWithList {
Iterator<Card> itr = list.iterator();
while(itr.hasNext()){
Card c = (Card)itr.next();
payment.getAbility().addCostToHashList(c, "Exiled");
part.addToList(c);
AllZone.getGameAction().exile(c);
}
part.addListToHash(sa, "Exiled");
payment.paidCost(part);
}
else{
@@ -202,7 +201,7 @@ public class CostExile extends CostPartWithList {
if (o != null) {
Card c = (Card) o;
typeList.remove(c);
payment.getAbility().addCostToHashList(c, "Exiled");
part.addToList(c);
AllZone.getGameAction().exile(c);
if (i == nNeeded - 1) done();
}
@@ -220,6 +219,7 @@ public class CostExile extends CostPartWithList {
public void done() {
stop();
part.addListToHash(sa, "Exiled");
payment.paidCost(part);
}
@@ -275,7 +275,7 @@ public class CostExile extends CostPartWithList {
public void selectCard(Card card, PlayerZone zone) {
if (typeList.contains(card)) {
nExiles++;
payment.getAbility().addCostToHashList(card, "Exiled");
part.addToList(card);
AllZone.getGameAction().exile(card);
typeList.remove(card);
//in case nothing else to exile
@@ -290,6 +290,7 @@ public class CostExile extends CostPartWithList {
public void done() {
stop();
part.addListToHash(sa, "Exiled");
payment.paidCost(part);
}
@@ -328,7 +329,9 @@ public class CostExile extends CostPartWithList {
if (choice.equals(0)) {
payment.getAbility().addCostToHashList(card, "Exiled");
AllZone.getGameAction().exile(card);
part.addToList(card);
stop();
part.addListToHash(sa, "Exiled");
payment.paidCost(part);
} else {
stop();

View File

@@ -13,6 +13,14 @@ public abstract class CostPart {
protected String type = "Card";
protected String typeDescription = null;
public CostPart(){}
public CostPart(String amount, String type, String description){
this.amount = amount;
this.type = type;
this.typeDescription = description;
}
public String getAmount() {
return amount;
}

View File

@@ -2,6 +2,7 @@ package forge.card.cost;
import forge.Card;
import forge.CardList;
import forge.card.spellability.SpellAbility;
public abstract class CostPartWithList extends CostPart {
protected CardList list = null;
@@ -9,4 +10,17 @@ public abstract class CostPartWithList extends CostPart {
public void setList(CardList setList) { list = setList; }
public void resetList() { list = new CardList(); }
public void addToList(Card c) { list.add(c); }
public void addListToHash(SpellAbility sa, String hash){
for(Card card : list){
sa.addCostToHashList(card, hash);
}
}
public CostPartWithList(){}
public CostPartWithList(String amount, String type, String description){
super(amount, type, description);
resetList();
}
}

View File

@@ -21,16 +21,10 @@ public class CostRemoveCounter extends CostPart {
}
public CostRemoveCounter(String amount, Counters counter, String type, String description){
super(amount, type, description);
isReusable = true;
this.amount = amount;
this.counter = counter;
if (type != null)
this.type = type;
else
this.type = "CARDNAME";
this.typeDescription = description;
this.counter = counter;
}
@Override

View File

@@ -18,9 +18,7 @@ public class CostReturn extends CostPartWithList {
// Return<Num/Type{/TypeDescription}>
public CostReturn(String amount, String type, String description){
this.amount = amount;
this.type = type;
this.typeDescription = description;
super(amount, type, description);
}
@Override
@@ -127,7 +125,7 @@ public class CostReturn extends CostPartWithList {
* @param part TODO
* @return a {@link forge.gui.input.Input} object.
*/
public static Input returnType(final SpellAbility sa, final String type, final Cost_Payment payment, final CostPart part, final int nNeeded) {
public static Input returnType(final SpellAbility sa, final String type, final Cost_Payment payment, final CostReturn part, final int nNeeded) {
Input target = new Input() {
private static final long serialVersionUID = 2685832214519141903L;
private CardList typeList;
@@ -158,6 +156,7 @@ public class CostReturn extends CostPartWithList {
public void selectCard(Card card, PlayerZone zone) {
if (typeList.contains(card)) {
nReturns++;
part.addToList(card);
AllZone.getGameAction().moveToHand(card);
typeList.remove(card);
//in case nothing else to return
@@ -177,6 +176,7 @@ public class CostReturn extends CostPartWithList {
public void cancel() {
stop();
part.addListToHash(sa, "Returned");
payment.cancelCost();
}
};
@@ -192,7 +192,7 @@ public class CostReturn extends CostPartWithList {
* @param part TODO
* @return a {@link forge.gui.input.Input} object.
*/
public static Input returnThis(final SpellAbility sa, final Cost_Payment payment, final CostPart part) {
public static Input returnThis(final SpellAbility sa, final Cost_Payment payment, final CostReturn part) {
Input target = new Input() {
private static final long serialVersionUID = 2685832214519141903L;
@@ -208,8 +208,10 @@ public class CostReturn extends CostPartWithList {
JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE,
null, possibleValues, possibleValues[0]);
if (choice.equals(0)) {
part.addToList(card);
AllZone.getGameAction().moveToHand(card);
stop();
part.addListToHash(sa, "Returned");
payment.paidCost(part);
} else {
stop();

View File

@@ -0,0 +1,215 @@
package forge.card.cost;
import forge.AllZone;
import forge.AllZoneUtil;
import forge.ButtonUtil;
import forge.Card;
import forge.CardList;
import forge.Constant;
import forge.Player;
import forge.card.abilityFactory.AbilityFactory;
import forge.card.spellability.SpellAbility;
import forge.gui.GuiUtils;
import forge.gui.input.Input;
import forge.PlayerZone;
public class CostReveal extends CostPartWithList {
//Reveal<Num/Type/TypeDescription>
public CostReveal(String amount, String type, String description){
super(amount, type, description);
}
@Override
public boolean canPay(SpellAbility ability, Card source, Player activator, Cost cost) {
CardList handList = AllZoneUtil.getPlayerHand(activator);
String type = getType();
Integer amount = convertAmount();
if (getThis()) {
if (!AllZone.getZone(source).is(Constant.Zone.Hand))
return false;
} else {
handList = handList.getValidCards(type.split(";"), activator, source);
if (amount != null && amount > handList.size()) {
// not enough cards in hand to pay
return false;
}
}
return true;
}
@Override
public boolean decideAIPayment(SpellAbility ability, Card source, Cost_Payment payment) {
String type = getType();
Player activator = ability.getActivatingPlayer();
CardList hand = AllZoneUtil.getPlayerHand(activator);
resetList();
if (getThis()){
if (!hand.contains(source))
return false;
list.add(source);
} else{
hand = hand.getValidCards(type.split(";"), activator, source);
Integer c = convertAmount();
if (c == null){
String sVar = source.getSVar(amount);
if (sVar.equals("XChoice")){
c = hand.size();
}
else{
c = AbilityFactory.calculateAmount(source, amount, ability);
}
}
list = AllZone.getGameAction().AI_discardNumType(c, type.split(";"), ability);
}
return list != null;
}
@Override
public void payAI(SpellAbility ability, Card source, Cost_Payment payment) {
GuiUtils.getChoiceOptional("Revealed cards:", list.toArray());
}
@Override
public boolean payHuman(SpellAbility ability, Card source, Cost_Payment payment) {
Player activator = ability.getActivatingPlayer();
String amount = getAmount();
resetList();
if (getThis()) {
addToList(source);
payment.setPaidManaPart(this, true);
} else {
Integer c = convertAmount();
CardList handList = AllZoneUtil.getPlayerHand(activator);
handList = handList.getValidCards(type.split(";"), activator, ability.getSourceCard());
if (c == null){
String sVar = source.getSVar(amount);
if (sVar.equals("XChoice")){
c = CostUtil.chooseXValue(source, handList.size());
}
else{
c = AbilityFactory.calculateAmount(source, amount, ability);
}
}
CostUtil.setInput(input_revealCost(type, handList, payment, this, ability, c));
return false;
}
addListToHash(ability, "Revealed");
return true;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("Reveal ");
Integer i = convertAmount();
if (getThis()) {
sb.append(type);
}
else {
StringBuilder desc = new StringBuilder();
if (type.equals("Card"))
desc.append("Card");
else
desc.append(typeDescription == null ? type : typeDescription).append(" card");
sb.append(Cost.convertAmountTypeToWords(i, amount, desc.toString()));
}
return sb.toString();
}
@Override
public void refund(Card source) {
}
// Inputs
/**
* <p>input_discardCost.</p>
* @param discType a {@link java.lang.String} object.
* @param handList a {@link forge.CardList} object.
* @param payment a {@link forge.card.cost.Cost_Payment} object.
* @param part TODO
* @param sa TODO
* @param nNeeded a int.
* @return a {@link forge.gui.input.Input} object.
*/
public static Input input_revealCost(final String discType, final CardList handList, final Cost_Payment payment, final CostReveal part, final SpellAbility sa, final int nNeeded) {
Input target = new Input() {
private static final long serialVersionUID = -329993322080934435L;
int nReveal = 0;
@Override
public void showMessage() {
if (AllZone.getHumanHand().size() < nNeeded) stop();
StringBuilder type = new StringBuilder("");
if (!discType.equals("Card")) {
type.append(" ").append(discType);
}
StringBuilder sb = new StringBuilder();
sb.append("Select a");
sb.append(part.getDescriptiveType());
sb.append(" to reveal.");
if (nNeeded > 1) {
sb.append(" You have ");
sb.append(nNeeded - nReveal);
sb.append(" remaining.");
}
AllZone.getDisplay().showMessage(sb.toString());
ButtonUtil.enableOnlyCancel();
}
@Override
public void selectButtonCancel() {
cancel();
}
@Override
public void selectCard(Card card, PlayerZone zone) {
if (zone.is(Constant.Zone.Hand) && handList.contains(card)) {
// send in CardList for Typing
handList.remove(card);
part.addToList(card);
nReveal++;
//in case no more cards in hand
if (nReveal == nNeeded)
done();
else if (AllZone.getHumanHand().size() == 0) // this really shouldn't happen
cancel();
else
showMessage();
}
}
public void cancel() {
stop();
payment.cancelCost();
}
public void done() {
stop();
// "Inform" AI of the revealed cards
part.addListToHash(sa, "Revealed");
payment.paidCost(part);
}
};
return target;
}//input_discard()
}

View File

@@ -17,9 +17,7 @@ import forge.gui.input.Input;
public class CostSacrifice extends CostPartWithList {
public CostSacrifice(String amount, String type, String description){
this.amount = amount;
this.type = type;
this.typeDescription = description;
super(amount, type, description);
}
@Override
@@ -85,7 +83,9 @@ public class CostSacrifice extends CostPartWithList {
CostUtil.setInput(CostSacrifice.sacrificeThis(ability, payment, this));
}
else if (amount.equals("All")){
this.list = list;
CostSacrifice.sacrificeAll(ability, payment, this, list);
addListToHash(ability, "Sacrificed");
return true;
}
else{
@@ -193,7 +193,7 @@ public class CostSacrifice extends CostPartWithList {
public void selectCard(Card card, PlayerZone zone) {
if (typeList.contains(card)) {
nSacrifices++;
payment.getAbility().addCostToHashList(card, "Sacrificed");
part.addToList(card);
AllZone.getGameAction().sacrifice(card);
typeList.remove(card);
//in case nothing else to sacrifice
@@ -208,11 +208,13 @@ public class CostSacrifice extends CostPartWithList {
public void done() {
stop();
part.addListToHash(sa, "Sacrificed");
payment.paidCost(part);
}
public void cancel() {
stop();
payment.cancelCost();
}
};
@@ -228,7 +230,7 @@ public class CostSacrifice extends CostPartWithList {
* @param part TODO
* @return a {@link forge.gui.input.Input} object.
*/
public static Input sacrificeThis(final SpellAbility sa, final Cost_Payment payment, final CostPart part) {
public static Input sacrificeThis(final SpellAbility sa, final Cost_Payment payment, final CostSacrifice part) {
Input target = new Input() {
private static final long serialVersionUID = 2685832214519141903L;
@@ -244,7 +246,8 @@ public class CostSacrifice extends CostPartWithList {
JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE,
null, possibleValues, possibleValues[0]);
if (choice.equals(0)) {
payment.getAbility().addCostToHashList(card, "Sacrificed");
part.addToList(card);
part.addListToHash(sa, "Sacrificed");
AllZone.getGameAction().sacrifice(card);
stop();
payment.paidCost(part);

View File

@@ -15,11 +15,8 @@ import forge.gui.input.Input;
public class CostTapType extends CostPartWithList {
public CostTapType(String amount, String type, String description){
list = new CardList();
super(amount, type, description);
isReusable = true;
this.amount = amount;
this.type = type;
this.typeDescription = description;
}
public String getDescription(){
@@ -128,7 +125,7 @@ public class CostTapType extends CostPartWithList {
* @param payment a {@link forge.card.cost.Cost_Payment} object.
* @return a {@link forge.gui.input.Input} object.
*/
public static Input input_tapXCost(final CostTapType tapType, final CardList cardList, SpellAbility sa, final Cost_Payment payment, final int nCards) {
public static Input input_tapXCost(final CostTapType tapType, final CardList cardList, final SpellAbility sa, final Cost_Payment payment, final int nCards) {
Input target = new Input() {
private static final long serialVersionUID = 6438988130447851042L;
@@ -155,7 +152,7 @@ public class CostTapType extends CostPartWithList {
card.tap();
tapType.addToList(card);
cardList.remove(card);
payment.getAbility().addCostToHashList(card, "Tapped");
nTapped++;
if (nTapped == nCards)
@@ -175,6 +172,7 @@ public class CostTapType extends CostPartWithList {
public void done() {
stop();
payment.paidCost(tapType);
tapType.addListToHash(sa, "Tapped");
}
};