mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 11:48:02 +00:00
"take priority" changed: now on priority SBA is checked, triggers are ordered, then player is asked for spell they want to play, then spell is played. Until player refuses to choose a spell, that means "I pass"
This commit is contained in:
@@ -55,6 +55,7 @@ import forge.game.cost.CostPart;
|
||||
import forge.game.phase.PhaseType;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.player.PlayerActionConfirmMode;
|
||||
import forge.game.spellability.Ability;
|
||||
import forge.game.spellability.AbilityManaPart;
|
||||
import forge.game.spellability.Spell;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
@@ -735,20 +736,24 @@ public class AiController {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void onPriorityRecieved() {
|
||||
public SpellAbility choooseSpellAbilityToPlay() {
|
||||
final PhaseType phase = game.getPhaseHandler().getPhase();
|
||||
switch(phase) {
|
||||
case MAIN1:
|
||||
case MAIN2:
|
||||
Log.debug("Computer " + phase.nameForUi);
|
||||
|
||||
if (game.getStack().isEmpty())
|
||||
playLands();
|
||||
// fall through is intended
|
||||
default:
|
||||
playSpellAbilities(game);
|
||||
break;
|
||||
|
||||
if (game.getStack().isEmpty() && phase.isMain()) {
|
||||
Log.debug("Computer " + phase.nameForUi);
|
||||
List<Card> landsWannaPlay = getLandsToPlay();
|
||||
if(landsWannaPlay != null && !landsWannaPlay.isEmpty() && player.canPlayLand(null)) {
|
||||
Card land = chooseBestLandToPlay(landsWannaPlay);
|
||||
if (ComputerUtil.damageFromETB(player, land) < player.getLife() || !player.canLoseLife()) {
|
||||
Ability.PLAY_LAND_SURROGATE.setSourceCard(land);
|
||||
return Ability.PLAY_LAND_SURROGATE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SpellAbility sa = getSpellAbilityToPlay();
|
||||
// System.out.println("Chosen to play: " + sa);
|
||||
return sa;
|
||||
}
|
||||
|
||||
// declares blockers for given defender in a given combat
|
||||
@@ -778,37 +783,6 @@ public class AiController {
|
||||
return combat;
|
||||
}
|
||||
|
||||
private void playLands() {
|
||||
final Player player = getPlayer();
|
||||
List<Card> landsWannaPlay = getLandsToPlay();
|
||||
|
||||
while(landsWannaPlay != null && !landsWannaPlay.isEmpty() && player.canPlayLand(null)) {
|
||||
Card land = chooseBestLandToPlay(landsWannaPlay);
|
||||
if (ComputerUtil.damageFromETB(player, land) >= player.getLife() && player.canLoseLife()) {
|
||||
break;
|
||||
}
|
||||
landsWannaPlay.remove(land);
|
||||
player.playLand(land, false);
|
||||
game.getPhaseHandler().setPriority(player);
|
||||
game.getAction().checkStateEffects();
|
||||
}
|
||||
}
|
||||
|
||||
private void playSpellAbilities(final Game game)
|
||||
{
|
||||
SpellAbility sa;
|
||||
do {
|
||||
if ( game.isGameOver() )
|
||||
return;
|
||||
sa = getSpellAbilityToPlay();
|
||||
if ( sa == null ) break;
|
||||
//System.out.println("Playing sa: " + sa);
|
||||
if (!ComputerUtil.handlePlayingSpellAbility(player, sa, game)) {
|
||||
break;
|
||||
}
|
||||
} while ( sa != null );
|
||||
}
|
||||
|
||||
private final SpellAbility getSpellAbilityToPlay() {
|
||||
// if top of stack is owned by me
|
||||
if (!game.getStack().isEmpty() && game.getStack().peekAbility().getActivatingPlayer().equals(player)) {
|
||||
|
||||
@@ -975,15 +975,23 @@ public class PhaseHandler implements java.io.Serializable {
|
||||
sw.start();
|
||||
}
|
||||
|
||||
// Rule 704.3 Whenever a player would get priority, the game checks ... for state-based actions,
|
||||
game.getAction().checkStateEffects();
|
||||
game.fireEvent(new GameEventPlayerPriority(getPlayerTurn(), getPhase(), getPriorityPlayer()));
|
||||
SpellAbility chosenSa = null;
|
||||
|
||||
// SBA could lead to game over
|
||||
if (game.isGameOver()) { return; }
|
||||
do {
|
||||
// Rule 704.3 Whenever a player would get priority, the game checks ... for state-based actions,
|
||||
game.getAction().checkStateEffects();
|
||||
if (game.isGameOver())
|
||||
return; // state-based effects check could lead to game over
|
||||
|
||||
game.getStack().chooseOrderOfSimultaneousStackEntry(pPlayerPriority);
|
||||
pPlayerPriority.getController().takePriority();
|
||||
game.getStack().chooseOrderOfSimultaneousStackEntry(pPlayerPriority);
|
||||
|
||||
chosenSa = pPlayerPriority.getController().chooseSpellAbilityToPlay();
|
||||
if( null == chosenSa )
|
||||
break; // that means 'I pass'
|
||||
|
||||
pPlayerPriority.getController().playChosenSpellAbility(chosenSa);
|
||||
} while (chosenSa != null);
|
||||
|
||||
if (DEBUG_PHASES) {
|
||||
sw.stop();
|
||||
@@ -1006,18 +1014,7 @@ public class PhaseHandler implements java.io.Serializable {
|
||||
if( DEBUG_PHASES )
|
||||
System.out.println(String.format("%s %s: %s passes priority to %s", playerTurn, phase, pPlayerPriority, nextPlayer));
|
||||
if (getFirstPriority() == nextPlayer) {
|
||||
|
||||
if (game.getStack().hasSimultaneousStackEntries() && givePriorityToPlayer)
|
||||
{
|
||||
Player ap = nextPlayer;
|
||||
Player nap = game.getNextPlayerAfter(ap);
|
||||
game.getStack().chooseOrderOfSimultaneousStackEntry(ap);
|
||||
do {
|
||||
game.getStack().chooseOrderOfSimultaneousStackEntry(nap);
|
||||
nap = game.getNextPlayerAfter(nap);
|
||||
} while( nap != ap);
|
||||
// All have passed, but there's something waiting to be added to stack. After that and give them priority again
|
||||
} else if (game.getStack().isEmpty()) {
|
||||
if (game.getStack().isEmpty()) {
|
||||
this.setPriority(this.getPlayerTurn()); // this needs to be set early as we exit the phase
|
||||
|
||||
// end phase
|
||||
|
||||
@@ -180,7 +180,8 @@ public abstract class PlayerController {
|
||||
|
||||
public abstract void declareAttackers(Player attacker, Combat combat);
|
||||
public abstract void declareBlockers(Player defender, Combat combat);
|
||||
public abstract void takePriority();
|
||||
public abstract SpellAbility chooseSpellAbilityToPlay();
|
||||
public abstract void playChosenSpellAbility(SpellAbility sa);
|
||||
|
||||
public abstract List<Card> chooseCardsToDiscardToMaximumHandSize(int numDiscard);
|
||||
public abstract boolean payManaOptional(Card card, Cost cost, SpellAbility sa, String prompt, ManaPaymentPurpose purpose);
|
||||
|
||||
@@ -394,12 +394,19 @@ public class PlayerControllerAi extends PlayerController {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void takePriority() {
|
||||
if (!game.isGameOver()) {
|
||||
brains.onPriorityRecieved();
|
||||
}
|
||||
// use separate thread for AI?
|
||||
public SpellAbility chooseSpellAbilityToPlay() {
|
||||
return brains.choooseSpellAbilityToPlay();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playChosenSpellAbility(SpellAbility sa)
|
||||
{
|
||||
// System.out.println("Playing sa: " + sa);
|
||||
if ( sa == Ability.PLAY_LAND_SURROGATE )
|
||||
player.playLand(sa.getSourceCard(), false);
|
||||
else
|
||||
ComputerUtil.handlePlayingSpellAbility(player, sa, game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Card> chooseCardsToDiscardToMaximumHandSize(int numDiscard) {
|
||||
|
||||
Reference in New Issue
Block a user