mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 04:08:01 +00:00
Fix battles attacking/blocking (#7075)
* Add battle SBA --------- Co-authored-by: tool4EvEr <tool4EvEr@192.168.0.59> Co-authored-by: tool4EvEr <tool4EvEr@192.168.0.60>
This commit is contained in:
@@ -1659,11 +1659,23 @@ public class GameAction {
|
|||||||
|
|
||||||
private boolean stateBasedAction_Battle(Card c, CardCollection removeList) {
|
private boolean stateBasedAction_Battle(Card c, CardCollection removeList) {
|
||||||
boolean checkAgain = false;
|
boolean checkAgain = false;
|
||||||
if (!c.getType().isBattle()) {
|
if (!c.isBattle()) {
|
||||||
return false;
|
return checkAgain;
|
||||||
|
}
|
||||||
|
if (((c.getProtectingPlayer() == null || !c.getProtectingPlayer().isInGame()) &&
|
||||||
|
(game.getCombat() == null || game.getCombat().getAttackersOf(c).isEmpty())) ||
|
||||||
|
(c.getType().hasStringType("Siege") && c.getController().equals(c.getProtectingPlayer()))) {
|
||||||
|
Player newProtector = c.getController().getController().chooseSingleEntityForEffect(c.getController().getOpponents(), null, "Choose an opponent to protect this battle", null);
|
||||||
|
// seems unlikely unless range of influence gets implemented
|
||||||
|
if (newProtector == null) {
|
||||||
|
removeList.add(c);
|
||||||
|
} else {
|
||||||
|
c.setProtectingPlayer(newProtector);
|
||||||
|
}
|
||||||
|
checkAgain = true;
|
||||||
}
|
}
|
||||||
if (c.getCounters(CounterEnumType.DEFENSE) > 0) {
|
if (c.getCounters(CounterEnumType.DEFENSE) > 0) {
|
||||||
return false;
|
return checkAgain;
|
||||||
}
|
}
|
||||||
// 704.5v If a battle has defense 0 and it isn't the source of an ability that has triggered but not yet left the stack,
|
// 704.5v If a battle has defense 0 and it isn't the source of an ability that has triggered but not yet left the stack,
|
||||||
// it’s put into its owner’s graveyard.
|
// it’s put into its owner’s graveyard.
|
||||||
|
|||||||
@@ -519,14 +519,6 @@ public class CardFactoryUtil {
|
|||||||
return filteredkw;
|
return filteredkw;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getCardTypesFromList(final CardCollectionView list) {
|
|
||||||
EnumSet<CardType.CoreType> types = EnumSet.noneOf(CardType.CoreType.class);
|
|
||||||
for (Card c1 : list) {
|
|
||||||
c1.getType().getCoreTypes().forEach(types::add);
|
|
||||||
}
|
|
||||||
return types.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds the ability factory abilities.
|
* Adds the ability factory abilities.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -201,6 +201,10 @@ public class CombatUtil {
|
|||||||
private static boolean canAttack(final Card attacker, final GameEntity defender, final boolean forNextTurn) {
|
private static boolean canAttack(final Card attacker, final GameEntity defender, final boolean forNextTurn) {
|
||||||
final Game game = attacker.getGame();
|
final Game game = attacker.getGame();
|
||||||
|
|
||||||
|
if (attacker.isBattle()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Basic checks (unless is for next turn)
|
// Basic checks (unless is for next turn)
|
||||||
if (!forNextTurn && (
|
if (!forNextTurn && (
|
||||||
!attacker.isCreature()
|
!attacker.isCreature()
|
||||||
@@ -480,6 +484,10 @@ public class CombatUtil {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (blocker.isBattle()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!nextTurn && blocker.isTapped() && !blocker.hasKeyword("CARDNAME can block as though it were untapped.")) {
|
if (!nextTurn && blocker.isTapped() && !blocker.hasKeyword("CARDNAME can block as though it were untapped.")) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -222,7 +222,7 @@ public class CostExile extends CostPartWithList {
|
|||||||
int amount = this.getAbilityAmount(ability);
|
int amount = this.getAbilityAmount(ability);
|
||||||
|
|
||||||
if (nTypes > -1) {
|
if (nTypes > -1) {
|
||||||
if (CardFactoryUtil.getCardTypesFromList(list) < nTypes) return false;
|
if (AbilityUtils.countCardTypesFromList(list, false) < nTypes) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sharedType) { // will need more logic if cost ever wants more than 2 that share a type
|
if (sharedType) { // will need more logic if cost ever wants more than 2 that share a type
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import forge.card.mana.ManaCostShard;
|
|||||||
import forge.game.*;
|
import forge.game.*;
|
||||||
import forge.game.ability.AbilityFactory;
|
import forge.game.ability.AbilityFactory;
|
||||||
import forge.game.ability.AbilityKey;
|
import forge.game.ability.AbilityKey;
|
||||||
|
import forge.game.ability.AbilityUtils;
|
||||||
import forge.game.ability.ApiType;
|
import forge.game.ability.ApiType;
|
||||||
import forge.game.ability.effects.DetachedCardEffect;
|
import forge.game.ability.effects.DetachedCardEffect;
|
||||||
import forge.game.ability.effects.RollDiceEffect;
|
import forge.game.ability.effects.RollDiceEffect;
|
||||||
@@ -2176,7 +2177,7 @@ public class Player extends GameEntity implements Comparable<Player> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final boolean hasDelirium() {
|
public final boolean hasDelirium() {
|
||||||
return CardFactoryUtil.getCardTypesFromList(getCardsIn(ZoneType.Graveyard)) >= 4;
|
return AbilityUtils.countCardTypesFromList(getCardsIn(ZoneType.Graveyard), false) >= 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final boolean hasLandfall() {
|
public final boolean hasLandfall() {
|
||||||
|
|||||||
@@ -303,7 +303,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
|||||||
inp.setCancelAllowed(true);
|
inp.setCancelAllowed(true);
|
||||||
inp.showAndWait();
|
inp.showAndWait();
|
||||||
if (inp.hasCancelled() ||
|
if (inp.hasCancelled() ||
|
||||||
!Expressions.compare(CardFactoryUtil.getCardTypesFromList(list), "GE", nTypes)) {
|
!Expressions.compare(AbilityUtils.countCardTypesFromList(list, false), "GE", nTypes)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return PaymentDecision.card(inp.getSelected());
|
return PaymentDecision.card(inp.getSelected());
|
||||||
|
|||||||
Reference in New Issue
Block a user