- Added AF_Sacrifice and Converted Diabolic Edict as a sample

- Cleanup of a few things related to Sacrifice, trying to funnel down the same path
This commit is contained in:
jendave
2011-08-06 12:46:22 +00:00
parent ac5e7d00fd
commit fa7569a7f8
10 changed files with 357 additions and 337 deletions

1
.gitattributes vendored
View File

@@ -5898,6 +5898,7 @@ src/forge/AbilityFactory_GainControl.java -text svneol=native#text/plain
src/forge/AbilityFactory_PermanentState.java -text svneol=native#text/plain src/forge/AbilityFactory_PermanentState.java -text svneol=native#text/plain
src/forge/AbilityFactory_Pump.java -text svneol=native#text/plain src/forge/AbilityFactory_Pump.java -text svneol=native#text/plain
src/forge/AbilityFactory_Regenerate.java -text svneol=native#text/plain src/forge/AbilityFactory_Regenerate.java -text svneol=native#text/plain
src/forge/AbilityFactory_Sacrifice.java -text svneol=native#text/plain
src/forge/AbilityFactory_Token.java -text svneol=native#text/plain src/forge/AbilityFactory_Token.java -text svneol=native#text/plain
src/forge/AbilityFactory_ZoneAffecting.java -text svneol=native#text/plain src/forge/AbilityFactory_ZoneAffecting.java -text svneol=native#text/plain
src/forge/Ability_Activated.java svneol=native#text/plain src/forge/Ability_Activated.java svneol=native#text/plain

View File

@@ -3,6 +3,7 @@ ManaCost:4 U
Types:Creature Bird Types:Creature Bird
Text:no text Text:no text
PT:3/3 PT:3/3
A:AB$Pump | Cost$ Sac<1/Land> | KW$ Flying | SpellDescription$ CARDNAME gains flying until end of turn.
SVar:Rarity:Common SVar:Rarity:Common
SVar:Picture:http://resources.wizards.com/magic/cards/pr/en-us/card24574.jpg SVar:Picture:http://resources.wizards.com/magic/cards/pr/en-us/card24574.jpg
SetInfo:8ED|Common|http://magiccards.info/scans/en/8e/66.jpg SetInfo:8ED|Common|http://magiccards.info/scans/en/8e/66.jpg

View File

@@ -1,7 +1,8 @@
Name:Diabolic Edict Name:Diabolic Edict
ManaCost:1 B ManaCost:1 B
Types:Instant Types:Instant
Text:Target player sacrifices a creature. Text:no text
A:SP$Sacrifice | Cost$ 1 B | ValidTgts$ Player | SacValid$ Creature | SacMessage$ Creature | SpellDescription$ Target player sacrifices a creature.
SVar:Rarity:Common SVar:Rarity:Common
SVar:Picture:http://www.wizards.com/global/images/magic/general/diabolic_edict.jpg SVar:Picture:http://www.wizards.com/global/images/magic/general/diabolic_edict.jpg
SetInfo:TMP|Common|http://magiccards.info/scans/en/tp/22.jpg SetInfo:TMP|Common|http://magiccards.info/scans/en/tp/22.jpg

View File

