mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 20:58:03 +00:00
Goodbye MustAttackEffect
This commit is contained in:
@@ -58,6 +58,9 @@ import forge.util.Expressions;
|
|||||||
import forge.util.MyRandom;
|
import forge.util.MyRandom;
|
||||||
import forge.util.collect.FCollection;
|
import forge.util.collect.FCollection;
|
||||||
import forge.util.collect.FCollectionView;
|
import forge.util.collect.FCollectionView;
|
||||||
|
import forge.util.maps.LinkedHashMapToAmount;
|
||||||
|
import forge.util.maps.MapToAmount;
|
||||||
|
import forge.util.maps.MapToAmountUtil;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -689,33 +692,18 @@ public class AiAttackController {
|
|||||||
}
|
}
|
||||||
GameEntity prefDefender = defs.contains(defendingOpponent) ? defendingOpponent : defs.get(0);
|
GameEntity prefDefender = defs.contains(defendingOpponent) ? defendingOpponent : defs.get(0);
|
||||||
|
|
||||||
// Attempt to see if there's a defined entity that must be attacked strictly this turn...
|
// 1. assault the opponent if you can kill him
|
||||||
GameEntity entity = ai.getMustAttackEntityThisTurn();
|
if (bAssault) {
|
||||||
if (nextTurn || entity == null) {
|
return prefDefender;
|
||||||
// ...or during the attacking creature controller's turn
|
|
||||||
entity = ai.getMustAttackEntity();
|
|
||||||
}
|
}
|
||||||
if (null != entity) {
|
// 2. attack planeswalkers
|
||||||
int n = defs.indexOf(entity);
|
List<Card> pwDefending = c.getDefendingPlaneswalkers();
|
||||||
if (-1 == n) {
|
if (!pwDefending.isEmpty()) {
|
||||||
System.out.println("getMustAttackEntity() or getMustAttackEntityThisTurn() returned something not in defenders.");
|
final Card pwNearUlti = ComputerUtilCard.getBestPlaneswalkerToDamage(pwDefending);
|
||||||
return prefDefender;
|
return pwNearUlti != null ? pwNearUlti : ComputerUtilCard.getBestPlaneswalkerAI(pwDefending);
|
||||||
}
|
|
||||||
return entity;
|
|
||||||
} else {
|
|
||||||
// 1. assault the opponent if you can kill him
|
|
||||||
if (bAssault) {
|
|
||||||
return prefDefender;
|
|
||||||
}
|
|
||||||
// 2. attack planeswalkers
|
|
||||||
List<Card> pwDefending = c.getDefendingPlaneswalkers();
|
|
||||||
if (!pwDefending.isEmpty()) {
|
|
||||||
final Card pwNearUlti = ComputerUtilCard.getBestPlaneswalkerToDamage(pwDefending);
|
|
||||||
return pwNearUlti != null ? pwNearUlti : ComputerUtilCard.getBestPlaneswalkerAI(pwDefending);
|
|
||||||
} else {
|
|
||||||
return prefDefender;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return prefDefender;
|
||||||
}
|
}
|
||||||
|
|
||||||
final boolean LOG_AI_ATTACKS = false;
|
final boolean LOG_AI_ATTACKS = false;
|
||||||
@@ -786,30 +774,41 @@ public class AiAttackController {
|
|||||||
// because creatures not chosen can't attack.
|
// because creatures not chosen can't attack.
|
||||||
if (!nextTurn) {
|
if (!nextTurn) {
|
||||||
for (final Card attacker : this.attackers) {
|
for (final Card attacker : this.attackers) {
|
||||||
boolean mustAttack = false;
|
GameEntity mustAttackDef = null;
|
||||||
// TODO this might result into trying to attack the wrong player
|
|
||||||
if (attacker.isGoaded()) {
|
if (attacker.isGoaded()) {
|
||||||
mustAttack = true;
|
// TODO this might result into trying to attack the wrong player
|
||||||
|
mustAttackDef = defender;
|
||||||
} else if (attacker.getSVar("MustAttack").equals("True")) {
|
} else if (attacker.getSVar("MustAttack").equals("True")) {
|
||||||
mustAttack = true;
|
mustAttackDef = defender;
|
||||||
} else if (attacker.hasSVar("EndOfTurnLeavePlay")
|
} else if (attacker.hasSVar("EndOfTurnLeavePlay")
|
||||||
&& isEffectiveAttacker(ai, attacker, combat, defender)) {
|
&& isEffectiveAttacker(ai, attacker, combat, defender)) {
|
||||||
mustAttack = true;
|
mustAttackDef = defender;
|
||||||
} else if (seasonOfTheWitch) {
|
} else if (seasonOfTheWitch) {
|
||||||
//TODO: if there are other ways to tap this creature (like mana creature), then don't need to attack
|
//TODO: if there are other ways to tap this creature (like mana creature), then don't need to attack
|
||||||
mustAttack = true;
|
mustAttackDef = defender;
|
||||||
} else {
|
} else {
|
||||||
final List<GameEntity> e = StaticAbilityMustAttack.entitiesMustAttack(attacker);
|
final List<GameEntity> attackRequirements = StaticAbilityMustAttack.entitiesMustAttack(attacker);
|
||||||
if (!e.isEmpty()) {
|
if (attackRequirements.contains(attacker)) {
|
||||||
mustAttack = true;
|
// TODO add cost check here and switch defender if there's one without a cost
|
||||||
// TODO switch defender if there's one without a cost or it's not the specific player
|
// must attack anything
|
||||||
} else if (attacker.getController().getMustAttackEntityThisTurn() != null &&
|
mustAttackDef = defender;
|
||||||
CombatUtil.getAttackCost(ai.getGame(), attacker, defender) == null) {
|
// next check if there's also a specific defender to attack, so don't count them
|
||||||
mustAttack = true;
|
attackRequirements.removeAll(new CardCollection(attacker));
|
||||||
|
}
|
||||||
|
final MapToAmount<GameEntity> amounts = new LinkedHashMapToAmount<>();
|
||||||
|
amounts.addAll(attackRequirements);
|
||||||
|
while (!amounts.isEmpty()) {
|
||||||
|
// check defenders in order of maximum requirements
|
||||||
|
GameEntity mustAttackDefMaybe = MapToAmountUtil.max(amounts).getKey();
|
||||||
|
if (canAttackWrapper(attacker, mustAttackDefMaybe) && CombatUtil.getAttackCost(ai.getGame(), attacker, mustAttackDefMaybe) == null) {
|
||||||
|
mustAttackDef = mustAttackDefMaybe;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
amounts.remove(mustAttackDefMaybe);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mustAttack) {
|
if (mustAttackDef != null) {
|
||||||
combat.addAttacker(attacker, defender);
|
combat.addAttacker(attacker, mustAttackDef);
|
||||||
attackersLeft.remove(attacker);
|
attackersLeft.remove(attacker);
|
||||||
numForcedAttackers++;
|
numForcedAttackers++;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -114,12 +114,11 @@ public class ComputerUtilCombat {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
final List<GameEntity> mustAttackEnts = StaticAbilityMustAttack.entitiesMustAttack(attacker);
|
final List<GameEntity> mustAttack = StaticAbilityMustAttack.entitiesMustAttack(attacker);
|
||||||
//if it contains only attacker, it only has a non-specific must attack
|
//if it contains only attacker, it only has a non-specific must attack
|
||||||
if (mustAttackEnts.size() > 1 || (mustAttackEnts.size() == 1 && mustAttackEnts.get(0) != attacker)) {
|
mustAttack.removeAll(new CardCollection(attacker));
|
||||||
if (!mustAttackEnts.contains(defender)) {
|
if (!mustAttack.isEmpty() && !mustAttack.contains(defender)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO this should be a factor but needs some alignment with AttachAi
|
// TODO this should be a factor but needs some alignment with AttachAi
|
||||||
|
|||||||
@@ -111,7 +111,6 @@ public enum SpellApiToAi {
|
|||||||
.put(ApiType.MoveCounter, CountersMoveAi.class)
|
.put(ApiType.MoveCounter, CountersMoveAi.class)
|
||||||
.put(ApiType.MultiplePiles, CannotPlayAi.class)
|
.put(ApiType.MultiplePiles, CannotPlayAi.class)
|
||||||
.put(ApiType.MultiplyCounter, CountersMultiplyAi.class)
|
.put(ApiType.MultiplyCounter, CountersMultiplyAi.class)
|
||||||
.put(ApiType.MustAttack, MustAttackAi.class)
|
|
||||||
.put(ApiType.MustBlock, MustBlockAi.class)
|
.put(ApiType.MustBlock, MustBlockAi.class)
|
||||||
.put(ApiType.Mutate, MutateAi.class)
|
.put(ApiType.Mutate, MutateAi.class)
|
||||||
.put(ApiType.NameCard, ChooseCardNameAi.class)
|
.put(ApiType.NameCard, ChooseCardNameAi.class)
|
||||||
|
|||||||
@@ -1635,8 +1635,6 @@ public class AttachAi extends SpellAbilityAi {
|
|||||||
if (keyword.endsWith("CARDNAME can't attack.") || keyword.equals("Defender")
|
if (keyword.endsWith("CARDNAME can't attack.") || keyword.equals("Defender")
|
||||||
|| keyword.endsWith("CARDNAME can't attack or block.")) {
|
|| keyword.endsWith("CARDNAME can't attack or block.")) {
|
||||||
return card.getNetCombatDamage() >= 1 && ComputerUtilCombat.canAttackNextTurn(card);
|
return card.getNetCombatDamage() >= 1 && ComputerUtilCombat.canAttackNextTurn(card);
|
||||||
} else if (keyword.endsWith("CARDNAME attacks each turn if able.") || keyword.endsWith("CARDNAME attacks each combat if able.")) {
|
|
||||||
return !ai.getCreaturesInPlay().isEmpty() && ComputerUtilCombat.canAttackNextTurn(card) && CombatUtil.canBlock(card, true);
|
|
||||||
} else if (keyword.endsWith("CARDNAME can't block.")) {
|
} else if (keyword.endsWith("CARDNAME can't block.")) {
|
||||||
return CombatUtil.canBlock(card, true);
|
return CombatUtil.canBlock(card, true);
|
||||||
} else if (keyword.endsWith("CARDNAME's activated abilities can't be activated.")) {
|
} else if (keyword.endsWith("CARDNAME's activated abilities can't be activated.")) {
|
||||||
|
|||||||
@@ -1,35 +0,0 @@
|
|||||||
package forge.ai.ability;
|
|
||||||
|
|
||||||
|
|
||||||
import forge.ai.SpellAbilityAi;
|
|
||||||
import forge.game.player.Player;
|
|
||||||
import forge.game.spellability.SpellAbility;
|
|
||||||
|
|
||||||
public class MustAttackAi extends SpellAbilityAi {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean canPlayAI(Player aiPlayer, SpellAbility sa) {
|
|
||||||
// disabled for the AI for now. Only for Gideon Jura at this time.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean chkAIDrawback(SpellAbility sa, Player aiPlayer) {
|
|
||||||
// AI should only activate this during Human's turn
|
|
||||||
// TODO - implement AI
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see forge.card.abilityfactory.SpellAiLogic#doTriggerAINoCost(forge.game.player.Player, java.util.Map, forge.card.spellability.SpellAbility, boolean)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected boolean doTriggerAINoCost(Player aiPlayer, SpellAbility sa, boolean mandatory) {
|
|
||||||
boolean chance;
|
|
||||||
|
|
||||||
// TODO - implement AI
|
|
||||||
chance = false;
|
|
||||||
|
|
||||||
return chance;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -166,10 +166,6 @@ public abstract class PumpAiBase extends SpellAbilityAi {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return ph.isPlayerTurn(ai) || (combat != null && combat.isAttacking(card) && card.getNetCombatDamage() > 0);
|
return ph.isPlayerTurn(ai) || (combat != null && combat.isAttacking(card) && card.getNetCombatDamage() > 0);
|
||||||
} else if (keyword.endsWith("CARDNAME attacks each turn if able.")
|
|
||||||
|| keyword.endsWith("CARDNAME attacks each combat if able.")) {
|
|
||||||
return !ph.isPlayerTurn(ai) && CombatUtil.canAttack(card, ai) && CombatUtil.canBeBlocked(card, ai)
|
|
||||||
&& !ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS);
|
|
||||||
} else if (keyword.endsWith("CARDNAME can't be regenerated.")) {
|
} else if (keyword.endsWith("CARDNAME can't be regenerated.")) {
|
||||||
if (card.getShieldCount() > 0) {
|
if (card.getShieldCount() > 0) {
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -575,7 +575,6 @@ public class GameAction {
|
|||||||
copied.setTapped(false); //untap card after it leaves the battlefield if needed
|
copied.setTapped(false); //untap card after it leaves the battlefield if needed
|
||||||
game.fireEvent(new GameEventCardTapped(c, false));
|
game.fireEvent(new GameEventCardTapped(c, false));
|
||||||
}
|
}
|
||||||
copied.setMustAttackEntity(null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Need to apply any static effects to produce correct triggers
|
// Need to apply any static effects to produce correct triggers
|
||||||
|
|||||||
@@ -112,7 +112,6 @@ public enum ApiType {
|
|||||||
MoveCounter (CountersMoveEffect.class),
|
MoveCounter (CountersMoveEffect.class),
|
||||||
MultiplePiles (MultiplePilesEffect.class),
|
MultiplePiles (MultiplePilesEffect.class),
|
||||||
MultiplyCounter (CountersMultiplyEffect.class),
|
MultiplyCounter (CountersMultiplyEffect.class),
|
||||||
MustAttack (MustAttackEffect.class),
|
|
||||||
MustBlock (MustBlockEffect.class),
|
MustBlock (MustBlockEffect.class),
|
||||||
Mutate (MutateEffect.class),
|
Mutate (MutateEffect.class),
|
||||||
NameCard (ChooseCardNameEffect.class),
|
NameCard (ChooseCardNameEffect.class),
|
||||||
|
|||||||
@@ -1,91 +0,0 @@
|
|||||||
package forge.game.ability.effects;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import forge.game.GameEntity;
|
|
||||||
import forge.game.ability.AbilityUtils;
|
|
||||||
import forge.game.ability.SpellAbilityEffect;
|
|
||||||
import forge.game.card.Card;
|
|
||||||
import forge.game.card.CardCollection;
|
|
||||||
import forge.game.player.Player;
|
|
||||||
import forge.game.player.PlayerCollection;
|
|
||||||
import forge.game.spellability.SpellAbility;
|
|
||||||
import forge.game.spellability.TargetRestrictions;
|
|
||||||
|
|
||||||
public class MustAttackEffect extends SpellAbilityEffect {
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see forge.card.abilityfactory.SpellEffect#getStackDescription(java.util.Map, forge.card.spellability.SpellAbility)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected String getStackDescription(SpellAbility sa) {
|
|
||||||
final Card host = sa.getHostCard();
|
|
||||||
final StringBuilder sb = new StringBuilder();
|
|
||||||
|
|
||||||
// end standard pre-
|
|
||||||
|
|
||||||
final List<Player> tgtPlayers = getTargetPlayers(sa);
|
|
||||||
|
|
||||||
String defender = null;
|
|
||||||
if (sa.getParam("Defender").equals("Self")) {
|
|
||||||
defender = host.toString();
|
|
||||||
} else {
|
|
||||||
defender = host.getController().toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (final Player player : tgtPlayers) {
|
|
||||||
sb.append("Creatures ").append(player).append(" controls attack ");
|
|
||||||
sb.append(defender).append(" during their next turn.");
|
|
||||||
}
|
|
||||||
for (final Card c : getTargetCards(sa)) {
|
|
||||||
sb.append(c).append(" must attack ");
|
|
||||||
sb.append(defender).append(" during its controller's next turn if able.");
|
|
||||||
}
|
|
||||||
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void resolve(SpellAbility sa) {
|
|
||||||
final List<Player> tgtPlayers = getTargetPlayers(sa);
|
|
||||||
final TargetRestrictions tgt = sa.getTargetRestrictions();
|
|
||||||
final String defender = sa.getParam("Defender");
|
|
||||||
final boolean thisTurn = sa.hasParam("ThisTurn");
|
|
||||||
GameEntity entity = null;
|
|
||||||
if (defender.equals("Self")) {
|
|
||||||
entity = sa.getHostCard();
|
|
||||||
} else {
|
|
||||||
PlayerCollection defPlayers = AbilityUtils.getDefinedPlayers(sa.getHostCard(), defender, sa);
|
|
||||||
CardCollection defPWs = AbilityUtils.getDefinedCards(sa.getHostCard(), defender, sa);
|
|
||||||
if ((defPlayers.isEmpty() && defPWs.isEmpty()) || defPlayers.size() > 1 || defPWs.size() > 1) {
|
|
||||||
throw new RuntimeException("Illegal (nonexistent or not uniquely defined) defender " + defender + " for MustAttackEffect in card " + sa.getHostCard());
|
|
||||||
}
|
|
||||||
if (!defPlayers.isEmpty()) {
|
|
||||||
entity = defPlayers.getFirst();
|
|
||||||
} else if (!defPWs.isEmpty()) {
|
|
||||||
entity = defPWs.getFirst();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO these should not override but add another requirement
|
|
||||||
for (final Player p : tgtPlayers) {
|
|
||||||
if ((tgt == null) || p.canBeTargetedBy(sa)) {
|
|
||||||
if (thisTurn || !p.getGame().getPhaseHandler().isPlayerTurn(p)) {
|
|
||||||
p.setMustAttackEntityThisTurn(entity);
|
|
||||||
} else {
|
|
||||||
p.setMustAttackEntity(entity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (final Card c : getTargetCards(sa)) {
|
|
||||||
if ((tgt == null) || c.canBeTargetedBy(sa)) {
|
|
||||||
if (thisTurn) {
|
|
||||||
c.setMustAttackEntityThisTurn(entity);
|
|
||||||
} else {
|
|
||||||
c.setMustAttackEntity(entity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // mustAttackResolve()
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -72,7 +72,6 @@ public class RestartGameEffect extends SpellAbilityEffect {
|
|||||||
p.resetCompletedDungeons();
|
p.resetCompletedDungeons();
|
||||||
p.setBlessing(false);
|
p.setBlessing(false);
|
||||||
p.clearController();
|
p.clearController();
|
||||||
p.setMustAttackEntity(null);
|
|
||||||
|
|
||||||
CardCollection newLibrary = new CardCollection(p.getCardsIn(restartZones, false));
|
CardCollection newLibrary = new CardCollection(p.getCardsIn(restartZones, false));
|
||||||
List<Card> filteredCards = null;
|
List<Card> filteredCards = null;
|
||||||
|
|||||||
@@ -126,9 +126,6 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
|||||||
|
|
||||||
private GameEntity entityAttachedTo;
|
private GameEntity entityAttachedTo;
|
||||||
|
|
||||||
private GameEntity mustAttackEntity;
|
|
||||||
private GameEntity mustAttackEntityThisTurn;
|
|
||||||
|
|
||||||
private final Map<StaticAbility, CardPlayOption> mayPlay = Maps.newHashMap();
|
private final Map<StaticAbility, CardPlayOption> mayPlay = Maps.newHashMap();
|
||||||
|
|
||||||
// changes by AF animate and continuous static effects
|
// changes by AF animate and continuous static effects
|
||||||
@@ -1337,21 +1334,6 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
|||||||
view.updateMustBlockCards(this);
|
view.updateMustBlockCards(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void setMustAttackEntity(final GameEntity e) {
|
|
||||||
mustAttackEntity = e;
|
|
||||||
}
|
|
||||||
public final GameEntity getMustAttackEntity() {
|
|
||||||
return mustAttackEntity;
|
|
||||||
}
|
|
||||||
public final void clearMustAttackEntity(final Player playerturn) {
|
|
||||||
if (getController().equals(playerturn)) {
|
|
||||||
mustAttackEntity = null;
|
|
||||||
}
|
|
||||||
mustAttackEntityThisTurn = mustAttackEntity;
|
|
||||||
}
|
|
||||||
public final GameEntity getMustAttackEntityThisTurn() { return mustAttackEntityThisTurn; }
|
|
||||||
public final void setMustAttackEntityThisTurn(GameEntity entThisTurn) { mustAttackEntityThisTurn = entThisTurn; }
|
|
||||||
|
|
||||||
public final Card getCloneOrigin() {
|
public final Card getCloneOrigin() {
|
||||||
return cloneOrigin;
|
return cloneOrigin;
|
||||||
}
|
}
|
||||||
@@ -6196,7 +6178,6 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
|||||||
setRegeneratedThisTurn(0);
|
setRegeneratedThisTurn(0);
|
||||||
resetShield();
|
resetShield();
|
||||||
setBecameTargetThisTurn(false);
|
setBecameTargetThisTurn(false);
|
||||||
clearMustAttackEntity(turn);
|
|
||||||
clearMustBlockCards();
|
clearMustBlockCards();
|
||||||
getDamageHistory().newTurn();
|
getDamageHistory().newTurn();
|
||||||
getDamageHistory().setCreatureAttackedLastTurnOf(turn, getDamageHistory().getCreatureAttackedThisTurn());
|
getDamageHistory().setCreatureAttackedLastTurnOf(turn, getDamageHistory().getCreatureAttackedThisTurn());
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package forge.game.combat;
|
package forge.game.combat;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -37,12 +38,6 @@ public class AttackRequirement {
|
|||||||
|
|
||||||
this.causesToAttack = causesToAttack;
|
this.causesToAttack = causesToAttack;
|
||||||
|
|
||||||
final GameEntity mustAttackThisTurn = attacker.getController().getMustAttackEntityThisTurn();
|
|
||||||
// TODO check if this always illegal (e.g. Taunt cast on self)
|
|
||||||
if (mustAttackThisTurn != null) {
|
|
||||||
defenderSpecific.add(mustAttackThisTurn);
|
|
||||||
}
|
|
||||||
|
|
||||||
int nAttackAnything = 0;
|
int nAttackAnything = 0;
|
||||||
|
|
||||||
if (attacker.isGoaded()) {
|
if (attacker.isGoaded()) {
|
||||||
@@ -51,18 +46,11 @@ public class AttackRequirement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//MustAttack static check
|
//MustAttack static check
|
||||||
final List<GameEntity> e = StaticAbilityMustAttack.entitiesMustAttack(attacker);
|
final List<GameEntity> mustAttack = StaticAbilityMustAttack.entitiesMustAttack(attacker);
|
||||||
if (e.contains(attacker)) {
|
nAttackAnything += Collections.frequency(mustAttack, attacker);
|
||||||
nAttackAnything++;
|
for (GameEntity e : mustAttack) {
|
||||||
} else if (!e.isEmpty()) {
|
if (e.equals(attacker)) continue;
|
||||||
for (GameEntity mustAtt : e) {
|
defenderSpecific.add(e);
|
||||||
defenderSpecific.add(mustAtt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final GameEntity mustAttackThisTurn3 = attacker.getMustAttackEntityThisTurn();
|
|
||||||
if (mustAttackThisTurn3 != null) {
|
|
||||||
defenderSpecific.add(mustAttackThisTurn3);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final Game game = attacker.getGame();
|
final Game game = attacker.getGame();
|
||||||
|
|||||||
@@ -844,9 +844,6 @@ public class PhaseHandler implements java.io.Serializable {
|
|||||||
|
|
||||||
private Player handleNextTurn() {
|
private Player handleNextTurn() {
|
||||||
game.getStack().onNextTurn();
|
game.getStack().onNextTurn();
|
||||||
// reset mustAttackEntity
|
|
||||||
playerTurn.setMustAttackEntityThisTurn(playerTurn.getMustAttackEntity());
|
|
||||||
playerTurn.setMustAttackEntity(null);
|
|
||||||
|
|
||||||
game.getTriggerHandler().clearThisTurnDelayedTrigger();
|
game.getTriggerHandler().clearThisTurnDelayedTrigger();
|
||||||
game.getTriggerHandler().resetTurnTriggerState();
|
game.getTriggerHandler().resetTurnTriggerState();
|
||||||
|
|||||||
@@ -203,8 +203,6 @@ public class Player extends GameEntity implements Comparable<Player> {
|
|||||||
|
|
||||||
private Table<Long, Long, KeywordsChange> changedKeywords = TreeBasedTable.create();
|
private Table<Long, Long, KeywordsChange> changedKeywords = TreeBasedTable.create();
|
||||||
private ManaPool manaPool = new ManaPool(this);
|
private ManaPool manaPool = new ManaPool(this);
|
||||||
private GameEntity mustAttackEntity;
|
|
||||||
private GameEntity mustAttackEntityThisTurn;
|
|
||||||
private List<Card> creatureAttackedThisTurn = new ArrayList<>();
|
private List<Card> creatureAttackedThisTurn = new ArrayList<>();
|
||||||
private boolean activateLoyaltyAbilityThisTurn = false;
|
private boolean activateLoyaltyAbilityThisTurn = false;
|
||||||
private boolean tappedLandForManaThisTurn = false;
|
private boolean tappedLandForManaThisTurn = false;
|
||||||
@@ -2296,22 +2294,6 @@ public class Player extends GameEntity implements Comparable<Player> {
|
|||||||
lifeLostLastTurn = n;
|
lifeLostLastTurn = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* get the Player object or Card (Planeswalker) object that this Player must
|
|
||||||
* attack this combat.
|
|
||||||
*
|
|
||||||
* @return the Player or Card (Planeswalker)
|
|
||||||
* @since 1.1.01
|
|
||||||
*/
|
|
||||||
public final GameEntity getMustAttackEntity() {
|
|
||||||
return mustAttackEntity;
|
|
||||||
}
|
|
||||||
public final void setMustAttackEntity(final GameEntity o) {
|
|
||||||
mustAttackEntity = o;
|
|
||||||
}
|
|
||||||
public final GameEntity getMustAttackEntityThisTurn() { return mustAttackEntityThisTurn; }
|
|
||||||
public final void setMustAttackEntityThisTurn(GameEntity entThisTurn) { mustAttackEntityThisTurn = entThisTurn; }
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compareTo(Player o) {
|
public int compareTo(Player o) {
|
||||||
if (o == null) {
|
if (o == null) {
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
All creatures able to block CARDNAME do so.
|
All creatures able to block CARDNAME do so.
|
||||||
Banding
|
Banding
|
||||||
CARDNAME's activated abilities can't be activated.
|
CARDNAME's activated abilities can't be activated.
|
||||||
CARDNAME attacks each combat if able.
|
|
||||||
CARDNAME blocks each combat if able.
|
CARDNAME blocks each combat if able.
|
||||||
CARDNAME can attack as though it didn't have defender.
|
CARDNAME can attack as though it didn't have defender.
|
||||||
CARDNAME can block any number of creatures.
|
CARDNAME can block any number of creatures.
|
||||||
|
|||||||
Reference in New Issue
Block a user