mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-11 16:26:22 +00:00
GameAction: first state based action for Battle
This commit is contained in:
@@ -1282,8 +1282,7 @@ public class GameAction {
|
||||
if (zt == ZoneType.Battlefield) {
|
||||
continue;
|
||||
}
|
||||
final Iterable<Card> cards = p.getCardsIn(zt).threadSafeIterable();
|
||||
for (final Card c : cards) {
|
||||
for (final Card c : p.getCardsIn(zt).threadSafeIterable()) {
|
||||
checkAgain |= stateBasedAction704_5d(c);
|
||||
// Dungeon Card won't affect other cards, so don't need to set checkAgain
|
||||
stateBasedAction_Dungeon(c);
|
||||
@@ -1296,6 +1295,7 @@ public class GameAction {
|
||||
CardCollection sacrificeList = new CardCollection();
|
||||
PlayerCollection spaceSculptors = new PlayerCollection();
|
||||
for (final Card c : game.getCardsIn(ZoneType.Battlefield)) {
|
||||
boolean checkAgainCard = false;
|
||||
if (c.hasKeyword(Keyword.SPACE_SCULPTOR)) {
|
||||
spaceSculptors.add(c.getController());
|
||||
}
|
||||
@@ -1303,7 +1303,7 @@ public class GameAction {
|
||||
// Rule 704.5f - Put into grave (no regeneration) for toughness <= 0
|
||||
if (c.getNetToughness() <= 0) {
|
||||
noRegCreats.add(c);
|
||||
checkAgain = true;
|
||||
checkAgainCard = true;
|
||||
} else if (c.hasKeyword("CARDNAME can't be destroyed by lethal damage unless lethal damage dealt by a single source is marked on it.")) {
|
||||
if (c.getLethal() <= c.getMaxDamageFromSource() || c.hasBeenDealtDeathtouchDamage()) {
|
||||
if (desCreats == null) {
|
||||
@@ -1311,7 +1311,7 @@ public class GameAction {
|
||||
}
|
||||
desCreats.add(c);
|
||||
c.setHasBeenDealtDeathtouchDamage(false);
|
||||
checkAgain = true;
|
||||
checkAgainCard = true;
|
||||
}
|
||||
}
|
||||
// Rule 704.5g - Destroy due to lethal damage
|
||||
@@ -1322,20 +1322,21 @@ public class GameAction {
|
||||
}
|
||||
desCreats.add(c);
|
||||
c.setHasBeenDealtDeathtouchDamage(false);
|
||||
checkAgain = true;
|
||||
checkAgainCard = true;
|
||||
}
|
||||
}
|
||||
|
||||
checkAgain |= stateBasedAction_Saga(c, sacrificeList);
|
||||
checkAgain |= stateBasedAction704_attach(c, unAttachList); // Attachment
|
||||
checkAgainCard |= stateBasedAction_Saga(c, sacrificeList);
|
||||
checkAgainCard |= stateBasedAction_Battle(c, noRegCreats);
|
||||
checkAgainCard |= stateBasedAction704_attach(c, unAttachList); // Attachment
|
||||
|
||||
checkAgain |= stateBasedAction704_5r(c); // annihilate +1/+1 counters with -1/-1 ones
|
||||
checkAgainCard |= stateBasedAction704_5r(c); // annihilate +1/+1 counters with -1/-1 ones
|
||||
|
||||
final CounterType dreamType = CounterType.get(CounterEnumType.DREAM);
|
||||
|
||||
if (c.getCounters(dreamType) > 7 && c.hasKeyword("CARDNAME can't have more than seven dream counters on it.")) {
|
||||
c.subtractCounter(dreamType, c.getCounters(dreamType) - 7);
|
||||
checkAgain = true;
|
||||
checkAgainCard = true;
|
||||
}
|
||||
|
||||
if (c.hasKeyword("The number of loyalty counters on CARDNAME is equal to the number of Beebles you control.")) {
|
||||
@@ -1350,17 +1351,18 @@ public class GameAction {
|
||||
}
|
||||
// Only check again if counters actually changed
|
||||
if (c.getCounters(CounterEnumType.LOYALTY) != loyal) {
|
||||
checkAgain = true;
|
||||
checkAgainCard = true;
|
||||
}
|
||||
}
|
||||
|
||||
// cleanup aura
|
||||
if (c.isAura() && c.isInPlay() && !c.isEnchanting()) {
|
||||
noRegCreats.add(c);
|
||||
checkAgain = true;
|
||||
checkAgainCard = true;
|
||||
}
|
||||
if (checkAgain) {
|
||||
if (checkAgainCard) {
|
||||
cardsToUpdateLKI.add(c);
|
||||
checkAgain = true;
|
||||
}
|
||||
}
|
||||
for (Card u : unAttachList) {
|
||||
@@ -1503,6 +1505,23 @@ public class GameAction {
|
||||
return checkAgain;
|
||||
}
|
||||
|
||||
private boolean stateBasedAction_Battle(Card c, CardCollection removeList) {
|
||||
boolean checkAgain = false;
|
||||
if (!c.getType().isBattle()) {
|
||||
return false;
|
||||
}
|
||||
if (c.getCounters(CounterEnumType.DEFENSE) > 0) {
|
||||
return false;
|
||||
}
|
||||
// 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.
|
||||
if (!game.getStack().hasSourceOnStack(c, SpellAbilityPredicates.isTrigger())) {
|
||||
removeList.add(c);
|
||||
checkAgain = true;
|
||||
}
|
||||
return checkAgain;
|
||||
}
|
||||
|
||||
private void stateBasedAction_Dungeon(Card c) {
|
||||
if (!c.getType().isDungeon() || !c.isInLastRoom()) {
|
||||
return;
|
||||
@@ -1531,7 +1550,7 @@ public class GameAction {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (c.isCreature() && c.isAttachedToEntity()) { // Rule 704.5q - Creature attached to an object or player, becomes unattached
|
||||
if ((c.isCreature() || c.isBattle()) && c.isAttachedToEntity()) { // Rule 704.5q - Creature attached to an object or player, becomes unattached
|
||||
unAttachList.add(c);
|
||||
checkAgain = true;
|
||||
}
|
||||
|
||||
@@ -63,6 +63,15 @@ public final class SpellAbilityPredicates extends CardTraitPredicates {
|
||||
};
|
||||
}
|
||||
|
||||
public static final Predicate<SpellAbility> isTrigger() {
|
||||
return new Predicate<SpellAbility>() {
|
||||
@Override
|
||||
public boolean apply(final SpellAbility sa) {
|
||||
return sa.isTrigger();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static final Predicate<SpellAbility> isValid(String[] restrictions, Player sourceController, Card source, CardTraitBase spellAbility) {
|
||||
return new Predicate<SpellAbility>() {
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user