package forge.card.abilityFactory;
import forge.AllZone;
import forge.Card;
import forge.ComputerUtil;
import forge.Player;
import forge.card.spellability.*;
import java.util.ArrayList;
/**
* <p>AbilityFactory_EndGameCondition class.</p>
*
* @author Forge
* @version $Id: $
*/
public class AbilityFactory_EndGameCondition {
// ***********************************************************************************************
// ***************************************** Wins Game *******************************************
// ***********************************************************************************************
/**
* <p>createAbilityWinsGame.</p>
*
* @param AF a {@link forge.card.abilityFactory.AbilityFactory} object.
* @return a {@link forge.card.spellability.SpellAbility} object.
*/
public static SpellAbility createAbilityWinsGame(final AbilityFactory AF) {
final SpellAbility abWinsGame = new Ability_Activated(AF.getHostCard(), AF.getAbCost(), AF.getAbTgt()) {
private static final long serialVersionUID = 8869422603616247307L;
final AbilityFactory af = AF;
@Override
public String getStackDescription() {
// when getStackDesc is called, just build exactly what is happening
return winsGameStackDescription(af, this);
}
public boolean canPlayAI() {
return winsGameCanPlayAI(af, this);
}
@Override
public void resolve() {
winsGameResolve(af, this);
}
@Override
public boolean doTrigger(boolean mandatory) {
return winsGameDoTriggerAI(af, this, mandatory);
}
};
return abWinsGame;
}
/**
* <p>createSpellWinsGame.</p>
*
* @param AF a {@link forge.card.abilityFactory.AbilityFactory} object.
* @return a {@link forge.card.spellability.SpellAbility} object.
*/
public static SpellAbility createSpellWinsGame(final AbilityFactory AF) {
final SpellAbility spWinsGame = new Spell(AF.getHostCard(), AF.getAbCost(), AF.getAbTgt()) {
private static final long serialVersionUID = 6631124959690157874L;
final AbilityFactory af = AF;
@Override
public String getStackDescription() {
// when getStackDesc is called, just build exactly what is happening
return winsGameStackDescription(af, this);
}
public boolean canPlayAI() {
// if X depends on abCost, the AI needs to choose which card he would sacrifice first
// then call xCount with that card to properly calculate the amount
// Or choosing how many to sacrifice
return winsGameCanPlayAI(af, this);
}
@Override
public void resolve() {
winsGameResolve(af, this);
}
};
return spWinsGame;
}
/**
* <p>createDrawbackWinsGame.</p>
*
* @param AF a {@link forge.card.abilityFactory.AbilityFactory} object.
* @return a {@link forge.card.spellability.SpellAbility} object.
*/
public static SpellAbility createDrawbackWinsGame(final AbilityFactory AF) {
final SpellAbility dbWinsGame = new Ability_Sub(AF.getHostCard(), AF.getAbTgt()) {
private static final long serialVersionUID = 6631124959690157874L;
final AbilityFactory af = AF;
@Override
public String getStackDescription() {
// when getStackDesc is called, just build exactly what is happening
return winsGameStackDescription(af, this);
}
public boolean canPlayAI() {
// if X depends on abCost, the AI needs to choose which card he would sacrifice first
// then call xCount with that card to properly calculate the amount
// Or choosing how many to sacrifice
return winsGameCanPlayAI(af, this);
}
@Override
public void resolve() {
winsGameResolve(af, this);
}
@Override
public boolean chkAI_Drawback() {
return true;
}
@Override
public boolean doTrigger(boolean mandatory) {
return winsGameDoTriggerAI(af, this, mandatory);
}
};
return dbWinsGame;
}
/**
* <p>winsGameStackDescription.</p>
*
* @param af a {@link forge.card.abilityFactory.AbilityFactory} object.
* @param sa a {@link forge.card.spellability.SpellAbility} object.
* @return a {@link java.lang.String} object.
*/
public static String winsGameStackDescription(AbilityFactory af, SpellAbility sa) {
StringBuilder sb = new StringBuilder();
if (!(sa instanceof Ability_Sub))
sb.append(sa.getSourceCard().getName()).append(" - ");
else
sb.append(" ");
// Let the spell description also be the stack description
sb.append(sa.getDescription());
Ability_Sub abSub = sa.getSubAbility();
if (abSub != null) {
sb.append(abSub.getStackDescription());
}
return sb.toString();
}
/**
* <p>winsGameCanPlayAI.</p>
*
* @param af a {@link forge.card.abilityFactory.AbilityFactory} object.
* @param sa a {@link forge.card.spellability.SpellAbility} object.
* @return a boolean.
*/
public static boolean winsGameCanPlayAI(final AbilityFactory af, final SpellAbility sa) {
if (AllZone.getComputerPlayer().cantWin())
return false;
// TODO: Check conditions are met on card (e.g. Coalition Victory)
// TODO: Consider likelihood of SA getting countered
// In general, don't return true.
// But this card wins the game, I can make an exception for that
return true;
}
/**
* <p>winsGameDoTriggerAI.</p>
*
* @param af a {@link forge.card.abilityFactory.AbilityFactory} object.
* @param sa a {@link forge.card.spellability.SpellAbility} object.
* @param mandatory a boolean.
* @return a boolean.
*/
public static boolean winsGameDoTriggerAI(AbilityFactory af, SpellAbility sa, boolean mandatory) {
if (!ComputerUtil.canPayCost(sa) && !mandatory) // If there is a cost payment it's usually not mandatory
return false;
// WinGame abilities usually don't have subAbilities but for consistency...
Ability_Sub abSub = sa.getSubAbility();
if (abSub != null) {
return abSub.doTrigger(mandatory);
}
return true;
}
/**
* <p>winsGameResolve.</p>
*
* @param af a {@link forge.card.abilityFactory.AbilityFactory} object.
* @param sa a {@link forge.card.spellability.SpellAbility} object.
*/
public static void winsGameResolve(final AbilityFactory af, final SpellAbility sa) {
Card card = af.getHostCard();
ArrayList<Player> players = AbilityFactory.getDefinedPlayers(card, af.getMapParams().get("Defined"), sa);
for (Player p : players)
p.altWinConditionMet(card.getName());
}
// ***********************************************************************************************
// **************************************** Loses Game *******************************************
// ***********************************************************************************************
/**
* <p>createAbilityLosesGame.</p>
*
* @param AF a {@link forge.card.abilityFactory.AbilityFactory} object.
* @return a {@link forge.card.spellability.SpellAbility} object.
*/
public static SpellAbility createAbilityLosesGame(final AbilityFactory AF) {
final SpellAbility abLosesGame = new Ability_Activated(AF.getHostCard(), AF.getAbCost(), AF.getAbTgt()) {
private static final long serialVersionUID = 8869422603616247307L;
final AbilityFactory af = AF;
@Override
public String getStackDescription() {
// when getStackDesc is called, just build exactly what is happening
return losesGameStackDescription(af, this);
}
public boolean canPlayAI() {
return losesGameCanPlayAI(af, this);
}
@Override
public void resolve() {
losesGameResolve(af, this);
}
@Override
public boolean doTrigger(boolean mandatory) {
return losesGameDoTriggerAI(af, this, mandatory);
}
};
return abLosesGame;
}
/**
* <p>createSpellLosesGame.</p>
*
* @param AF a {@link forge.card.abilityFactory.AbilityFactory} object.
* @return a {@link forge.card.spellability.SpellAbility} object.
*/
public static SpellAbility createSpellLosesGame(final AbilityFactory AF) {
final SpellAbility spLosesGame = new Spell(AF.getHostCard(), AF.getAbCost(), AF.getAbTgt()) {
private static final long serialVersionUID = 6631124959690157874L;
final AbilityFactory af = AF;
@Override
public String getStackDescription() {
// when getStackDesc is called, just build exactly what is happening
return losesGameStackDescription(af, this);
}
public boolean canPlayAI() {
// if X depends on abCost, the AI needs to choose which card he would sacrifice first
// then call xCount with that card to properly calculate the amount
// Or choosing how many to sacrifice
return losesGameCanPlayAI(af, this);
}
@Override
public void resolve() {
losesGameResolve(af, this);
}
};
return spLosesGame;
}
/**
* <p>createDrawbackLosesGame.</p>
*
* @param AF a {@link forge.card.abilityFactory.AbilityFactory} object.
* @return a {@link forge.card.spellability.SpellAbility} object.
*/
public static SpellAbility createDrawbackLosesGame(final AbilityFactory AF) {
final SpellAbility dbLosesGame = new Ability_Sub(AF.getHostCard(), AF.getAbTgt()) {
private static final long serialVersionUID = 6631124959690157874L;
final AbilityFactory af = AF;
@Override
public String getStackDescription() {
// when getStackDesc is called, just build exactly what is happening
return losesGameStackDescription(af, this);
}
public boolean canPlayAI() {
// if X depends on abCost, the AI needs to choose which card he would sacrifice first
// then call xCount with that card to properly calculate the amount
// Or choosing how many to sacrifice
return losesGameCanPlayAI(af, this);
}
@Override
public void resolve() {
losesGameResolve(af, this);
}
@Override
public boolean chkAI_Drawback() {
return true;
}
@Override
public boolean doTrigger(boolean mandatory) {
return losesGameDoTriggerAI(af, this, mandatory);
}
};
return dbLosesGame;
}
/**
* <p>losesGameStackDescription.</p>
*
* @param af a {@link forge.card.abilityFactory.AbilityFactory} object.
* @param sa a {@link forge.card.spellability.SpellAbility} object.
* @return a {@link java.lang.String} object.
*/
public static String losesGameStackDescription(AbilityFactory af, SpellAbility sa) {
StringBuilder sb = new StringBuilder();
Card source = sa.getSourceCard();
if (!(sa instanceof Ability_Sub))
sb.append(source.getName()).append(" - ");
else
sb.append(" ");
Target tgt = sa.getTarget();
ArrayList<Player> players = null;
if (sa.getTarget() != null) {
players = tgt.getTargetPlayers();
} else {
players = AbilityFactory.getDefinedPlayers(source, af.getMapParams().get("Defined"), sa);
}
for (Player p : players) {
sb.append(p.getName()).append(" ");
}
sb.append("loses the game.");
Ability_Sub abSub = sa.getSubAbility();
if (abSub != null) {
sb.append(abSub.getStackDescription());
}
return sb.toString();
}
/**
* <p>losesGameCanPlayAI.</p>
*
* @param af a {@link forge.card.abilityFactory.AbilityFactory} object.
* @param sa a {@link forge.card.spellability.SpellAbility} object.
* @return a boolean.
*/
public static boolean losesGameCanPlayAI(final AbilityFactory af, final SpellAbility sa) {
if (AllZone.getHumanPlayer().cantLose())
return false;
// Only one SA Lose the Game card right now, which is Door to Nothingness
Target tgt = sa.getTarget();
if (tgt != null) {
tgt.resetTargets();
tgt.addTarget(AllZone.getHumanPlayer());
}
// In general, don't return true.
// But this card wins the game, I can make an exception for that
return true;
}
/**
* <p>losesGameDoTriggerAI.</p>
*
* @param af a {@link forge.card.abilityFactory.AbilityFactory} object.
* @param sa a {@link forge.card.spellability.SpellAbility} object.
* @param mandatory a boolean.
* @return a boolean.
*/
public static boolean losesGameDoTriggerAI(AbilityFactory af, SpellAbility sa, boolean mandatory) {
if (!ComputerUtil.canPayCost(sa) && !mandatory) // If there is a cost payment it's usually not mandatory
return false;
// Phage the Untouchable
// (Final Fortune would need to attach it's delayed trigger to a specific turn, which can't be done yet)
if (!mandatory && AllZone.getHumanPlayer().cantLose())
return false;
Target tgt = sa.getTarget();
if (tgt != null) {
tgt.resetTargets();
tgt.addTarget(AllZone.getHumanPlayer());
}
// WinGame abilities usually don't have subAbilities but for consistency...
Ability_Sub abSub = sa.getSubAbility();
if (abSub != null) {
return abSub.doTrigger(mandatory);
}
return true;
}
/**
* <p>losesGameResolve.</p>
*
* @param af a {@link forge.card.abilityFactory.AbilityFactory} object.
* @param sa a {@link forge.card.spellability.SpellAbility} object.
*/
public static void losesGameResolve(final AbilityFactory af, final SpellAbility sa) {
Card card = af.getHostCard();
Target tgt = sa.getTarget();
ArrayList<Player> players = null;
if (sa.getTarget() != null) {
players = tgt.getTargetPlayers();
} else {
players = AbilityFactory.getDefinedPlayers(card, af.getMapParams().get("Defined"), sa);
}
for (Player p : players)
p.altLoseConditionMet(card.getName());
}
}