mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 12:48:00 +00:00
- 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:
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -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_Pump.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_ZoneAffecting.java -text svneol=native#text/plain
|
||||
src/forge/Ability_Activated.java svneol=native#text/plain
|
||||
|
||||
@@ -3,6 +3,7 @@ ManaCost:4 U
|
||||
Types:Creature Bird
|
||||
Text:no text
|
||||
PT:3/3
|
||||
A:AB$Pump | Cost$ Sac<1/Land> | KW$ Flying | SpellDescription$ CARDNAME gains flying until end of turn.
|
||||
SVar:Rarity:Common
|
||||
SVar:Picture:http://resources.wizards.com/magic/cards/pr/en-us/card24574.jpg
|
||||
SetInfo:8ED|Common|http://magiccards.info/scans/en/8e/66.jpg
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
Name:Diabolic Edict
|
||||
ManaCost:1 B
|
||||
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:Picture:http://www.wizards.com/global/images/magic/general/diabolic_edict.jpg
|
||||
SetInfo:TMP|Common|http://magiccards.info/scans/en/tp/22.jpg
|
||||
|
||||
@@ -106,8 +106,12 @@ public class AbilityFactory {
|
||||
for (int aaCnt = 0; aaCnt < aa.length; aaCnt ++)
|
||||
aa[aaCnt] = aa[aaCnt].trim();
|
||||
|
||||
if (!(aa.length == 2))
|
||||
throw new RuntimeException("AbilityFactory : getAbility -- aa.length not 2 in " + hostCard.getName());
|
||||
if (aa.length != 2){
|
||||
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]);
|
||||
}
|
||||
@@ -321,6 +325,15 @@ public class AbilityFactory {
|
||||
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 (isAb)
|
||||
SA = AbilityFactory_Destroy.createAbilityDestroy(this);
|
||||
@@ -374,13 +387,14 @@ public class AbilityFactory {
|
||||
SA = c.getSpellCounter(this);
|
||||
}
|
||||
|
||||
if (SA != null){
|
||||
if(hasSubAbility())
|
||||
SA.setSubAbility(getSubAbility());
|
||||
}
|
||||
|
||||
if (SA == null)
|
||||
throw new RuntimeException("AbilityFactory : SpellAbility was not created. Did you add the API section?");
|
||||
|
||||
// *********************************************
|
||||
// set universal properties of the SpellAbility
|
||||
if(hasSubAbility())
|
||||
SA.setSubAbility(getSubAbility());
|
||||
|
||||
if (hasSpDesc)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
@@ -391,7 +405,7 @@ public class AbilityFactory {
|
||||
sb.append(mapParams.get("CostDesc")).append(" ");
|
||||
else sb.append(abCost.toString());
|
||||
|
||||
sb.append(mapParams.get("SpellDescription"));
|
||||
sb.append(mapParams.get("SpellDescription"));
|
||||
|
||||
SA.setDescription(sb.toString());
|
||||
}
|
||||
|
||||
259
src/forge/AbilityFactory_Sacrifice.java
Normal file
259
src/forge/AbilityFactory_Sacrifice.java
Normal 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));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -757,105 +757,29 @@ public class CardFactoryUtil {
|
||||
};
|
||||
return target;
|
||||
}//input_targetPermanent()
|
||||
|
||||
|
||||
//CardList choices are the only cards the user can successful select
|
||||
//sacrifices one of the CardList choices
|
||||
public static Input input_sacrifice(final SpellAbility spell, final CardList choices, final String message) {
|
||||
|
||||
public static Input input_destroyNoRegeneration(final CardList choices, final String message) {
|
||||
Input target = new Input() {
|
||||
private static final long serialVersionUID = 2685832214519141903L;
|
||||
|
||||
@Override
|
||||
private static final long serialVersionUID = -6637588517573573232L;
|
||||
|
||||
@Override
|
||||
public void showMessage() {
|
||||
AllZone.Display.showMessage(message);
|
||||
ButtonUtil.enableOnlyCancel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void selectButtonCancel() {
|
||||
stop();
|
||||
ButtonUtil.disableAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void selectCard(Card card, PlayerZone zone) {
|
||||
if(choices.contains(card)) {
|
||||
AllZone.getZone(card).remove(card);
|
||||
AllZone.GameAction.moveToGraveyard(card);
|
||||
|
||||
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));
|
||||
AllZone.GameAction.destroyNoRegeneration(card);
|
||||
stop();
|
||||
}
|
||||
}
|
||||
};
|
||||
return target;
|
||||
}//input_sacrifice()
|
||||
|
||||
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()
|
||||
|
||||
|
||||
}//input_destroyNoRegeneration()
|
||||
|
||||
public static Input Wheneverinput_sacrifice(final SpellAbility spell, final CardList choices, final String message, final Command Paid) {
|
||||
Input target = new Input() {
|
||||
private static final long serialVersionUID = 2685832214519141903L;
|
||||
@@ -883,43 +807,7 @@ public class CardFactoryUtil {
|
||||
};
|
||||
return target;
|
||||
}//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:
|
||||
public static Input input_sacrificePermanent(final SpellAbility spell, final CardList choices, final String message) {
|
||||
Input target = new Input() {
|
||||
@@ -954,94 +842,25 @@ public class CardFactoryUtil {
|
||||
return target;
|
||||
}//input_sacrifice()
|
||||
|
||||
|
||||
public static Input input_sacrificePermanent(final CardList choices, final String message) {
|
||||
Input target = new Input() {
|
||||
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;
|
||||
return input_sacrificePermanentsFromList(1, choices, "Select a permanent to 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) {
|
||||
Input target = new Input() {
|
||||
private static final long serialVersionUID = -8149416676562317629L;
|
||||
int n = 0;
|
||||
|
||||
@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;
|
||||
CardList list = AllZoneUtil.getPlayerCardsInPlay(AllZone.HumanPlayer);
|
||||
list.remove("Mana Pool"); // is this needed?
|
||||
return input_sacrificePermanentsFromList(nCards, list, "Select a permanent to sacrifice");
|
||||
}//input_sacrificePermanents()
|
||||
|
||||
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() {
|
||||
private static final long serialVersionUID = 1981791992623774490L;
|
||||
int n = 0;
|
||||
@@ -1049,23 +868,20 @@ public class CardFactoryUtil {
|
||||
@Override
|
||||
public void showMessage() {
|
||||
//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();
|
||||
|
||||
AllZone.Display.showMessage("Select a " +type +" to sacrifice (" +(nCards-n) +" left)");
|
||||
AllZone.Display.showMessage(message + " (" +(nCards-n) +" left)");
|
||||
ButtonUtil.disableAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
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);
|
||||
n++;
|
||||
list.remove(card);
|
||||
|
||||
//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();
|
||||
else
|
||||
showMessage();
|
||||
|
||||
@@ -7064,76 +7064,14 @@ public class CardFactory_Creatures {
|
||||
}//*************** 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 **************************
|
||||
else if(cardName.equals("Spitting Spider")) {
|
||||
final Ability ability = new Ability(card, "0") {
|
||||
@Override
|
||||
// temporary fix until DamageAll is created
|
||||
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() {
|
||||
return false;
|
||||
}
|
||||
@@ -7147,25 +7085,12 @@ public class CardFactory_Creatures {
|
||||
}//resolve()
|
||||
};//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();
|
||||
sb.append(card).append(" deals 1 damage to each creature with flying.");
|
||||
ability.setStackDescription(sb.toString());
|
||||
|
||||
ability.setDescription("Sacrifice a land: Spitting Spider deals 1 damage to each creature with flying.");
|
||||
|
||||
card.addSpellAbility(ability);
|
||||
ability.setBeforePayMana(runtime);
|
||||
}//*************** END ************ END **************************
|
||||
|
||||
|
||||
|
||||
@@ -3146,35 +3146,6 @@ public class CardFactory_Instants {
|
||||
|
||||
return card;
|
||||
}//*************** 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 **************************
|
||||
else if(cardName.equals("Path to Exile")) {
|
||||
|
||||
@@ -1009,14 +1009,7 @@ public class CombatUtil {
|
||||
if (crd.getController().isHuman())
|
||||
{
|
||||
CardList list = new CardList(AllZone.Computer_Play.getCards());
|
||||
CardListUtil.sortCMC(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));
|
||||
ComputerUtil.sacrificePermanents(a, list);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -759,4 +759,43 @@ public class ComputerUtil
|
||||
};//Comparator
|
||||
Arrays.sort(sa, c);
|
||||
}//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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user