mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-15 02:08:00 +00:00
Merge branch 'fixing' into 'master'
Card fixes Closes #1866 See merge request core-developers/forge!4803
This commit is contained in:
@@ -3351,7 +3351,8 @@ public class AbilityUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (value.equals("OpponentsAttackedThisTurn")) {
|
if (value.equals("OpponentsAttackedThisTurn")) {
|
||||||
return doXMath(player.getAttackedOpponentsThisTurn().size(), m, source, ctb);
|
final PlayerCollection opps = game.getPlayersAttackedThisTurn().get(player);
|
||||||
|
return doXMath(opps == null ? 0 : opps.size(), m, source, ctb);
|
||||||
}
|
}
|
||||||
|
|
||||||
return doXMath(0, m, source, ctb);
|
return doXMath(0, m, source, ctb);
|
||||||
|
|||||||
@@ -198,7 +198,7 @@ public abstract class SpellAbilityEffect {
|
|||||||
// Players
|
// Players
|
||||||
protected final static PlayerCollection getTargetPlayers(final SpellAbility sa) { return getPlayers(false, "Defined", sa); }
|
protected final static PlayerCollection getTargetPlayers(final SpellAbility sa) { return getPlayers(false, "Defined", sa); }
|
||||||
protected final static PlayerCollection getTargetPlayers(final SpellAbility sa, final String definedParam) { return getPlayers(false, definedParam, sa); }
|
protected final static PlayerCollection getTargetPlayers(final SpellAbility sa, final String definedParam) { return getPlayers(false, definedParam, sa); }
|
||||||
protected final static PlayerCollection getDefinedPlayersOrTargeted(final SpellAbility sa ) { return getPlayers(true, "Defined", sa); }
|
protected final static PlayerCollection getDefinedPlayersOrTargeted(final SpellAbility sa) { return getPlayers(true, "Defined", sa); }
|
||||||
protected final static PlayerCollection getDefinedPlayersOrTargeted(final SpellAbility sa, final String definedParam) { return getPlayers(true, definedParam, sa); }
|
protected final static PlayerCollection getDefinedPlayersOrTargeted(final SpellAbility sa, final String definedParam) { return getPlayers(true, definedParam, sa); }
|
||||||
|
|
||||||
private static PlayerCollection getPlayers(final boolean definedFirst, final String definedParam, final SpellAbility sa) {
|
private static PlayerCollection getPlayers(final boolean definedFirst, final String definedParam, final SpellAbility sa) {
|
||||||
|
|||||||
@@ -184,7 +184,7 @@ public class DigEffect extends SpellAbilityEffect {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sa.hasParam("Choser")) {
|
if (sa.hasParam("Choser")) {
|
||||||
final FCollectionView<Player> choosers = AbilityUtils.getDefinedPlayers(sa.getHostCard(), sa.getParam("Choser"), sa);
|
final FCollectionView<Player> choosers = AbilityUtils.getDefinedPlayers(host, sa.getParam("Choser"), sa);
|
||||||
if (!choosers.isEmpty()) {
|
if (!choosers.isEmpty()) {
|
||||||
chooser = player.getController().chooseSingleEntityForEffect(choosers, null, sa, Localizer.getInstance().getMessage("lblChooser") + ":", false, p, null);
|
chooser = player.getController().chooseSingleEntityForEffect(choosers, null, sa, Localizer.getInstance().getMessage("lblChooser") + ":", false, p, null);
|
||||||
}
|
}
|
||||||
@@ -221,8 +221,8 @@ public class DigEffect extends SpellAbilityEffect {
|
|||||||
|
|
||||||
// Optional abilities that use a dialog box to prompt the user to skip the ability (e.g. Explorer's Scope, Quest for Ula's Temple)
|
// Optional abilities that use a dialog box to prompt the user to skip the ability (e.g. Explorer's Scope, Quest for Ula's Temple)
|
||||||
if (optional && mayBeSkipped && !valid.isEmpty()) {
|
if (optional && mayBeSkipped && !valid.isEmpty()) {
|
||||||
String prompt = !optionalAbilityPrompt.isEmpty() ? optionalAbilityPrompt : Localizer.getInstance().getMessage("lblWouldYouLikeProceedWithOptionalAbility") + " " + sa.getHostCard() + "?\n\n(" + sa.getDescription() + ")";
|
String prompt = !optionalAbilityPrompt.isEmpty() ? optionalAbilityPrompt : Localizer.getInstance().getMessage("lblWouldYouLikeProceedWithOptionalAbility") + " " + host + "?\n\n(" + sa.getDescription() + ")";
|
||||||
if (!p.getController().confirmAction(sa, null, TextUtil.fastReplace(prompt, "CARDNAME", CardTranslation.getTranslatedName(sa.getHostCard().getName())))) {
|
if (!p.getController().confirmAction(sa, null, TextUtil.fastReplace(prompt, "CARDNAME", CardTranslation.getTranslatedName(host.getName())))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ public class DigMultipleEffect extends SpellAbilityEffect {
|
|||||||
final Card host = sa.getHostCard();
|
final Card host = sa.getHostCard();
|
||||||
final Player player = sa.getActivatingPlayer();
|
final Player player = sa.getActivatingPlayer();
|
||||||
final Game game = player.getGame();
|
final Game game = player.getGame();
|
||||||
Player chooser = player;
|
|
||||||
int numToDig = AbilityUtils.calculateAmount(host, sa.getParam("DigNum"), sa);
|
int numToDig = AbilityUtils.calculateAmount(host, sa.getParam("DigNum"), sa);
|
||||||
|
|
||||||
final ZoneType srcZone = sa.hasParam("SourceZone") ? ZoneType.smartValueOf(sa.getParam("SourceZone")) : ZoneType.Library;
|
final ZoneType srcZone = sa.hasParam("SourceZone") ? ZoneType.smartValueOf(sa.getParam("SourceZone")) : ZoneType.Library;
|
||||||
@@ -40,13 +39,13 @@ public class DigMultipleEffect extends SpellAbilityEffect {
|
|||||||
boolean chooseOptional = sa.hasParam("Optional");
|
boolean chooseOptional = sa.hasParam("Optional");
|
||||||
|
|
||||||
CardZoneTable table = new CardZoneTable();
|
CardZoneTable table = new CardZoneTable();
|
||||||
for (final Player p : getTargetPlayers(sa)) {
|
for (final Player chooser : getDefinedPlayersOrTargeted(sa)) {
|
||||||
if (sa.usesTargeting() && !p.canBeTargetedBy(sa)) {
|
if (sa.usesTargeting() && !chooser.canBeTargetedBy(sa)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
final CardCollection top = new CardCollection();
|
final CardCollection top = new CardCollection();
|
||||||
final CardCollection rest = new CardCollection();
|
final CardCollection rest = new CardCollection();
|
||||||
final PlayerZone sourceZone = p.getZone(srcZone);
|
final PlayerZone sourceZone = chooser.getZone(srcZone);
|
||||||
|
|
||||||
numToDig = Math.min(numToDig, sourceZone.size());
|
numToDig = Math.min(numToDig, sourceZone.size());
|
||||||
for (int i = 0; i < numToDig; i++) {
|
for (int i = 0; i < numToDig; i++) {
|
||||||
@@ -60,10 +59,10 @@ public class DigMultipleEffect extends SpellAbilityEffect {
|
|||||||
rest.addAll(top);
|
rest.addAll(top);
|
||||||
|
|
||||||
if (sa.hasParam("Reveal")) {
|
if (sa.hasParam("Reveal")) {
|
||||||
game.getAction().reveal(top, p, false);
|
game.getAction().reveal(top, chooser, false);
|
||||||
} else {
|
} else {
|
||||||
// reveal cards first
|
// reveal cards first
|
||||||
game.getAction().revealTo(top, player);
|
game.getAction().revealTo(top, chooser);
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, CardCollection> validMap = Maps.newHashMap();
|
Map<String, CardCollection> validMap = Maps.newHashMap();
|
||||||
|
|||||||
@@ -1704,7 +1704,7 @@ public class CardProperty {
|
|||||||
} else if (property.startsWith("set")) {
|
} else if (property.startsWith("set")) {
|
||||||
final String setCode = property.substring(3, 6);
|
final String setCode = property.substring(3, 6);
|
||||||
final PaperCard setCard = StaticData.instance().getCommonCards().getCardFromEdition(card.getName(), CardDb.SetPreference.Earliest);
|
final PaperCard setCard = StaticData.instance().getCommonCards().getCardFromEdition(card.getName(), CardDb.SetPreference.Earliest);
|
||||||
if (!setCard.getEdition().equals(setCode)) {
|
if (setCard != null && !setCard.getEdition().equals(setCode)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (property.startsWith("inZone")) {
|
} else if (property.startsWith("inZone")) {
|
||||||
|
|||||||
@@ -221,6 +221,8 @@ public final class CardUtil {
|
|||||||
|
|
||||||
newCopy.getCurrentState().copyFrom(in.getState(in.getFaceupCardStateName()), true);
|
newCopy.getCurrentState().copyFrom(in.getState(in.getFaceupCardStateName()), true);
|
||||||
if (in.isFaceDown()) {
|
if (in.isFaceDown()) {
|
||||||
|
// prevent StackDescription from revealing face
|
||||||
|
newCopy.setName(in.toString());
|
||||||
newCopy.turnFaceDownNoUpdate();
|
newCopy.turnFaceDownNoUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -369,10 +369,6 @@ public class CombatUtil {
|
|||||||
c.getDamageHistory().clearNotAttackedSinceLastUpkeepOf();
|
c.getDamageHistory().clearNotAttackedSinceLastUpkeepOf();
|
||||||
c.getController().addCreaturesAttackedThisTurn(c);
|
c.getController().addCreaturesAttackedThisTurn(c);
|
||||||
c.getController().incrementAttackersDeclaredThisTurn();
|
c.getController().incrementAttackersDeclaredThisTurn();
|
||||||
|
|
||||||
if (combat.getDefenderByAttacker(c) != null && combat.getDefenderByAttacker(c) instanceof Player) {
|
|
||||||
c.getController().addAttackedOpponentThisTurn(combat.getDefenderPlayerByAttacker(c));
|
|
||||||
}
|
|
||||||
} // checkDeclareAttackers
|
} // checkDeclareAttackers
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1958,10 +1958,6 @@ public class Player extends GameEntity implements Comparable<Player> {
|
|||||||
attackersDeclaredThisTurn = 0;
|
attackersDeclaredThisTurn = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final PlayerCollection getAttackedOpponentsThisTurn() { return attackedOpponentsThisTurn; }
|
|
||||||
public final void addAttackedOpponentThisTurn(Player p) { attackedOpponentsThisTurn.add(p); }
|
|
||||||
public final void resetAttackedOpponentsThisTurn() { attackedOpponentsThisTurn.clear(); }
|
|
||||||
|
|
||||||
public final void altWinBySpellEffect(final String sourceName) {
|
public final void altWinBySpellEffect(final String sourceName) {
|
||||||
if (cantWin()) {
|
if (cantWin()) {
|
||||||
System.out.println("Tried to win, but currently can't.");
|
System.out.println("Tried to win, but currently can't.");
|
||||||
@@ -2498,7 +2494,6 @@ public class Player extends GameEntity implements Comparable<Player> {
|
|||||||
resetSacrificedThisTurn();
|
resetSacrificedThisTurn();
|
||||||
clearAssignedDamage();
|
clearAssignedDamage();
|
||||||
resetAttackersDeclaredThisTurn();
|
resetAttackersDeclaredThisTurn();
|
||||||
resetAttackedOpponentsThisTurn();
|
|
||||||
setRevolt(false);
|
setRevolt(false);
|
||||||
resetProwl();
|
resetProwl();
|
||||||
setSpellsCastLastTurn(getSpellsCastThisTurn());
|
setSpellsCastLastTurn(getSpellsCastThisTurn());
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
Name:City in a Bottle
|
Name:City in a Bottle
|
||||||
ManaCost:2
|
ManaCost:2
|
||||||
Types:Artifact
|
Types:Artifact
|
||||||
T:Mode$ Always | TriggerZones$ Battlefield | IsPresent$ Permanent.nontoken+setARN+Other | Execute$ TrigSac | TriggerDescription$ Whenever one or more other nontoken permanents with a name originally printed in the Arabian Nights expansion are on the battlefield, their controllers sacrifice them.
|
T:Mode$ Always | TriggerZones$ Battlefield | IsPresent$ Permanent.nonToken+setARN+Other | Execute$ TrigSac | TriggerDescription$ Whenever one or more other nontoken permanents with a name originally printed in the Arabian Nights expansion are on the battlefield, their controllers sacrifice them.
|
||||||
SVar:TrigSac:DB$ SacrificeAll | ValidCards$ Permanent.nontoken+setARN+Other
|
SVar:TrigSac:DB$ SacrificeAll | ValidCards$ Permanent.nontoken+setARN+Other
|
||||||
S:Mode$ CantPlayLand | ValidCard$ Card.setARN | Description$ Players can't cast spells or play lands with a name originally printed in the Arabian Nights expansion.
|
S:Mode$ CantPlayLand | ValidCard$ Card.setARN | Description$ Players can't cast spells or play lands with a name originally printed in the Arabian Nights expansion.
|
||||||
S:Mode$ CantBeCast | ValidCard$ Card.setARN
|
S:Mode$ CantBeCast | ValidCard$ Card.setARN
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ PT:5/6
|
|||||||
K:Trample
|
K:Trample
|
||||||
T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ DelTrig | TriggerDescription$ Whenever CARDNAME attacks or blocks, sacrifice it at end of combat.
|
T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ DelTrig | TriggerDescription$ Whenever CARDNAME attacks or blocks, sacrifice it at end of combat.
|
||||||
T:Mode$ Blocks | ValidCard$ Card.Self | Execute$ DelTrig | Secondary$ True | TriggerDescription$ Whenever CARDNAME attacks or blocks, sacrifice it at end of combat.
|
T:Mode$ Blocks | ValidCard$ Card.Self | Execute$ DelTrig | Secondary$ True | TriggerDescription$ Whenever CARDNAME attacks or blocks, sacrifice it at end of combat.
|
||||||
SVar:DelTrig:DB$ DelayedTrigger | Mode$ Phase | Phase$ EndCombat | ValidPlayer$ Player | Execute$ TrigSacrifice | TriggerDescription$ Sacrifice CARDNAME at end of combat.
|
SVar:DelTrig:DB$ DelayedTrigger | Mode$ Phase | Phase$ EndCombat | RememberObjects$ Self | ValidPlayer$ Player | Execute$ TrigSacrifice | TriggerDescription$ Sacrifice CARDNAME at end of combat.
|
||||||
SVar:TrigSacrifice:DB$ SacrificeAll | Defined$ DelayTriggerRememberedLKI
|
SVar:TrigSacrifice:DB$ SacrificeAll | Defined$ DelayTriggerRememberedLKI
|
||||||
SVar:SacrificeEndCombat:True
|
SVar:SacrificeEndCombat:True
|
||||||
Oracle:Trample\nWhen Runaway Carriage attacks or blocks, sacrifice it at end of combat.
|
Oracle:Trample\nWhen Runaway Carriage attacks or blocks, sacrifice it at end of combat.
|
||||||
|
|||||||
@@ -12,8 +12,7 @@ ALTERNATE
|
|||||||
Name:Explore the Vastlands
|
Name:Explore the Vastlands
|
||||||
ManaCost:3
|
ManaCost:3
|
||||||
Types:Sorcery
|
Types:Sorcery
|
||||||
A:SP$ RepeatEach | RepeatPlayers$ Player | RepeatSubAbility$ DBDig | SpellDescription$ Each player looks at the top five cards of their library and may reveal a land card and/or an instant or sorcery card from among them. Each player puts the cards they revealed this way into their hand and the rest on the bottom of their library in a random order. Each player gains 3 life.
|
A:SP$ DigMultiple | Defined$ Player | DigNum$ 5 | Optional$ True | ChangeValid$ Land,Spell.HasNoSubtype Aura | RestRandomOrder$ True | SpellDescription$ Each player may reveal a land card and/or an instant or sorcery card from among them, then puts the cards they revealed this way into their hand and the rest on the bottom of their library in a random order.
|
||||||
SVar:DBDig:DB$ Dig | Defined$ Player.IsRemembered | Choser$ Player.IsRemembered | DigNum$ 5 | ChangeNum$ 1 | ChangeValid$ Land,Instant,Sorcery | RestRandomOrder$ True | SubAbility$ DBGainLife | SpellDescription$ Each player looks at the top five cards of their library, reveals a land card and/or an instant or sorcery card from among them, then puts the cards they revealed this way into their hand and the rest on the bottom of their library in a random order.
|
|
||||||
SVar:DBGainLife:DB$ GainLife | Defined$ Player | LifeAmount$ 3
|
SVar:DBGainLife:DB$ GainLife | Defined$ Player | LifeAmount$ 3
|
||||||
DeckHas:Ability$LifeGain
|
DeckHas:Ability$LifeGain
|
||||||
DeckHints:Type$Instant|Sorcery
|
DeckHints:Type$Instant|Sorcery
|
||||||
|
|||||||
Reference in New Issue
Block a user