mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 20:58:03 +00:00
@@ -66,12 +66,8 @@ public class GameCopier {
|
||||
}
|
||||
|
||||
public Game makeCopy() {
|
||||
if (origGame.EXPERIMENTAL_RESTORE_SNAPSHOT) {
|
||||
return snapshot.makeCopy();
|
||||
} else {
|
||||
return makeCopy(null, null);
|
||||
}
|
||||
}
|
||||
public Game makeCopy(PhaseType advanceToPhase, Player aiPlayer) {
|
||||
if (origGame.EXPERIMENTAL_RESTORE_SNAPSHOT) {
|
||||
// How do we advance to phase when using restores?
|
||||
|
||||
@@ -138,11 +138,6 @@ public class PaperCard implements Comparable<IPaperCard>, InventoryItemFromSet,
|
||||
return unFoiledVersion;
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public String getImageKey() {
|
||||
// return getImageLocator(getImageName(), getArtIndex(), true, false);
|
||||
// }
|
||||
|
||||
@Override
|
||||
public String getItemType() {
|
||||
final Localizer localizer = Localizer.getInstance();
|
||||
|
||||
@@ -27,6 +27,7 @@ import forge.game.spellability.SpellAbility;
|
||||
import forge.game.trigger.Trigger;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.util.Expressions;
|
||||
import forge.util.ITranslatable;
|
||||
|
||||
/**
|
||||
* Base class for Triggers,ReplacementEffects and StaticAbilities.
|
||||
@@ -623,6 +624,14 @@ public abstract class CardTraitBase extends GameObject implements IHasCardView,
|
||||
return getCardState().getView().getState();
|
||||
}
|
||||
|
||||
public ITranslatable getHostName(CardTraitBase node) {
|
||||
// if alternate state is viewed while card uses original
|
||||
if (node.isIntrinsic() && node.cardState != null && !node.cardState.getStateName().equals(getHostCard().getCurrentStateName())) {
|
||||
return node.cardState;
|
||||
}
|
||||
return node.getHostCard();
|
||||
}
|
||||
|
||||
public Card getOriginalHost() {
|
||||
if (getCardState() != null)
|
||||
return getCardState().getCard();
|
||||
|
||||
@@ -1507,6 +1507,7 @@ public class GameAction {
|
||||
if (!c.isSaga()) {
|
||||
return false;
|
||||
}
|
||||
// needs to be effect, because otherwise it might be a cost?
|
||||
if (!c.canBeSacrificedBy(null, true)) {
|
||||
return false;
|
||||
}
|
||||
@@ -1514,7 +1515,6 @@ public class GameAction {
|
||||
return false;
|
||||
}
|
||||
if (!game.getStack().hasSourceOnStack(c, SpellAbilityPredicates.isChapter())) {
|
||||
// needs to be effect, because otherwise it might be a cost?
|
||||
sacrificeList.add(c);
|
||||
checkAgain = true;
|
||||
}
|
||||
@@ -1537,6 +1537,7 @@ public class GameAction {
|
||||
}
|
||||
return checkAgain;
|
||||
}
|
||||
|
||||
private boolean stateBasedAction_Role(Card c, CardCollection removeList) {
|
||||
if (!c.hasCardAttachments()) {
|
||||
return false;
|
||||
@@ -1552,7 +1553,6 @@ public class GameAction {
|
||||
if (rolesByPlayer.size() <= 1) {
|
||||
continue;
|
||||
}
|
||||
// sort by game timestamp
|
||||
rolesByPlayer.sort(CardPredicates.compareByGameTimestamp());
|
||||
removeList.addAll(rolesByPlayer.subList(0, rolesByPlayer.size() - 1));
|
||||
checkAgain = true;
|
||||
@@ -1780,7 +1780,6 @@ public class GameAction {
|
||||
}
|
||||
|
||||
private boolean handlePlaneswalkerRule(Player p, CardCollection noRegCreats) {
|
||||
// get all Planeswalkers
|
||||
final List<Card> list = p.getPlaneswalkersInPlay();
|
||||
boolean recheck = false;
|
||||
|
||||
@@ -2584,7 +2583,6 @@ public class GameAction {
|
||||
player.addCompletedDungeon(dungeon);
|
||||
ceaseToExist(dungeon, true);
|
||||
|
||||
// Run RoomEntered trigger
|
||||
final Map<AbilityKey, Object> runParams = AbilityKey.mapFromCard(dungeon);
|
||||
runParams.put(AbilityKey.Player, player);
|
||||
game.getTriggerHandler().runTrigger(TriggerType.DungeonCompleted, runParams, false);
|
||||
|
||||
@@ -30,16 +30,7 @@ public class AbilityApiBased extends AbilityActivated {
|
||||
|
||||
@Override
|
||||
public String getStackDescription() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (this.hostCard.hasPromisedGift() && this.isSpell() && !this.hostCard.isPermanent()) {
|
||||
sb.append("Gift a ").
|
||||
append(this.getAdditionalAbility("GiftAbility").getParam("GiftDescription")).
|
||||
append(" to ").append(this.hostCard.getPromisedGift()).
|
||||
append(". ");
|
||||
}
|
||||
|
||||
sb.append(effect.getStackDescriptionWithSubs(mapParams, this));
|
||||
return sb.toString();
|
||||
return effect.getStackDescriptionWithSubs(mapParams, this);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
||||
@@ -64,6 +64,11 @@ public abstract class SpellAbilityEffect {
|
||||
// prelude for when this is root ability
|
||||
if (!(sa instanceof AbilitySub)) {
|
||||
sb.append(sa.getHostCard()).append(" -");
|
||||
if (sa.getHostCard().hasPromisedGift()) {
|
||||
sb.append(" Gift ").
|
||||
append(sa.getAdditionalAbility("GiftAbility").getParam("GiftDescription")).
|
||||
append(" to ").append(sa.getHostCard().getPromisedGift()).append(". ");
|
||||
}
|
||||
}
|
||||
sb.append(" ");
|
||||
}
|
||||
@@ -462,6 +467,7 @@ public abstract class SpellAbilityEffect {
|
||||
|
||||
public static void addForgetOnMovedTrigger(final Card card, final String zone) {
|
||||
String trig = "Mode$ ChangesZone | ValidCard$ Card.IsRemembered | Origin$ " + zone + " | ExcludedDestinations$ Stack,Exile | Destination$ Any | TriggerZones$ Command | Static$ True";
|
||||
// CR 400.8 Exiled card becomes new object when it's exiled
|
||||
String trig2 = "Mode$ Exiled | ValidCard$ Card.IsRemembered | ValidCause$ SpellAbility.!EffectSource | TriggerZones$ Command | Static$ True";
|
||||
|
||||
final Trigger parsedTrigger = TriggerHandler.parseTrigger(trig, card, true);
|
||||
|
||||
@@ -28,7 +28,6 @@ public class AnimateAllEffect extends AnimateEffectBase {
|
||||
public void resolve(final SpellAbility sa) {
|
||||
final Card host = sa.getHostCard();
|
||||
|
||||
// AF specific sa
|
||||
Integer power = null;
|
||||
if (sa.hasParam("Power")) {
|
||||
power = AbilityUtils.calculateAmount(host, sa.getParam("Power"), sa);
|
||||
|
||||
@@ -208,7 +208,7 @@ public class CopyPermanentEffect extends TokenEffectBase {
|
||||
Player chooser = activator;
|
||||
if (sa.hasParam("Chooser")) {
|
||||
final String choose = sa.getParam("Chooser");
|
||||
chooser = AbilityUtils.getDefinedPlayers(sa.getHostCard(), choose, sa).get(0);
|
||||
chooser = AbilityUtils.getDefinedPlayers(host, choose, sa).get(0);
|
||||
}
|
||||
|
||||
// For Mimic Vat with mutated creature, need to choose one imprinted card
|
||||
@@ -272,7 +272,6 @@ public class CopyPermanentEffect extends TokenEffectBase {
|
||||
|
||||
if (!useZoneTable) {
|
||||
triggerList.triggerChangesZoneAll(game, sa);
|
||||
triggerList.clear();
|
||||
}
|
||||
if (combatChanged.isTrue()) {
|
||||
game.updateCombatForView();
|
||||
|
||||
@@ -56,8 +56,7 @@ public class DamageAllEffect extends DamageBaseEffect {
|
||||
final Card sourceLKI = card.getGame().getChangeZoneLKIInfo(card);
|
||||
final Game game = sa.getActivatingPlayer().getGame();
|
||||
|
||||
final String damage = sa.getParam("NumDmg");
|
||||
final int dmg = AbilityUtils.calculateAmount(source, damage, sa);
|
||||
final int dmg = AbilityUtils.calculateAmount(source, sa.getParam("NumDmg"), sa);
|
||||
|
||||
//Remember params from this effect have been moved to dealDamage in GameAction
|
||||
Player targetPlayer = sa.getTargets().getFirstTargetedPlayer();
|
||||
|
||||
@@ -230,7 +230,7 @@ public class MakeCardEffect extends SpellAbilityEffect {
|
||||
}
|
||||
}
|
||||
|
||||
private List<ICardFace> parseFaces (final SpellAbility sa, final String param) {
|
||||
private List<ICardFace> parseFaces(final SpellAbility sa, final String param) {
|
||||
List<ICardFace> parsedFaces = new ArrayList<>();
|
||||
for (String s : sa.getParam(param).split(",")) {
|
||||
// Cardnames that include "," must use ";" instead (i.e. Tovolar; Dire Overlord)
|
||||
@@ -244,7 +244,7 @@ public class MakeCardEffect extends SpellAbilityEffect {
|
||||
return parsedFaces;
|
||||
}
|
||||
|
||||
private Card finishMaking (final SpellAbility sa, final Card made, final Card source) {
|
||||
private Card finishMaking(final SpellAbility sa, final Card made, final Card source) {
|
||||
if (sa.hasParam("FaceDown")) made.turnFaceDown(true);
|
||||
if (sa.hasParam("RememberMade")) source.addRemembered(made);
|
||||
if (sa.hasParam("ImprintMade")) source.addImprintedCard(made);
|
||||
|
||||
@@ -11,14 +11,12 @@ public class GameEventSpellAbilityCast extends GameEvent {
|
||||
|
||||
public final SpellAbility sa;
|
||||
public final SpellAbilityStackInstance si;
|
||||
public final boolean replicate;
|
||||
public final int stackIndex;
|
||||
|
||||
public GameEventSpellAbilityCast(SpellAbility sp, SpellAbilityStackInstance si, int stackIndex, boolean replicate) {
|
||||
public GameEventSpellAbilityCast(SpellAbility sp, SpellAbilityStackInstance si, int stackIndex) {
|
||||
sa = sp;
|
||||
this.si = si;
|
||||
this.stackIndex = stackIndex;
|
||||
this.replicate = replicate;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
||||
@@ -2017,14 +2017,7 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
}
|
||||
|
||||
public final boolean cantWin() {
|
||||
boolean isAnyOppLoseProof = false;
|
||||
for (Player p : game.getPlayers()) {
|
||||
if (p == this || p.getOutcome() != null) {
|
||||
continue; // except self and already dead
|
||||
}
|
||||
isAnyOppLoseProof |= p.hasKeyword("You can't lose the game.");
|
||||
}
|
||||
return hasKeyword("You can't win the game.") || isAnyOppLoseProof;
|
||||
return hasKeyword("You can't win the game.");
|
||||
}
|
||||
|
||||
public final boolean checkLoseCondition() {
|
||||
|
||||
@@ -10,7 +10,6 @@ import forge.game.GameType;
|
||||
import forge.item.IPaperCard;
|
||||
import forge.item.PaperCard;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@@ -19,7 +18,7 @@ public class RegisteredPlayer {
|
||||
private final Deck originalDeck; // never return or modify this instance (it's a reference to game resources)
|
||||
private Deck currentDeck;
|
||||
|
||||
private static final Iterable<PaperCard> EmptyList = Collections.unmodifiableList(new ArrayList<>());
|
||||
private static final Iterable<PaperCard> EmptyList = Collections.emptyList();
|
||||
|
||||
private LobbyPlayer player = null;
|
||||
|
||||
@@ -49,7 +48,6 @@ public class RegisteredPlayer {
|
||||
public final Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public final void setId(Integer id0) {
|
||||
id = id0;
|
||||
}
|
||||
@@ -61,15 +59,6 @@ public class RegisteredPlayer {
|
||||
public final int getStartingLife() {
|
||||
return startingLife;
|
||||
}
|
||||
public final Iterable<? extends IPaperCard> getCardsOnBattlefield() {
|
||||
return Iterables.concat(cardsOnBattlefield == null ? EmptyList : cardsOnBattlefield,
|
||||
extraCardsOnBattlefield == null ? EmptyList : extraCardsOnBattlefield);
|
||||
}
|
||||
|
||||
public final Iterable<? extends IPaperCard> getExtraCardsInCommandZone() {
|
||||
return extraCardsInCommandZone == null ? EmptyList : extraCardsInCommandZone;
|
||||
}
|
||||
|
||||
public final void setStartingLife(int startingLife) {
|
||||
this.startingLife = startingLife;
|
||||
}
|
||||
@@ -77,7 +66,6 @@ public class RegisteredPlayer {
|
||||
public final int getManaShards() {
|
||||
return manaShards;
|
||||
}
|
||||
|
||||
public final void setManaShards(int manaShards) {
|
||||
this.manaShards = manaShards;
|
||||
}
|
||||
@@ -89,6 +77,15 @@ public class RegisteredPlayer {
|
||||
enableETBCountersEffect = value;
|
||||
}
|
||||
|
||||
public final Iterable<? extends IPaperCard> getCardsOnBattlefield() {
|
||||
return Iterables.concat(cardsOnBattlefield == null ? EmptyList : cardsOnBattlefield,
|
||||
extraCardsOnBattlefield == null ? EmptyList : extraCardsOnBattlefield);
|
||||
}
|
||||
|
||||
public final Iterable<? extends IPaperCard> getExtraCardsInCommandZone() {
|
||||
return extraCardsInCommandZone == null ? EmptyList : extraCardsInCommandZone;
|
||||
}
|
||||
|
||||
public final void setCardsOnBattlefield(Iterable<IPaperCard> cardsOnTable) {
|
||||
this.cardsOnBattlefield = cardsOnTable;
|
||||
}
|
||||
@@ -137,7 +134,6 @@ public class RegisteredPlayer {
|
||||
public int getTeamNumber() {
|
||||
return teamNumber;
|
||||
}
|
||||
|
||||
public void setTeamNumber(int teamNumber0) {
|
||||
this.teamNumber = teamNumber0;
|
||||
}
|
||||
@@ -192,7 +188,6 @@ public class RegisteredPlayer {
|
||||
public LobbyPlayer getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
public RegisteredPlayer setPlayer(LobbyPlayer player0) {
|
||||
this.player = player0;
|
||||
return this;
|
||||
@@ -219,7 +214,6 @@ public class RegisteredPlayer {
|
||||
setStartingLife(getStartingLife() + avatar.getRules().getLife());
|
||||
setStartingHand(getStartingHand() + avatar.getRules().getHand());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public PaperCard getPlaneswalker() {
|
||||
|
||||
@@ -110,7 +110,6 @@ public class ReplaceAddCounter extends ReplacementEffect {
|
||||
|
||||
@Override
|
||||
public boolean modeCheck(ReplacementType event, Map<AbilityKey, Object> runParams) {
|
||||
// TODO Auto-generated method stub
|
||||
if (super.modeCheck(event, runParams)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -222,12 +222,7 @@ public abstract class ReplacementEffect extends TriggerReplacementBase {
|
||||
public String getDescription() {
|
||||
if (hasParam("Description") && !this.isSuppressed()) {
|
||||
String desc = AbilityUtils.applyDescriptionTextChangeEffects(getParam("Description"), this);
|
||||
ITranslatable nameSource;
|
||||
if (this.isIntrinsic() && cardState != null && cardState.getCard() == getHostCard()) {
|
||||
nameSource = cardState;
|
||||
} else {
|
||||
nameSource = getHostCard();
|
||||
}
|
||||
ITranslatable nameSource = getHostName(this);
|
||||
desc = CardTranslation.translateMultipleDescriptionText(desc, nameSource);
|
||||
String translatedName = CardTranslation.getTranslatedName(nameSource);
|
||||
desc = TextUtil.fastReplace(desc, "CARDNAME", translatedName);
|
||||
|
||||
@@ -984,13 +984,7 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
|
||||
}
|
||||
String desc = node.getDescription();
|
||||
if (node.getHostCard() != null) {
|
||||
ITranslatable nameSource;
|
||||
// if alternate state is viewed while card uses original
|
||||
if (node.isIntrinsic() && node.cardState != null && node.cardState.getCard() == node.getHostCard()) {
|
||||
nameSource = node.cardState;
|
||||
} else {
|
||||
nameSource = node.getHostCard();
|
||||
}
|
||||
ITranslatable nameSource = getHostName(node);
|
||||
desc = CardTranslation.translateMultipleDescriptionText(desc, nameSource);
|
||||
String translatedName = CardTranslation.getTranslatedName(nameSource);
|
||||
desc = TextUtil.fastReplace(desc, "CARDNAME", translatedName);
|
||||
|
||||
@@ -183,12 +183,7 @@ public class StaticAbility extends CardTraitBase implements IIdentifiable, Clone
|
||||
@Override
|
||||
public final String toString() {
|
||||
if (hasParam("Description") && !this.isSuppressed()) {
|
||||
ITranslatable nameSource;
|
||||
if (this.isIntrinsic() && cardState != null && cardState.getCard() == getHostCard()) {
|
||||
nameSource = cardState;
|
||||
} else {
|
||||
nameSource = getHostCard();
|
||||
}
|
||||
ITranslatable nameSource = getHostName(this);
|
||||
String desc = CardTranslation.translateSingleDescriptionText(getParam("Description"), nameSource);
|
||||
String translatedName = CardTranslation.getTranslatedName(nameSource);
|
||||
desc = TextUtil.fastReplace(desc, "CARDNAME", translatedName);
|
||||
|
||||
@@ -120,12 +120,7 @@ public abstract class Trigger extends TriggerReplacementBase {
|
||||
public String toString(boolean active) {
|
||||
if (hasParam("TriggerDescription") && !this.isSuppressed()) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
ITranslatable nameSource;
|
||||
if (this.isIntrinsic() && cardState != null && cardState.getCard() == getHostCard()) {
|
||||
nameSource = cardState;
|
||||
} else {
|
||||
nameSource = getHostCard();
|
||||
}
|
||||
ITranslatable nameSource = getHostName(this);
|
||||
String desc = getParam("TriggerDescription");
|
||||
if (!desc.contains("ABILITY")) {
|
||||
desc = CardTranslation.translateSingleDescriptionText(getParam("TriggerDescription"), nameSource);
|
||||
|
||||
@@ -544,7 +544,7 @@ public class MagicStack /* extends MyObservable */ implements Iterable<SpellAbil
|
||||
sp.getActivatingPlayer().setActivateLoyaltyAbilityThisTurn(true);
|
||||
}
|
||||
game.updateStackForView();
|
||||
game.fireEvent(new GameEventSpellAbilityCast(sp, si, stackIndex, false));
|
||||
game.fireEvent(new GameEventSpellAbilityCast(sp, si, stackIndex));
|
||||
return si;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,8 +25,10 @@ public class DeckSetFilter extends DeckFormatFilter {
|
||||
public DeckSetFilter(ItemManager<? super DeckProxy> itemManager0, Collection<String> sets0,
|
||||
Collection<String> limitedSets0, boolean allowReprints0) {
|
||||
this(itemManager0, sets0, allowReprints0);
|
||||
if (limitedSets0 != null) {
|
||||
this.limitedSets.addAll(limitedSets0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemFilter<DeckProxy> createCopy() {
|
||||
|
||||
@@ -3,6 +3,6 @@ ManaCost:1 G G
|
||||
Types:Creature Lizard
|
||||
PT:2/3
|
||||
T:Mode$ ChangesZone | Origin$ Graveyard | Destination$ Hand | ValidCard$ Card.Self | Execute$ TrigGainLife | TriggerDescription$ When CARDNAME is put into your hand from your graveyard, you gain 2 life.
|
||||
K:Dredge:2
|
||||
SVar:TrigGainLife:DB$ GainLife | Defined$ You | LifeAmount$ 2
|
||||
K:Dredge:2
|
||||
Oracle:When Golgari Brownscale is put into your hand from your graveyard, you gain 2 life.\nDredge 2 (If you would draw a card, you may mill two cards instead. If you do, return this card from your graveyard to your hand.)
|
||||
|
||||
Reference in New Issue
Block a user