mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 12:18:00 +00:00
dredge action from player* moved: decisions are taken at PlayerController, execution remains in Player
This commit is contained in:
@@ -2,6 +2,7 @@ Name:Land Equilibrium
|
|||||||
ManaCost:2 U U
|
ManaCost:2 U U
|
||||||
Types:Enchantment
|
Types:Enchantment
|
||||||
Text:If an opponent who controls at least as many lands as you do would put a land onto the battlefield, that player instead puts that land onto the battlefield then sacrifices a land.
|
Text:If an opponent who controls at least as many lands as you do would put a land onto the battlefield, that player instead puts that land onto the battlefield then sacrifices a land.
|
||||||
|
SVar:SacLand:DB$ Sacrifice | SacValid$ Land | Defined$ Opponent | SpellDescription$ Opponent sacrifices a land
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/land_equilibrium.jpg
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/land_equilibrium.jpg
|
||||||
Oracle:If an opponent who controls at least as many lands as you do would put a land onto the battlefield, that player instead puts that land onto the battlefield then sacrifices a land.
|
Oracle:If an opponent who controls at least as many lands as you do would put a land onto the battlefield, that player instead puts that land onto the battlefield then sacrifices a land.
|
||||||
SetInfo:LEG Rare
|
SetInfo:LEG Rare
|
||||||
@@ -48,6 +48,7 @@ import forge.game.player.Player;
|
|||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
import forge.util.Aggregates;
|
import forge.util.Aggregates;
|
||||||
import forge.util.Expressions;
|
import forge.util.Expressions;
|
||||||
|
import forge.util.MyRandom;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
@@ -706,5 +707,18 @@ public class AiController {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AI decides if he wants to use dredge ability and which one if many available
|
||||||
|
* @param dredgers - contains at least single element
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Card chooseCardToDredge(List<Card> dredgers) {
|
||||||
|
// use dredge if there are more than one of them in your graveyard
|
||||||
|
if (dredgers.size() > 1 || MyRandom.getRandom().nextBoolean()) {
|
||||||
|
return Aggregates.random(dredgers);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,8 +18,6 @@
|
|||||||
package forge.game.player;
|
package forge.game.player;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
import forge.Card;
|
import forge.Card;
|
||||||
|
|
||||||
import forge.CardLists;
|
import forge.CardLists;
|
||||||
@@ -27,10 +25,8 @@ import forge.CardPredicates;
|
|||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.game.GameState;
|
import forge.game.GameState;
|
||||||
import forge.game.ai.AiController;
|
import forge.game.ai.AiController;
|
||||||
import forge.game.ai.ComputerUtilCard;
|
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
import forge.util.Aggregates;
|
import forge.util.Aggregates;
|
||||||
import forge.util.MyRandom;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
@@ -63,43 +59,6 @@ public class AIPlayer extends Player {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
// //////////////////////////////
|
|
||||||
// /
|
|
||||||
// / replaces Singletons.getModel().getGameAction().draw* methods
|
|
||||||
// /
|
|
||||||
// //////////////////////////////
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* dredge.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @return a boolean.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final boolean dredge() {
|
|
||||||
final List<Card> dredgers = this.getDredge();
|
|
||||||
final Random random = MyRandom.getRandom();
|
|
||||||
|
|
||||||
// use dredge if there are more than one of them in your graveyard
|
|
||||||
if ((dredgers.size() > 1) || ((dredgers.size() == 1) && random.nextBoolean())) {
|
|
||||||
CardLists.shuffle(dredgers);
|
|
||||||
final Card c = dredgers.get(0);
|
|
||||||
// rule 702.49a
|
|
||||||
if (this.getDredgeNumber(c) <= this.getCardsIn(ZoneType.Library).size()) {
|
|
||||||
// dredge library, put card in hand
|
|
||||||
game.getAction().moveToHand(c);
|
|
||||||
// put dredge number in graveyard
|
|
||||||
for (int i = 0; i < this.getDredgeNumber(c); i++) {
|
|
||||||
final Card c2 = this.getCardsIn(ZoneType.Library).get(0);
|
|
||||||
game.getAction().moveToGraveyard(c2);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// //////////////////////////////
|
// //////////////////////////////
|
||||||
// /
|
// /
|
||||||
// / replaces Singletons.getModel().getGameAction().discard* methods
|
// / replaces Singletons.getModel().getGameAction().discard* methods
|
||||||
@@ -133,16 +92,6 @@ public class AIPlayer extends Player {
|
|||||||
|
|
||||||
// /////////////////////////
|
// /////////////////////////
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
|
||||||
@Override
|
|
||||||
public final void sacrificePermanent(final String prompt, final List<Card> choices) {
|
|
||||||
if (choices.size() > 0) {
|
|
||||||
// TODO - this could probably use better AI
|
|
||||||
final Card c = ComputerUtilCard.getWorstPermanentAI(choices, false, false, false, false);
|
|
||||||
game.getAction().sacrificeDestroy(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see forge.game.player.Player#getType()
|
* @see forge.game.player.Player#getType()
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -17,17 +17,10 @@
|
|||||||
*/
|
*/
|
||||||
package forge.game.player;
|
package forge.game.player;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import forge.Card;
|
|
||||||
|
|
||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.control.input.Input;
|
|
||||||
import forge.game.GameState;
|
import forge.game.GameState;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
import forge.gui.GuiChoose;
|
|
||||||
import forge.gui.GuiDialog;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
@@ -40,52 +33,11 @@ import forge.gui.GuiDialog;
|
|||||||
public class HumanPlayer extends Player {
|
public class HumanPlayer extends Player {
|
||||||
private PlayerControllerHuman controller;
|
private PlayerControllerHuman controller;
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* Constructor for HumanPlayer.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param myName
|
|
||||||
* a {@link java.lang.String} object.
|
|
||||||
*/
|
|
||||||
public HumanPlayer(final LobbyPlayer player, GameState game) {
|
public HumanPlayer(final LobbyPlayer player, GameState game) {
|
||||||
super(player, game);
|
super(player, game);
|
||||||
|
|
||||||
controller = new PlayerControllerHuman(game, this);
|
controller = new PlayerControllerHuman(game, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* dredge.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @return a boolean.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final boolean dredge() {
|
|
||||||
boolean dredged = false;
|
|
||||||
final boolean wantDredge = GuiDialog.confirm(null, "Do you want to dredge?");
|
|
||||||
if (wantDredge) {
|
|
||||||
final Card c = GuiChoose.one("Select card to dredge", this.getDredge());
|
|
||||||
// rule 702.49a
|
|
||||||
if (this.getDredgeNumber(c) <= getZone(ZoneType.Library).size()) {
|
|
||||||
|
|
||||||
// might have to make this more sophisticated
|
|
||||||
// dredge library, put card in hand
|
|
||||||
game.getAction().moveToHand(c);
|
|
||||||
|
|
||||||
for (int i = 0; i < this.getDredgeNumber(c); i++) {
|
|
||||||
final Card c2 = getZone(ZoneType.Library).get(0);
|
|
||||||
game.getAction().moveToGraveyard(c2);
|
|
||||||
}
|
|
||||||
dredged = true;
|
|
||||||
} else {
|
|
||||||
dredged = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dredged;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
@Override
|
@Override
|
||||||
public final void discard(final int num, final SpellAbility sa) {
|
public final void discard(final int num, final SpellAbility sa) {
|
||||||
@@ -100,26 +52,12 @@ public class HumanPlayer extends Player {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
|
||||||
@Override
|
|
||||||
public final void sacrificePermanent(final String prompt, final List<Card> choices) {
|
|
||||||
final Input in = PlayerUtil.inputSacrificePermanent(choices, prompt);
|
|
||||||
Singletons.getModel().getMatch().getInput().setInput(in);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see forge.game.player.Player#getType()
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public PlayerType getType() {
|
public PlayerType getType() {
|
||||||
return PlayerType.HUMAN;
|
return PlayerType.HUMAN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see forge.game.player.Player#getController()
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public PlayerController getController() {
|
public PlayerController getController() {
|
||||||
return controller;
|
return controller;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end HumanPlayer class
|
} // end HumanPlayer class
|
||||||
|
|||||||
@@ -1234,16 +1234,6 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
|
|||||||
return this.drawCards(1);
|
return this.drawCards(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* dredge.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @return a boolean.
|
|
||||||
*/
|
|
||||||
public abstract boolean dredge();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* TODO Write javadoc for this method.
|
* TODO Write javadoc for this method.
|
||||||
@@ -1288,8 +1278,17 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
|
|||||||
for (int i = 0; i < n; i++) {
|
for (int i = 0; i < n; i++) {
|
||||||
|
|
||||||
// TODO: multiple replacements need to be selected by the controller
|
// TODO: multiple replacements need to be selected by the controller
|
||||||
if (!this.getDredge().isEmpty()) {
|
List<Card> dredgers = this.getDredge();
|
||||||
if (this.dredge()) {
|
if (!dredgers.isEmpty()) {
|
||||||
|
Card toDredge = getController().chooseCardToDredge(dredgers);
|
||||||
|
int dredgeNumber = toDredge == null ? Integer.MAX_VALUE : getDredgeNumber(toDredge);
|
||||||
|
if ( dredgeNumber <= getZone(ZoneType.Library).size()) {
|
||||||
|
game.getAction().moveToHand(toDredge);
|
||||||
|
|
||||||
|
for (int iD = 0; iD < dredgeNumber; iD++) {
|
||||||
|
final Card c2 = getZone(ZoneType.Library).get(0);
|
||||||
|
game.getAction().moveToGraveyard(c2);
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2141,19 +2140,6 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
|
|||||||
this.attackersDeclaredThisTurn = 0;
|
this.attackersDeclaredThisTurn = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// //////////////////////////////
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* sacrificePermanent.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param prompt
|
|
||||||
* a {@link java.lang.String} object.
|
|
||||||
* @param choices
|
|
||||||
* a {@link forge.CardList} object.
|
|
||||||
*/
|
|
||||||
public abstract void sacrificePermanent(String prompt, List<Card> choices);
|
|
||||||
|
|
||||||
// Game win/loss
|
// Game win/loss
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -111,4 +111,5 @@ public abstract class PlayerController {
|
|||||||
|
|
||||||
/** p = target player, validCards - possible discards, min cards to discard */
|
/** p = target player, validCards - possible discards, min cards to discard */
|
||||||
public abstract List<Card> chooseCardsToDiscardFrom(Player p, SpellAbility sa, List<Card> validCards, int min);
|
public abstract List<Card> chooseCardsToDiscardFrom(Player p, SpellAbility sa, List<Card> validCards, int min);
|
||||||
|
public abstract Card chooseCardToDredge(List<Card> dredgers);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -255,9 +255,6 @@ public class PlayerControllerAi extends PlayerController {
|
|||||||
return true; // AI does not know what will happen next (another clash or that would become his topdeck)
|
return true; // AI does not know what will happen next (another clash or that would become his topdeck)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see forge.game.player.PlayerController#chooseCardsToDiscardFrom(forge.game.player.Player, java.util.List, int)
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public List<Card> chooseCardsToDiscardFrom(Player p, SpellAbility sa, List<Card> validCards, int min) {
|
public List<Card> chooseCardsToDiscardFrom(Player p, SpellAbility sa, List<Card> validCards, int min) {
|
||||||
boolean isTargetFriendly = !p.isOpponentOf(getPlayer());
|
boolean isTargetFriendly = !p.isOpponentOf(getPlayer());
|
||||||
@@ -267,4 +264,9 @@ public class PlayerControllerAi extends PlayerController {
|
|||||||
: ComputerUtil.getCardsToDiscardFromOpponent(player, p, sa, validCards, min);
|
: ComputerUtil.getCardsToDiscardFromOpponent(player, p, sa, validCards, min);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Card chooseCardToDredge(List<Card> dredgers) {
|
||||||
|
return brains.chooseCardToDredge(dredgers);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -326,4 +326,15 @@ public class PlayerControllerHuman extends PlayerController {
|
|||||||
public List<Card> chooseCardsToDiscardFrom(Player p, SpellAbility sa, List<Card> valid, int minDiscard) {
|
public List<Card> chooseCardsToDiscardFrom(Player p, SpellAbility sa, List<Card> valid, int minDiscard) {
|
||||||
return GuiChoose.order("Choose cards to Discard", "Discarded", minDiscard == 0 ? -1 : minDiscard, valid, null, null);
|
return GuiChoose.order("Choose cards to Discard", "Discarded", minDiscard == 0 ? -1 : minDiscard, valid, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see forge.game.player.PlayerController#chooseCardToDredge(java.util.List)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Card chooseCardToDredge(List<Card> dredgers) {
|
||||||
|
if (GuiDialog.confirm(null, "Do you want to dredge?", false)) {
|
||||||
|
return GuiChoose.oneOrNone("Select card to dredge", dredgers);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,10 +23,7 @@ package forge.game.player;
|
|||||||
* @author jendave
|
* @author jendave
|
||||||
*/
|
*/
|
||||||
public enum PlayerType {
|
public enum PlayerType {
|
||||||
|
|
||||||
/** The HUMAN. */
|
|
||||||
HUMAN,
|
HUMAN,
|
||||||
|
COMPUTER,
|
||||||
/** The COMPUTER. */
|
REMOTE
|
||||||
COMPUTER
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -154,22 +154,6 @@ public final class PlayerUtil {
|
|||||||
return target;
|
return target;
|
||||||
} // input_discard()
|
} // input_discard()
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* input_sacrificePermanent.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param choices
|
|
||||||
* a {@link forge.CardList} object.
|
|
||||||
* @param message
|
|
||||||
* a {@link java.lang.String} object.
|
|
||||||
* @return a {@link forge.control.input.Input} object.
|
|
||||||
* @since 1.0.15
|
|
||||||
*/
|
|
||||||
public static Input inputSacrificePermanent(final List<Card> choices, final String message) {
|
|
||||||
return PlayerUtil.inputSacrificePermanentsFromList(1, choices, message);
|
|
||||||
} // input_sacrifice()
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* input_sacrificePermanents.
|
* input_sacrificePermanents.
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import forge.CardPredicates;
|
|||||||
import forge.CardPredicates.Presets;
|
import forge.CardPredicates.Presets;
|
||||||
import forge.Command;
|
import forge.Command;
|
||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
|
import forge.card.ability.AbilityFactory;
|
||||||
import forge.card.mana.ManaCost;
|
import forge.card.mana.ManaCost;
|
||||||
import forge.card.spellability.Ability;
|
import forge.card.spellability.Ability;
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
@@ -143,30 +144,17 @@ public class PlayerZoneBattlefield extends PlayerZone {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final List<Card> les = c.getOwner().getOpponent().getCardsIn(ZoneType.Battlefield, "Land Equilibrium");
|
|
||||||
final Card lesLand = c;
|
for( Player opp : c.getOwner().getOpponents())
|
||||||
if (les.size() > 0) {
|
for( Card le : opp.getCardsIn(ZoneType.Battlefield, "Land Equilibrium") ) {
|
||||||
final Card source = les.get(0);
|
final List<Card> pLands = c.getOwner().getLandsInPlay();
|
||||||
final SpellAbility ability = new Ability(source, ManaCost.NO_COST) {
|
final List<Card> oLands = opp.getLandsInPlay();
|
||||||
@Override
|
|
||||||
public void resolve() {
|
if (oLands.size() <= (pLands.size() - 1)) {
|
||||||
final List<Card> lands = lesLand.getOwner().getLandsInPlay();
|
SpellAbility abSac = AbilityFactory.getAbility(le.getSVar("SacLand"), le);
|
||||||
lesLand.getOwner().sacrificePermanent(source.getName() + " - Select a land to sacrifice",
|
Singletons.getModel().getGame().getStack().addSimultaneousStackEntry(abSac);
|
||||||
lands);
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
final StringBuilder sb = new StringBuilder();
|
|
||||||
sb.append(source).append(" - ");
|
|
||||||
sb.append(tisLand.getController()).append(" sacrifices a land.");
|
|
||||||
ability.setStackDescription(sb.toString());
|
|
||||||
final List<Card> pLands = lesLand.getOwner().getLandsInPlay();
|
|
||||||
final List<Card> oLands = lesLand.getOwner().getOpponent().getLandsInPlay();
|
|
||||||
// (pLands - 1) because this land is in play, and the
|
|
||||||
// ability is before it is in play
|
|
||||||
if (oLands.size() <= (pLands.size() - 1)) {
|
|
||||||
Singletons.getModel().getGame().getStack().addSimultaneousStackEntry(ability);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} // isLand()
|
} // isLand()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user