mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-15 18:28:00 +00:00
Merge pull request #138 from Northmoc/snc_ab_ql
Arcane Bombardment - quality of life
This commit is contained in:
@@ -823,6 +823,7 @@ public abstract class GameState {
|
|||||||
String id = rememberedEnts.getValue();
|
String id = rememberedEnts.getValue();
|
||||||
|
|
||||||
Card exiledWith = idToCard.get(Integer.parseInt(id));
|
Card exiledWith = idToCard.get(Integer.parseInt(id));
|
||||||
|
exiledWith.addExiledCard(c);
|
||||||
c.setExiledWith(exiledWith);
|
c.setExiledWith(exiledWith);
|
||||||
c.setExiledBy(exiledWith.getController());
|
c.setExiledBy(exiledWith.getController());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -192,6 +192,7 @@ public class ChangeZoneAllEffect extends SpellAbilityEffect {
|
|||||||
if (host == null) {
|
if (host == null) {
|
||||||
host = sa.getHostCard();
|
host = sa.getHostCard();
|
||||||
}
|
}
|
||||||
|
host.addExiledCard(movedCard);
|
||||||
movedCard.setExiledWith(host);
|
movedCard.setExiledWith(host);
|
||||||
movedCard.setExiledBy(host.getController());
|
movedCard.setExiledBy(host.getController());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -719,6 +719,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
|||||||
if (host == null) {
|
if (host == null) {
|
||||||
host = sa.getHostCard();
|
host = sa.getHostCard();
|
||||||
}
|
}
|
||||||
|
host.addExiledCard(gameCard);
|
||||||
gameCard.setExiledWith(host);
|
gameCard.setExiledWith(host);
|
||||||
gameCard.setExiledBy(host.getController());
|
gameCard.setExiledBy(host.getController());
|
||||||
}
|
}
|
||||||
@@ -745,6 +746,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
|||||||
if (destination.equals(ZoneType.Exile) && !movedCard.isToken()) {
|
if (destination.equals(ZoneType.Exile) && !movedCard.isToken()) {
|
||||||
movedCard.setExiledWith(host);
|
movedCard.setExiledWith(host);
|
||||||
if (host != null) {
|
if (host != null) {
|
||||||
|
host.addExiledCard(movedCard);
|
||||||
movedCard.setExiledBy(host.getController());
|
movedCard.setExiledBy(host.getController());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1350,6 +1352,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
|||||||
if (host == null) {
|
if (host == null) {
|
||||||
host = sa.getHostCard();
|
host = sa.getHostCard();
|
||||||
}
|
}
|
||||||
|
host.addExiledCard(movedCard);
|
||||||
movedCard.setExiledWith(host);
|
movedCard.setExiledWith(host);
|
||||||
movedCard.setExiledBy(host.getController());
|
movedCard.setExiledBy(host.getController());
|
||||||
}
|
}
|
||||||
@@ -1541,6 +1544,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
|||||||
host = srcSA.getHostCard();
|
host = srcSA.getHostCard();
|
||||||
}
|
}
|
||||||
movedCard = game.getAction().exile(tgtHost, srcSA, params);
|
movedCard = game.getAction().exile(tgtHost, srcSA, params);
|
||||||
|
host.addExiledCard(movedCard);
|
||||||
movedCard.setExiledWith(host);
|
movedCard.setExiledWith(host);
|
||||||
movedCard.setExiledBy(host.getController());
|
movedCard.setExiledBy(host.getController());
|
||||||
} else if (srcSA.getParam("Destination").equals("TopOfLibrary")) {
|
} else if (srcSA.getParam("Destination").equals("TopOfLibrary")) {
|
||||||
|
|||||||
@@ -420,6 +420,7 @@ public class DigEffect extends SpellAbilityEffect {
|
|||||||
if (sa.hasParam("ExileWithCounter")) {
|
if (sa.hasParam("ExileWithCounter")) {
|
||||||
c.addCounter(CounterType.getType(sa.getParam("ExileWithCounter")), 1, player, counterTable);
|
c.addCounter(CounterType.getType(sa.getParam("ExileWithCounter")), 1, player, counterTable);
|
||||||
}
|
}
|
||||||
|
effectHost.addExiledCard(c);
|
||||||
c.setExiledWith(effectHost);
|
c.setExiledWith(effectHost);
|
||||||
c.setExiledBy(effectHost.getController());
|
c.setExiledBy(effectHost.getController());
|
||||||
}
|
}
|
||||||
@@ -492,6 +493,7 @@ public class DigEffect extends SpellAbilityEffect {
|
|||||||
if (sa.hasParam("ExileWithCounter")) {
|
if (sa.hasParam("ExileWithCounter")) {
|
||||||
c.addCounter(CounterType.getType(sa.getParam("ExileWithCounter")), 1, player, counterTable);
|
c.addCounter(CounterType.getType(sa.getParam("ExileWithCounter")), 1, player, counterTable);
|
||||||
}
|
}
|
||||||
|
effectHost.addExiledCard(c);
|
||||||
c.setExiledWith(effectHost);
|
c.setExiledWith(effectHost);
|
||||||
c.setExiledBy(effectHost.getController());
|
c.setExiledBy(effectHost.getController());
|
||||||
if (remZone2) {
|
if (remZone2) {
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ public class MillEffect extends SpellAbilityEffect {
|
|||||||
host = sa.getHostCard();
|
host = sa.getHostCard();
|
||||||
}
|
}
|
||||||
for (final Card c : milled) {
|
for (final Card c : milled) {
|
||||||
|
host.addExiledCard(c);
|
||||||
c.setExiledWith(host);
|
c.setExiledWith(host);
|
||||||
if (facedown) {
|
if (facedown) {
|
||||||
c.turnFaceDown(true);
|
c.turnFaceDown(true);
|
||||||
|
|||||||
@@ -109,7 +109,8 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
|||||||
private final Table<Long, Long, List<String>> hiddenExtrinsicKeywords = TreeBasedTable.create();
|
private final Table<Long, Long, List<String>> hiddenExtrinsicKeywords = TreeBasedTable.create();
|
||||||
|
|
||||||
// cards attached or otherwise linked to this card
|
// cards attached or otherwise linked to this card
|
||||||
private CardCollection hauntedBy, devouredCards, exploitedCards, delvedCards, convokedCards, imprintedCards, encodedCards;
|
private CardCollection hauntedBy, devouredCards, exploitedCards, delvedCards, convokedCards, imprintedCards,
|
||||||
|
exiledCards, encodedCards;
|
||||||
private CardCollection gainControlTargets, chosenCards;
|
private CardCollection gainControlTargets, chosenCards;
|
||||||
private CardCollection mergedCards;
|
private CardCollection mergedCards;
|
||||||
private Map<Long, CardCollection> mustBlockCards = Maps.newHashMap();
|
private Map<Long, CardCollection> mustBlockCards = Maps.newHashMap();
|
||||||
@@ -1079,6 +1080,31 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
|||||||
imprintedCards = view.clearCards(imprintedCards, TrackableProperty.ImprintedCards);
|
imprintedCards = view.clearCards(imprintedCards, TrackableProperty.ImprintedCards);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final CardCollectionView getExiledCards() {
|
||||||
|
return CardCollection.getView(exiledCards);
|
||||||
|
}
|
||||||
|
public final boolean hasExiledCard() {
|
||||||
|
return FCollection.hasElements(exiledCards);
|
||||||
|
}
|
||||||
|
public final boolean hasExiledCard(Card c) {
|
||||||
|
return FCollection.hasElement(exiledCards, c);
|
||||||
|
}
|
||||||
|
public final void addExiledCard(final Card c) {
|
||||||
|
exiledCards = view.addCard(exiledCards, c, TrackableProperty.ExiledCards);
|
||||||
|
}
|
||||||
|
public final void addExiledCards(final Iterable<Card> cards) {
|
||||||
|
exiledCards = view.addCards(exiledCards, cards, TrackableProperty.ExiledCards);
|
||||||
|
}
|
||||||
|
public final void removeExiledCard(final Card c) {
|
||||||
|
exiledCards = view.removeCard(exiledCards, c, TrackableProperty.ExiledCards);
|
||||||
|
}
|
||||||
|
public final void removeExiledCards(final Iterable<Card> cards) {
|
||||||
|
exiledCards = view.removeCards(exiledCards, cards, TrackableProperty.ExiledCards);
|
||||||
|
}
|
||||||
|
public final void clearExiledCards() {
|
||||||
|
exiledCards = view.clearCards(exiledCards, TrackableProperty.ExiledCards);
|
||||||
|
}
|
||||||
|
|
||||||
public final CardCollectionView getEncodedCards() {
|
public final CardCollectionView getEncodedCards() {
|
||||||
return CardCollection.getView(encodedCards);
|
return CardCollection.getView(encodedCards);
|
||||||
}
|
}
|
||||||
@@ -1668,6 +1694,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exiledWith.removeExiledCard(this);
|
||||||
exiledWith.removeUntilLeavesBattlefield(this);
|
exiledWith.removeUntilLeavesBattlefield(this);
|
||||||
|
|
||||||
exiledWith = null;
|
exiledWith = null;
|
||||||
|
|||||||
@@ -647,6 +647,10 @@ public class CardView extends GameEntityView {
|
|||||||
return get(TrackableProperty.ImprintedCards);
|
return get(TrackableProperty.ImprintedCards);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public FCollectionView<CardView> getExiledCards() {
|
||||||
|
return get(TrackableProperty.ExiledCards);
|
||||||
|
}
|
||||||
|
|
||||||
public FCollectionView<CardView> getHauntedBy() {
|
public FCollectionView<CardView> getHauntedBy() {
|
||||||
return get(TrackableProperty.HauntedBy);
|
return get(TrackableProperty.HauntedBy);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -232,8 +232,10 @@ public class CostAdjustment {
|
|||||||
} else if (!test) {
|
} else if (!test) {
|
||||||
sa.getHostCard().addDelved(c);
|
sa.getHostCard().addDelved(c);
|
||||||
final Card d = game.getAction().exile(c, null);
|
final Card d = game.getAction().exile(c, null);
|
||||||
d.setExiledWith(sa.getHostCard());
|
final Card host = sa.getHostCard();
|
||||||
d.setExiledBy(sa.getHostCard().getController());
|
host.addExiledCard(d);
|
||||||
|
d.setExiledWith(host);
|
||||||
|
d.setExiledBy(host.getController());
|
||||||
table.put(ZoneType.Graveyard, d.getZone().getZoneType(), d);
|
table.put(ZoneType.Graveyard, d.getZone().getZoneType(), d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -180,8 +180,10 @@ public class CostExile extends CostPartWithList {
|
|||||||
@Override
|
@Override
|
||||||
protected Card doPayment(SpellAbility ability, Card targetCard, final boolean effect) {
|
protected Card doPayment(SpellAbility ability, Card targetCard, final boolean effect) {
|
||||||
final Game game = targetCard.getGame();
|
final Game game = targetCard.getGame();
|
||||||
|
final Card host = ability.getHostCard();
|
||||||
Card newCard = game.getAction().exile(targetCard, null);
|
Card newCard = game.getAction().exile(targetCard, null);
|
||||||
newCard.setExiledWith(ability.getHostCard());
|
host.addExiledCard(newCard);
|
||||||
|
newCard.setExiledWith(host);
|
||||||
newCard.setExiledBy(ability.getActivatingPlayer());
|
newCard.setExiledBy(ability.getActivatingPlayer());
|
||||||
return newCard;
|
return newCard;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ public enum TrackableProperty {
|
|||||||
NeedsTapAnimation(TrackableTypes.BooleanType, FreezeMode.IgnoresFreeze),
|
NeedsTapAnimation(TrackableTypes.BooleanType, FreezeMode.IgnoresFreeze),
|
||||||
|
|
||||||
ImprintedCards(TrackableTypes.CardViewCollectionType),
|
ImprintedCards(TrackableTypes.CardViewCollectionType),
|
||||||
|
ExiledCards(TrackableTypes.CardViewCollectionType),
|
||||||
HauntedBy(TrackableTypes.CardViewCollectionType),
|
HauntedBy(TrackableTypes.CardViewCollectionType),
|
||||||
Haunting(TrackableTypes.CardViewType),
|
Haunting(TrackableTypes.CardViewType),
|
||||||
MustBlockCards(TrackableTypes.CardViewCollectionType),
|
MustBlockCards(TrackableTypes.CardViewCollectionType),
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
Name:Arcane Bombardment
|
Name:Arcane Bombardment
|
||||||
ManaCost:4 R R
|
ManaCost:4 R R
|
||||||
Types:Enchantment
|
Types:Enchantment
|
||||||
T:Mode$ SpellCast | ValidCard$ Instant,Sorcery | ValidActivatingPlayer$ You | ActivatorThisTurnCast$ EQ1 | NoResolvingCheck$ True | Execute$ TrigExile | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast your first instant or sorcery spell each turn, exile an instant or sorcery card at random from your graveyard. Then copy each card exiled with CARDNAME. You may cast any number of the copies without paying their mana costs.
|
T:Mode$ SpellCast | ValidCard$ Instant,Sorcery | ValidActivatingPlayer$ You | ActivatorThisTurnCast$ EQ1 | NoResolvingCheck$ True | Execute$ TrigExile | TriggerZones$ Battlefield | OrderDuplicates$ True | TriggerDescription$ Whenever you cast your first instant or sorcery spell each turn, exile an instant or sorcery card at random from your graveyard. Then copy each card exiled with CARDNAME. You may cast any number of the copies without paying their mana costs.
|
||||||
SVar:TrigExile:DB$ ChangeZone | DefinedPlayer$ You | Destination$ Exile | ChangeNum$ 1 | ChangeType$ Instant.YouOwn,Sorcery.YouOwn | AtRandom$ True | Origin$ Graveyard | Hidden$ True | Mandatory$ True | SubAbility$ DBCast
|
SVar:TrigExile:DB$ ChangeZone | DefinedPlayer$ You | Destination$ Exile | ChangeNum$ 1 | ChangeType$ Instant.YouOwn,Sorcery.YouOwn | AtRandom$ True | Origin$ Graveyard | Hidden$ True | Mandatory$ True | SubAbility$ DBCast
|
||||||
SVar:DBCast:DB$ Play | Valid$ Card.ExiledWithSource | ValidSA$ Spell | ValidZone$ Exile | Amount$ All | CopyCard$ True | Optional$ True | WithoutManaCost$ True
|
SVar:DBCast:DB$ Play | Valid$ Card.ExiledWithSource | ValidSA$ Spell | ValidZone$ Exile | Amount$ All | CopyCard$ True | Optional$ True | WithoutManaCost$ True
|
||||||
DeckNeeds:Type$Instant|Sorcery
|
DeckNeeds:Type$Instant|Sorcery
|
||||||
|
|||||||
@@ -560,6 +560,15 @@ public class CardDetailUtil {
|
|||||||
area.append(StringUtils.join(card.getImprintedCards(), ", "));
|
area.append(StringUtils.join(card.getImprintedCards(), ", "));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CardsExiledBy
|
||||||
|
if (card.getExiledCards() != null) {
|
||||||
|
if (area.length() != 0) {
|
||||||
|
area.append("\n");
|
||||||
|
}
|
||||||
|
area.append("Exiled: ");
|
||||||
|
area.append(StringUtils.join(card.getExiledCards(), ", "));
|
||||||
|
}
|
||||||
|
|
||||||
// Haunt
|
// Haunt
|
||||||
if (card.getHauntedBy() != null) {
|
if (card.getHauntedBy() != null) {
|
||||||
if (area.length() != 0) {
|
if (area.length() != 0) {
|
||||||
|
|||||||
@@ -577,6 +577,7 @@ public class HumanPlay {
|
|||||||
hostCard.addDelved(c);
|
hostCard.addDelved(c);
|
||||||
final ZoneType o = c.getZone().getZoneType();
|
final ZoneType o = c.getZone().getZoneType();
|
||||||
final Card d = game.getAction().exile(c, null);
|
final Card d = game.getAction().exile(c, null);
|
||||||
|
hostCard.addExiledCard(d);
|
||||||
d.setExiledWith(hostCard);
|
d.setExiledWith(hostCard);
|
||||||
d.setExiledBy(hostCard.getController());
|
d.setExiledBy(hostCard.getController());
|
||||||
table.put(o, d.getZone().getZoneType(), d);
|
table.put(o, d.getZone().getZoneType(), d);
|
||||||
|
|||||||
@@ -1842,7 +1842,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
|||||||
if (!currentSa.isTrigger() && currentSa.usesTargeting()) {
|
if (!currentSa.isTrigger() && currentSa.usesTargeting()) {
|
||||||
needPrompt = true;
|
needPrompt = true;
|
||||||
}
|
}
|
||||||
if (!needPrompt && !saStr.equals(firstStr)) {
|
if (!needPrompt && !saStr.equals(firstStr) && !currentSa.hasParam("OrderDuplicates")) {
|
||||||
needPrompt = true; // prompt by default unless all abilities
|
needPrompt = true; // prompt by default unless all abilities
|
||||||
// are the same
|
// are the same
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user