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_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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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());
|
||||||
}
|
}
|
||||||
|
|||||||
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
|||||||
@@ -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 **************************
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user