mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 19:28:01 +00:00
Skip combat phases if player has no creatures that can attack
This commit is contained in:
@@ -20,6 +20,7 @@ package forge.game.combat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
@@ -669,6 +670,45 @@ public class CombatUtil {
|
||||
}
|
||||
}
|
||||
|
||||
// can a player attack with one or more creatures at the moment?
|
||||
/**
|
||||
* <p>
|
||||
* canAttack.
|
||||
* </p>
|
||||
*
|
||||
* @param p
|
||||
* a {@link forge.game.player} object.
|
||||
* @return a boolean.
|
||||
*/
|
||||
public static boolean canAttack(Player p) {
|
||||
List<Card> creatures = p.getCreaturesInPlay();
|
||||
if (creatures.isEmpty()) { return false; }
|
||||
|
||||
List<Player> defenders = p.getOpponents();
|
||||
if (defenders.isEmpty()) { return false; }
|
||||
|
||||
boolean foundCreatureThatCantAttackAlone = false;
|
||||
|
||||
for (Card c : creatures) {
|
||||
if (CombatUtil.canAttack(c)) {
|
||||
for (Player def : defenders) {
|
||||
if (CombatUtil.canAttackNextTurn(c, def)) {
|
||||
if (c.hasKeyword("CARDNAME can't attack or block alone.")) {
|
||||
//ensure another possible attacker is found
|
||||
//if the first one found can't attack alone
|
||||
if (!foundCreatureThatCantAttackAlone) {
|
||||
foundCreatureThatCantAttackAlone = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// can a creature attack given the combat state
|
||||
/**
|
||||
* <p>
|
||||
@@ -685,37 +725,40 @@ public class CombatUtil {
|
||||
int cntAttackers = combat.getAttackers().size();
|
||||
final Game game = c.getGame();
|
||||
|
||||
if (cntAttackers > 0) {
|
||||
for (final Card card : game.getCardsIn(ZoneType.Battlefield)) {
|
||||
for (final String keyword : card.getKeyword()) {
|
||||
if (keyword.equals("No more than two creatures can attack each combat.") && cntAttackers > 1) {
|
||||
if (cntAttackers > 1) {
|
||||
if (keyword.equals("No more than two creatures can attack each combat.")) {
|
||||
return false;
|
||||
}
|
||||
if (keyword.equals("No more than two creatures can attack you each combat.") && cntAttackers > 1
|
||||
&& card.getController().getOpponent().equals(c.getController())) {
|
||||
if (keyword.equals("No more than two creatures can attack you each combat.") &&
|
||||
card.getController().getOpponent().equals(c.getController())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (keyword.equals("CARDNAME can only attack alone.") && combat.isAttacking(card)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final List<Card> list = c.getController().getCreaturesInPlay();
|
||||
if (list.size() < 2 && c.hasKeyword("CARDNAME can't attack or block alone.")) {
|
||||
if (c.hasKeyword("CARDNAME can only attack alone.")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cntAttackers > 0 && c.hasKeyword("CARDNAME can only attack alone.")) {
|
||||
if (game.getStaticEffects().getGlobalRuleChange(GlobalRuleChange.onlyOneAttackerACombat)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (c.hasKeyword("CARDNAME can't attack or block alone.") &&
|
||||
c.getController().getCreaturesInPlay().size() < 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cntAttackers > 0
|
||||
&& game.getStaticEffects().getGlobalRuleChange(GlobalRuleChange.onlyOneAttackerACombat)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((cntAttackers > 0 || c.getController().getAttackedWithCreatureThisTurn())
|
||||
&& game.getStaticEffects().getGlobalRuleChange(GlobalRuleChange.onlyOneAttackerATurn)) {
|
||||
if ((cntAttackers > 0 || c.getController().getAttackedWithCreatureThisTurn()) &&
|
||||
game.getStaticEffects().getGlobalRuleChange(GlobalRuleChange.onlyOneAttackerATurn)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -806,7 +849,6 @@ public class CombatUtil {
|
||||
final int[] powerLimit = { 0 };
|
||||
String cantAttackKw = null;
|
||||
|
||||
|
||||
for( String kw : c.getKeyword()) {
|
||||
if (kw.startsWith("CARDNAME can't attack if defending player controls an untapped creature with power")) {
|
||||
cantAttackKw = kw;
|
||||
|
||||
@@ -51,6 +51,7 @@ import forge.game.card.CardLists;
|
||||
import forge.game.card.CardPredicates;
|
||||
import forge.game.card.CounterType;
|
||||
import forge.game.card.CardPredicates.Presets;
|
||||
import forge.game.combat.CombatUtil;
|
||||
import forge.game.event.GameEventLandPlayed;
|
||||
import forge.game.event.GameEventMulligan;
|
||||
import forge.game.event.GameEventPlayerControl;
|
||||
@@ -2947,7 +2948,6 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
* @return a boolean.
|
||||
*/
|
||||
public boolean isSkippingCombat() {
|
||||
|
||||
if (hasKeyword("Skip your next combat phase.")) {
|
||||
return true;
|
||||
}
|
||||
@@ -2963,7 +2963,8 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
//skip combat unless player has a creature that can attack
|
||||
return !CombatUtil.canAttack(this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -47,7 +47,6 @@ public class InputAttack extends InputSyncronizedBase {
|
||||
/** Constant <code>serialVersionUID=7849903731842214245L</code>. */
|
||||
private static final long serialVersionUID = 7849903731842214245L;
|
||||
|
||||
|
||||
private final Combat combat;
|
||||
private final List<GameEntity> defenders;
|
||||
private GameEntity currentDefender;
|
||||
@@ -62,7 +61,6 @@ public class InputAttack extends InputSyncronizedBase {
|
||||
this.defenders = combat.getDefenders();
|
||||
}
|
||||
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public final void showMessage() {
|
||||
|
||||
Reference in New Issue
Block a user