Merge pull request #138 from Northmoc/snc_ab_ql

Arcane Bombardment - quality of life
This commit is contained in:
Northmoc
2022-04-26 08:34:19 -04:00
committed by GitHub
14 changed files with 61 additions and 6 deletions

View File

@@ -823,6 +823,7 @@ public abstract class GameState {
String id = rememberedEnts.getValue();
Card exiledWith = idToCard.get(Integer.parseInt(id));
exiledWith.addExiledCard(c);
c.setExiledWith(exiledWith);
c.setExiledBy(exiledWith.getController());
}

View File

@@ -192,6 +192,7 @@ public class ChangeZoneAllEffect extends SpellAbilityEffect {
if (host == null) {
host = sa.getHostCard();
}
host.addExiledCard(movedCard);
movedCard.setExiledWith(host);
movedCard.setExiledBy(host.getController());
}

View File

@@ -719,6 +719,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
if (host == null) {
host = sa.getHostCard();
}
host.addExiledCard(gameCard);
gameCard.setExiledWith(host);
gameCard.setExiledBy(host.getController());
}
@@ -745,6 +746,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
if (destination.equals(ZoneType.Exile) && !movedCard.isToken()) {
movedCard.setExiledWith(host);
if (host != null) {
host.addExiledCard(movedCard);
movedCard.setExiledBy(host.getController());
}
}
@@ -1350,6 +1352,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
if (host == null) {
host = sa.getHostCard();
}
host.addExiledCard(movedCard);
movedCard.setExiledWith(host);
movedCard.setExiledBy(host.getController());
}
@@ -1541,6 +1544,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
host = srcSA.getHostCard();
}
movedCard = game.getAction().exile(tgtHost, srcSA, params);
host.addExiledCard(movedCard);
movedCard.setExiledWith(host);
movedCard.setExiledBy(host.getController());
} else if (srcSA.getParam("Destination").equals("TopOfLibrary")) {

View File

@@ -420,6 +420,7 @@ public class DigEffect extends SpellAbilityEffect {
if (sa.hasParam("ExileWithCounter")) {
c.addCounter(CounterType.getType(sa.getParam("ExileWithCounter")), 1, player, counterTable);
}
effectHost.addExiledCard(c);
c.setExiledWith(effectHost);
c.setExiledBy(effectHost.getController());
}
@@ -492,6 +493,7 @@ public class DigEffect extends SpellAbilityEffect {
if (sa.hasParam("ExileWithCounter")) {
c.addCounter(CounterType.getType(sa.getParam("ExileWithCounter")), 1, player, counterTable);
}
effectHost.addExiledCard(c);
c.setExiledWith(effectHost);
c.setExiledBy(effectHost.getController());
if (remZone2) {

View File

@@ -68,6 +68,7 @@ public class MillEffect extends SpellAbilityEffect {
host = sa.getHostCard();
}
for (final Card c : milled) {
host.addExiledCard(c);
c.setExiledWith(host);
if (facedown) {
c.turnFaceDown(true);

View File

@@ -109,7 +109,8 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
private final Table<Long, Long, List<String>> hiddenExtrinsicKeywords = TreeBasedTable.create();
// 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 mergedCards;
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);
}
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() {
return CardCollection.getView(encodedCards);
}
@@ -1668,6 +1694,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
return;
}
exiledWith.removeExiledCard(this);
exiledWith.removeUntilLeavesBattlefield(this);
exiledWith = null;

View File

@@ -647,6 +647,10 @@ public class CardView extends GameEntityView {
return get(TrackableProperty.ImprintedCards);
}
public FCollectionView<CardView> getExiledCards() {
return get(TrackableProperty.ExiledCards);
}
public FCollectionView<CardView> getHauntedBy() {
return get(TrackableProperty.HauntedBy);
}

View File

@@ -232,8 +232,10 @@ public class CostAdjustment {
} else if (!test) {
sa.getHostCard().addDelved(c);
final Card d = game.getAction().exile(c, null);
d.setExiledWith(sa.getHostCard());
d.setExiledBy(sa.getHostCard().getController());
final Card host = sa.getHostCard();
host.addExiledCard(d);
d.setExiledWith(host);
d.setExiledBy(host.getController());
table.put(ZoneType.Graveyard, d.getZone().getZoneType(), d);
}
}

View File

@@ -180,8 +180,10 @@ public class CostExile extends CostPartWithList {
@Override
protected Card doPayment(SpellAbility ability, Card targetCard, final boolean effect) {
final Game game = targetCard.getGame();
final Card host = ability.getHostCard();
Card newCard = game.getAction().exile(targetCard, null);
newCard.setExiledWith(ability.getHostCard());
host.addExiledCard(newCard);
newCard.setExiledWith(host);
newCard.setExiledBy(ability.getActivatingPlayer());
return newCard;
}

View File

@@ -87,6 +87,7 @@ public enum TrackableProperty {
NeedsTapAnimation(TrackableTypes.BooleanType, FreezeMode.IgnoresFreeze),
ImprintedCards(TrackableTypes.CardViewCollectionType),
ExiledCards(TrackableTypes.CardViewCollectionType),
HauntedBy(TrackableTypes.CardViewCollectionType),
Haunting(TrackableTypes.CardViewType),
MustBlockCards(TrackableTypes.CardViewCollectionType),

View File

@@ -1,7 +1,7 @@
Name:Arcane Bombardment
ManaCost:4 R R
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:DBCast:DB$ Play | Valid$ Card.ExiledWithSource | ValidSA$ Spell | ValidZone$ Exile | Amount$ All | CopyCard$ True | Optional$ True | WithoutManaCost$ True
DeckNeeds:Type$Instant|Sorcery

View File

@@ -560,6 +560,15 @@ public class CardDetailUtil {
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
if (card.getHauntedBy() != null) {
if (area.length() != 0) {

View File

@@ -577,6 +577,7 @@ public class HumanPlay {
hostCard.addDelved(c);
final ZoneType o = c.getZone().getZoneType();
final Card d = game.getAction().exile(c, null);
hostCard.addExiledCard(d);
d.setExiledWith(hostCard);
d.setExiledBy(hostCard.getController());
table.put(o, d.getZone().getZoneType(), d);

View File

@@ -1842,7 +1842,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
if (!currentSa.isTrigger() && currentSa.usesTargeting()) {
needPrompt = true;
}
if (!needPrompt && !saStr.equals(firstStr)) {
if (!needPrompt && !saStr.equals(firstStr) && !currentSa.hasParam("OrderDuplicates")) {
needPrompt = true; // prompt by default unless all abilities
// are the same
}