@@ -106,8 +106,12 @@ public class AbilityFactory {
for (int aaCnt = 0; aaCnt < aa.length; aaCnt ++) for (int aaCnt = 0; aaCnt < aa.length; aaCnt ++)
aa[aaCnt] = aa[aaCnt].trim(); aa[aaCnt] = aa[aaCnt].trim();
if (!(aa.length == 2)) if (aa.length != 2){
throw new RuntimeException("AbilityFactory : getAbility -- aa.length not 2 in " + hostCard.getName()); StringBuilder sb = new StringBuilder();
sb.append("AbilityFactory Parsing Error in getAbility() : Split length of ");
sb.append(a[i]).append(" in ").append(hostCard.getName()).append(" is not 2.");
throw new RuntimeException(sb.toString());
}
mapParams.put(aa[0], aa[1]); mapParams.put(aa[0], aa[1]);
} }
@@ -321,6 +325,15 @@ public class AbilityFactory {
SA = AbilityFactory_ZoneAffecting.createDrawbackMill(this); SA = AbilityFactory_ZoneAffecting.createDrawbackMill(this);
} }
if (API.equals("Sacrifice")){
if (isAb)
SA = AbilityFactory_Sacrifice.createAbilitySacrifice(this);
else if (isSp)
SA = AbilityFactory_Sacrifice.createSpellSacrifice(this);
else if (isDb)
SA = AbilityFactory_Sacrifice.createDrawbackSacrifice(this);
}
if (API.equals("Destroy")){ if (API.equals("Destroy")){
if (isAb) if (isAb)
SA = AbilityFactory_Destroy.createAbilityDestroy(this); SA = AbilityFactory_Destroy.createAbilityDestroy(this);
@@ -374,13 +387,14 @@ public class AbilityFactory {
SA = c.getSpellCounter(this); SA = c.getSpellCounter(this);
} }
if (SA != null){ if (SA == null)
if(hasSubAbility()) throw new RuntimeException("AbilityFactory : SpellAbility was not created. Did you add the API section?");
SA.setSubAbility(getSubAbility());
}
// ********************************************* // *********************************************
// set universal properties of the SpellAbility // set universal properties of the SpellAbility
if(hasSubAbility())
SA.setSubAbility(getSubAbility());
if (hasSpDesc) if (hasSpDesc)
{ {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
@@ -391,7 +405,7 @@ public class AbilityFactory {
sb.append(mapParams.get("CostDesc")).append(" "); sb.append(mapParams.get("CostDesc")).append(" ");
else sb.append(abCost.toString()); else sb.append(abCost.toString());
sb.append(mapParams.get("SpellDescription")); sb.append(mapParams.get("SpellDescription"));
SA.setDescription(sb.toString()); SA.setDescription(sb.toString());
} }

View File

@@ -0,0 +1,259 @@
package forge;
import java.util.ArrayList;
import java.util.HashMap;
public class AbilityFactory_Sacrifice {
//**************************************************************
// ****************************** FOG **************************
//**************************************************************
public static SpellAbility createAbilitySacrifice(final AbilityFactory AF){
final SpellAbility abSacrifice = new Ability_Activated(AF.getHostCard(), AF.getAbCost(), AF.getAbTgt()){
private static final long serialVersionUID = -1933592438783630254L;
final AbilityFactory af = AF;
public boolean canPlayAI()
{
return sacrificeCanPlayAI(af, this);
}
@Override
public void resolve() {
sacrificeResolve(af, this);
}
public String getStackDescription(){
return sacrificeDescription(af, this);
}
};
return abSacrifice;
}
public static SpellAbility createSpellSacrifice(final AbilityFactory AF){
final SpellAbility spSacrifice = new Spell(AF.getHostCard(), AF.getAbCost(), AF.getAbTgt()){
private static final long serialVersionUID = -5141246507533353605L;
final AbilityFactory af = AF;
public boolean canPlayAI()
{
return sacrificeCanPlayAI(af, this);
}
@Override
public void resolve() {
sacrificeResolve(af, this);
}
public String getStackDescription(){
return sacrificeDescription(af, this);
}
};
return spSacrifice;
}
public static SpellAbility createDrawbackSacrifice(final AbilityFactory AF){
final SpellAbility dbSacrifice = new Ability_Sub(AF.getHostCard(), AF.getAbTgt()){
private static final long serialVersionUID = -5141246507533353605L;
final AbilityFactory af = AF;
@Override
public void resolve() {
sacrificeResolve(af, this);
}
@Override
public boolean chkAI_Drawback() {
return sacrificePlayDrawbackAI(af, this);
}
public String getStackDescription(){
return sacrificeDescription(af, this);
}
};
return dbSacrifice;
}
public static String sacrificeDescription(final AbilityFactory af, SpellAbility sa){
StringBuilder sb = new StringBuilder();
if (sa instanceof Ability_Sub)
sb.append(" ");
else
sb.append(sa.getSourceCard().getName()).append(" - ");
Target tgt = af.getAbTgt();
if (tgt == null){
return sa.toString();
}
String valid = af.getMapParams().get("SacValid");
String num = af.getMapParams().get("Amount");
num = (num == null) ? "1" : num;
int amount = AbilityFactory.calculateAmount(sa.getSourceCard(), num, sa);
for(Player p : tgt.getTargetPlayers())
sb.append(p.getName()).append(" ");
String msg = af.getMapParams().get("SacMessage");
if (msg == null)
msg = valid;
sb.append("Sacrifices ").append(amount).append(" ").append(msg);
return sb.toString();
}
public static boolean sacrificeCanPlayAI(final AbilityFactory af, SpellAbility sa){
// AI should only activate this during Human's Declare Blockers phase
boolean chance = sacrificeTgtAI(af, sa);
// Some additional checks based on what is being sacrificed, and who is sacrificing
Target tgt = af.getAbTgt();
if (tgt != null){
String valid = af.getMapParams().get("SacValid");
String num = af.getMapParams().get("Amount");
num = (num == null) ? "1" : num;
int amount = AbilityFactory.calculateAmount(sa.getSourceCard(), num, sa);
CardList list = AllZoneUtil.getPlayerCardsInPlay(AllZone.HumanPlayer);
list = list.getValidCards(valid.split(","), sa.getActivatingPlayer(), sa.getSourceCard());
if (list.size() == 0)
return false;
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 true;
}
Ability_Sub subAb = sa.getSubAbility();
if (subAb != null)
chance &= subAb.chkAI_Drawback();
return chance;
}
public static boolean sacrificePlayDrawbackAI(final AbilityFactory af, SpellAbility sa){
// AI should only activate this during Human's turn
boolean chance = sacrificeTgtAI(af, sa);
// todo: restrict the subAbility a bit
Ability_Sub subAb = sa.getSubAbility();
if (subAb != null)
chance &= subAb.chkAI_Drawback();
return chance;
}
public static boolean sacrificeTgtAI(AbilityFactory af, SpellAbility sa){
Target tgt = af.getAbTgt();
if (tgt != null){
tgt.resetTargets();
if (AllZone.HumanPlayer.canTarget(sa.getSourceCard()))
tgt.addTarget(AllZone.HumanPlayer);
else
return false;
}
else{
String defined = af.getMapParams().get("Defined");
if (defined == null){
// Self Sacrifice.
}
else if (defined.equals("Each")){
// If Sacrifice hits both players:
// Don't cast it if Human doesn't have any of valid
// Definitely cast it if AI doesn't have any of Valid
// Cast if the type is favorable: my "worst" valid is worse than his "worst" valid
}
}
return true;
}
public static void sacrificeResolve(final AbilityFactory af, final SpellAbility sa){
HashMap<String,String> params = af.getMapParams();
Card card = sa.getSourceCard();
String DrawBack = params.get("SubAbility");
// Expand Fog keyword here depending on what we need out of it.
String num = params.containsKey("Amount") ? params.get("Amount") : "1";
int amount = AbilityFactory.calculateAmount(card, num, sa);
Target tgt = af.getAbTgt();
ArrayList<Object> tgts;
if (tgt != null){
tgts = tgt.getTargets();
}
else{
tgts = new ArrayList<Object>();
String defined = params.get("Defined");
if (defined == null) // Self
tgts.add(sa.getActivatingPlayer());
else{
if (defined.equals("Each")){
tgts.add(sa.getActivatingPlayer());
tgts.add(sa.getActivatingPlayer().getOpponent());
}
else if (defined.equals("Targeted")){
SpellAbility parent;
do{
parent = ((Ability_Sub)sa).getParent();
}while(parent.getTarget() == null && parent.getTarget().getTargetPlayers().size() == 0);
tgts.addAll(parent.getTarget().getTargetPlayers());
}
}
}
String valid = params.get("SacValid");
String msg = params.get("SacMessage");
if (msg == null)
msg = valid;
msg = "Sacrifice a " + msg;
for(Object o : tgts){
Player p = (Player)o;
if (p.isComputer())
sacrificeAI(p, amount, valid, sa);
else
sacrificeHuman(p, amount, valid, sa, msg);
}
if (af.hasSubAbility()){
Ability_Sub abSub = sa.getSubAbility();
if (abSub != null){
abSub.resolve();
}
else
CardFactoryUtil.doDrawBack(DrawBack, 0, card.getController(), card.getController().getOpponent(), card.getController(), card, null, sa);
}
}
private static void sacrificeAI(Player p, int amount, String valid, SpellAbility sa){
CardList list = AllZoneUtil.getPlayerCardsInPlay(p);
list = list.getValidCards(valid.split(","), sa.getActivatingPlayer(), sa.getSourceCard());
ComputerUtil.sacrificePermanents(amount, list);
}
private static void sacrificeHuman(Player p, int amount, String valid, SpellAbility sa, String message){
CardList list = AllZoneUtil.getPlayerCardsInPlay(p);
list = list.getValidCards(valid.split(","), sa.getActivatingPlayer(), sa.getSourceCard());
AllZone.InputControl.setInput(CardFactoryUtil.input_sacrificePermanentsFromList(amount, list, message));
}
}

View File

@@ -759,102 +759,26 @@ public class CardFactoryUtil {
}//input_targetPermanent() }//input_targetPermanent()
//CardList choices are the only cards the user can successful select public static Input input_destroyNoRegeneration(final CardList choices, final String message) {
//sacrifices one of the CardList choices
public static Input input_sacrifice(final SpellAbility spell, final CardList choices, final String message) {
Input target = new Input() { Input target = new Input() {
private static final long serialVersionUID = 2685832214519141903L; private static final long serialVersionUID = -6637588517573573232L;
@Override @Override
public void showMessage() { public void showMessage() {
AllZone.Display.showMessage(message); AllZone.Display.showMessage(message);
ButtonUtil.enableOnlyCancel(); ButtonUtil.disableAll();
}
@Override
public void selectButtonCancel() {
stop();
} }
@Override @Override
public void selectCard(Card card, PlayerZone zone) { public void selectCard(Card card, PlayerZone zone) {
if(choices.contains(card)) { if(choices.contains(card)) {
AllZone.getZone(card).remove(card); AllZone.GameAction.destroyNoRegeneration(card);
AllZone.GameAction.moveToGraveyard(card); stop();
if(spell.getManaCost().equals("0") || this.isFree()) {
this.setFree(false);
AllZone.Stack.add(spell, spell.getSourceCard().getManaCost().contains("X"));
stop();
} else stopSetNext(new Input_PayManaCost(spell));
} }
} }
}; };
return target; return target;
}//input_sacrifice() }//input_destroyNoRegeneration()
public static Input input_sacrificeThis(final SpellAbility spell) {
Input target = new Input() {
private static final long serialVersionUID = 2685832214519141903L;
@Override
public void showMessage() {
Card card = spell.getSourceCard();
String[] choices = {"Yes", "No"};
if(card.getController().equals(AllZone.HumanPlayer)) {
Object o = AllZone.Display.getChoice("Sacrifice " + card.getName() + " ?", choices);
if(o.equals("Yes")) {
sacrifice(card);
}
else{
//undo?
stop();
}
}
}
public void sacrifice(Card card)
{
AllZone.GameAction.sacrifice(card);
stop();
AllZone.Stack.add(spell);
}
};
return target;
}//input_sacrifice()
public static Input input_sacrificeType(final SpellAbility spell, final String type, final String message) {
// This input should be setAfterManaPaid so it can add the spell to the stack
Input target = new Input() {
private static final long serialVersionUID = 2685832214519141903L;
private CardList typeList;
@Override
public void showMessage() {
PlayerZone play = AllZone.getZone(Constant.Zone.Play, spell.getSourceCard().getController());
typeList = new CardList(play.getCards());
typeList = typeList.getType(type);
AllZone.Display.showMessage(message);
ButtonUtil.enableOnlyCancel();
}
@Override
public void selectButtonCancel() {
stop();
}
@Override
public void selectCard(Card card, PlayerZone zone) {
if(typeList.contains(card)) {
AllZone.GameAction.sacrifice(card);
AllZone.Stack.add(spell);
stop();
}
}
};
return target;
}//input_sacrificeType()
public static Input Wheneverinput_sacrifice(final SpellAbility spell, final CardList choices, final String message, final Command Paid) { public static Input Wheneverinput_sacrifice(final SpellAbility spell, final CardList choices, final String message, final Command Paid) {
Input target = new Input() { Input target = new Input() {
@@ -884,42 +808,6 @@ public class CardFactoryUtil {
return target; return target;
}//Wheneverinput_sacrifice() }//Wheneverinput_sacrifice()
public static Input input_sacrifice(final SpellAbility spell, final CardList choices, final String message, final boolean free) {
Input target = new Input() {
private static final long serialVersionUID = 3391527854483291332L;
@Override
public void showMessage() {
AllZone.Display.showMessage(message);
ButtonUtil.enableOnlyCancel();
}
@Override
public void selectButtonCancel() {
stop();
}
@Override
public void selectCard(Card card, PlayerZone zone) {
if(choices.contains(card)) {
AllZone.getZone(card).remove(card);
AllZone.GameAction.moveToGraveyard(card);
if (free)
this.setFree(true);
if(spell.getManaCost().equals("0") || this.isFree()) {
this.setFree(false);
AllZone.Stack.add(spell, spell.getSourceCard().getManaCost().contains("X"));
stop();
} else stopSetNext(new Input_PayManaCost(spell));
}
}
};
return target;
}//input_sacrifice()
//this one is used for Phyrexian War Beast: //this one is used for Phyrexian War Beast:
public static Input input_sacrificePermanent(final SpellAbility spell, final CardList choices, final String message) { public static Input input_sacrificePermanent(final SpellAbility spell, final CardList choices, final String message) {
Input target = new Input() { Input target = new Input() {
@@ -954,94 +842,25 @@ public class CardFactoryUtil {
return target; return target;
}//input_sacrifice() }//input_sacrifice()
public static Input input_sacrificePermanent(final CardList choices, final String message) { public static Input input_sacrificePermanent(final CardList choices, final String message) {
Input target = new Input() { return input_sacrificePermanentsFromList(1, choices, "Select a permanent to sacrifice");
private static final long serialVersionUID = 2685832214519141903L;
@Override
public void showMessage() {
if(choices.size() == 0) stop();
AllZone.Display.showMessage(message);
ButtonUtil.disableAll();
}
@Override
public void selectCard(Card card, PlayerZone zone) {
if(choices.contains(card)) {
AllZone.GameAction.sacrifice(card);
stop();
}
}
};
return target;
}//input_sacrifice() }//input_sacrifice()
public static Input input_destroyNoRegeneration(final CardList choices, final String message) {
Input target = new Input() {
private static final long serialVersionUID = -6637588517573573232L;
@Override
public void showMessage() {
AllZone.Display.showMessage(message);
ButtonUtil.disableAll();
}
@Override
public void selectCard(Card card, PlayerZone zone) {
if(choices.contains(card)) {
AllZone.GameAction.destroyNoRegeneration(card);
stop();
}
}
};
return target;
}//input_destroyNoRegeneration()
public static Input input_sacrificePermanents(final int nCards) { public static Input input_sacrificePermanents(final int nCards) {
Input target = new Input() { CardList list = AllZoneUtil.getPlayerCardsInPlay(AllZone.HumanPlayer);
private static final long serialVersionUID = -8149416676562317629L; list.remove("Mana Pool"); // is this needed?
int n = 0; return input_sacrificePermanentsFromList(nCards, list, "Select a permanent to sacrifice");
@Override
public void showMessage() {
CardList list = new CardList(AllZone.Human_Play.getCards());
list = list.filter(new CardListFilter(){
public boolean addCard(Card c)
{
return c.isPermanent() && !c.getName().equals("Mana Pool");
}
});
if(n == nCards || list.size() == 0) stop();
AllZone.Display.showMessage("Select a permanent to sacrifice (" +(nCards-n) +" left)");
ButtonUtil.disableAll();
}
@Override
public void selectCard(Card card, PlayerZone zone) {
if(zone.equals(AllZone.Human_Play) && !card.getName().equals("Mana Pool")) {
AllZone.GameAction.sacrifice(card);
n++;
//in case no more {type}s in play
CardList list = new CardList(AllZone.Human_Play.getCards());
list = list.filter(new CardListFilter(){
public boolean addCard(Card c)
{
return c.isPermanent() && !c.getName().equals("Mana Pool");
}
});
if(n == nCards || list.size() == 0) stop();
else
showMessage();
}
}
};
return target;
}//input_sacrificePermanents() }//input_sacrificePermanents()
public static Input input_sacrificePermanents(final int nCards, final String type) { public static Input input_sacrificePermanents(final int nCards, final String type) {
CardList list = AllZoneUtil.getPlayerCardsInPlay(AllZone.HumanPlayer);
list.remove("Mana Pool"); // is this needed?
list = list.getType(type);
return input_sacrificePermanentsFromList(nCards, list, "Select a " +type +" to sacrifice");
}//input_sacrificePermanents()
public static Input input_sacrificePermanentsFromList(final int nCards, final CardList list, final String message) {
Input target = new Input() { Input target = new Input() {
private static final long serialVersionUID = 1981791992623774490L; private static final long serialVersionUID = 1981791992623774490L;
int n = 0; int n = 0;
@@ -1049,23 +868,20 @@ public class CardFactoryUtil {
@Override @Override
public void showMessage() { public void showMessage() {
//in case no more {type}s in play //in case no more {type}s in play
CardList list = new CardList(AllZone.Human_Play.getCards());
list = list.getType(type);
if(n == nCards || list.size() == 0) stop(); if(n == nCards || list.size() == 0) stop();
AllZone.Display.showMessage("Select a " +type +" to sacrifice (" +(nCards-n) +" left)"); AllZone.Display.showMessage(message + " (" +(nCards-n) +" left)");
ButtonUtil.disableAll(); ButtonUtil.disableAll();
} }
@Override @Override
public void selectCard(Card card, PlayerZone zone) { public void selectCard(Card card, PlayerZone zone) {
if(zone.equals(AllZone.Human_Play) && card.getType().contains(type)) { if(zone.equals(AllZone.Human_Play) && list.contains(card)) {
AllZone.GameAction.sacrifice(card); AllZone.GameAction.sacrifice(card);
n++; n++;
list.remove(card);
//in case no more {type}s in play //in case no more {type}s in play
CardList list = new CardList(AllZone.Human_Play.getCards());
list = list.getType(type);
if(n == nCards || list.size() == 0) stop(); if(n == nCards || list.size() == 0) stop();
else else
showMessage(); showMessage();

View File

@@ -7064,76 +7064,14 @@ public class CardFactory_Creatures {
}//*************** END ************ END ************************** }//*************** END ************ END **************************
//*************** START *********** START **************************
else if(cardName.equals("Coastal Hornclaw")) {
//sacrifice ability - targets itself - until EOT
final Command untilEOT = new Command() {
private static final long serialVersionUID = 7538741250040204529L;
public void execute() {
card.removeIntrinsicKeyword("Flying");
}
};
//mana tap ability
final Ability ability = new Ability(card, "0") {
@Override
public boolean canPlayAI() {
CardList land = new CardList(AllZone.Computer_Play.getCards());
land = land.getType("Land");
return (land.size() != 0) && (!card.getKeyword().contains("Flying"))
&& CardFactoryUtil.AI_getHumanCreature("Flying", card, false).isEmpty()
&& (!card.hasSickness()) && (AllZone.Phase.getPhase().equals(Constant.Phase.Main1));
}
@Override
public void chooseTargetAI() {
CardList land = new CardList(AllZone.Computer_Play.getCards());
land = land.getType("Land");
land.shuffle();
AllZone.GameAction.sacrifice(land.get(0));
}
@Override
public void resolve() {
if(AllZone.GameAction.isCardInPlay(card)) {
card.addIntrinsicKeyword("Flying");
AllZone.EndOfTurn.addUntil(untilEOT);
}
}//resolve()
};//SpellAbility
Input runtime = new Input() {
private static final long serialVersionUID = 4874019210748846864L;
@Override
public void showMessage() {
StringBuilder sb = new StringBuilder();
sb.append(card).append(" gains flying until EOT.");
ability.setStackDescription(sb.toString());
PlayerZone play = AllZone.getZone(Constant.Zone.Play, card.getController());
CardList choice = new CardList(play.getCards());
choice = choice.getType("Land");
stopSetNext(CardFactoryUtil.input_sacrifice(ability, choice, "Select a land to sacrifice."));
}
};
StringBuilder sb = new StringBuilder();
sb.append(card).append(" gains flying until end of turn.");
ability.setStackDescription(sb.toString());
ability.setDescription("Sacrifice a land: Coastal Hornclaw gains flying until end of turn.");
card.addSpellAbility(ability);
ability.setBeforePayMana(runtime);
}//*************** END ************ END **************************
//*************** START *********** START ************************** //*************** START *********** START **************************
else if(cardName.equals("Spitting Spider")) { else if(cardName.equals("Spitting Spider")) {
final Ability ability = new Ability(card, "0") { // temporary fix until DamageAll is created
@Override Ability_Cost abCost = new Ability_Cost("Sac<1/Land>", cardName, true);
final SpellAbility ability = new Ability_Activated(card, abCost, null) {
private static final long serialVersionUID = 2560268493829888869L;
@Override
public boolean canPlayAI() { public boolean canPlayAI() {
return false; return false;
} }
@@ -7147,25 +7085,12 @@ public class CardFactory_Creatures {
}//resolve() }//resolve()
};//SpellAbility };//SpellAbility
Input runtime = new Input() {
private static final long serialVersionUID = 2004031367305867525L;
@Override
public void showMessage() {
PlayerZone play = AllZone.getZone(Constant.Zone.Play, card.getController());
CardList choice = new CardList(play.getCards());
choice = choice.getType("Land");
stopSetNext(CardFactoryUtil.input_sacrifice(ability, choice, "Select a land to sacrifice."));
}
};
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append(card).append(" deals 1 damage to each creature with flying."); sb.append(card).append(" deals 1 damage to each creature with flying.");
ability.setStackDescription(sb.toString()); ability.setStackDescription(sb.toString());
ability.setDescription("Sacrifice a land: Spitting Spider deals 1 damage to each creature with flying."); ability.setDescription("Sacrifice a land: Spitting Spider deals 1 damage to each creature with flying.");
card.addSpellAbility(ability); card.addSpellAbility(ability);
ability.setBeforePayMana(runtime);
}//*************** END ************ END ************************** }//*************** END ************ END **************************

View File

@@ -3147,35 +3147,6 @@ public class CardFactory_Instants {
return card; return card;
}//*************** END ************ END ************************** }//*************** END ************ END **************************
//*************** START *********** START **************************
else if(cardName.equals("Diabolic Edict") ) {
final SpellAbility spell = new Spell(card) {
private static final long serialVersionUID = 1593405082929818055L;
@Override
public void resolve() {
getTargetPlayer().sacrificeCreature();
}
@Override
public boolean canPlayAI() {
PlayerZone hPlay = AllZone.getZone(Constant.Zone.Play, AllZone.HumanPlayer);
CardList hList = new CardList(hPlay.getCards());
hList = hList.getType("Creature");
return hList.size() > 0;
}
};
spell.setChooseTargetAI(CardFactoryUtil.AI_targetHuman());
spell.setBeforePayMana(CardFactoryUtil.input_targetPlayer(spell));
card.clearSpellAbility();
card.addSpellAbility(spell);
}//*************** END ************ END **************************
//*************** START *********** START ************************** //*************** START *********** START **************************
else if(cardName.equals("Path to Exile")) { else if(cardName.equals("Path to Exile")) {
SpellAbility spell = new Spell(card) { SpellAbility spell = new Spell(card) {

View File

@@ -1009,14 +1009,7 @@ public class CombatUtil {
if (crd.getController().isHuman()) if (crd.getController().isHuman())
{ {
CardList list = new CardList(AllZone.Computer_Play.getCards()); CardList list = new CardList(AllZone.Computer_Play.getCards());
CardListUtil.sortCMC(list); ComputerUtil.sacrificePermanents(a, list);
list.reverse();
int max = list.size();
if (max>a)
max = a;
for (int i=0;i<max;i++)
AllZone.GameAction.sacrifice(list.get(i));
} }
else else
{ {

View File

@@ -759,4 +759,43 @@ public class ComputerUtil
};//Comparator };//Comparator
Arrays.sort(sa, c); Arrays.sort(sa, c);
}//sortSpellAbilityByCost() }//sortSpellAbilityByCost()
static void sacrificePermanents(int amount, CardList list) {
// used in Annihilator and AF_Sacrifice
int max = list.size();
if (max > amount)
max = amount;
CardListUtil.sortCMC(list);
list.reverse();
for (int i = 0; i < max; i++) {
// todo: use getWorstPermanent() would be wayyyy better
Card c;
if (list.getNotType("Creature").size() == 0) {
c = CardFactoryUtil.AI_getWorstCreature(list);
} else if (list.getNotType("Land").size() == 0) {
c = CardFactoryUtil.getWorstLand(AllZone.ComputerPlayer);
} else {
c = list.get(0);
}
ArrayList<Card> auras = c.getEnchantedBy();
if (auras.size() > 0){
// todo: choose "worst" controlled enchanting Aura
for(int j = 0; j < auras.size(); j++){
Card aura = auras.get(j);
if (aura.getController().isPlayer(c.getController()) && list.contains(aura)){
c = aura;
break;
}
}
}
list.remove(c);
AllZone.GameAction.sacrifice(c);
}
}
} }