mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 19:28:01 +00:00
Card & Player: changed Commander Effect to work with multiple Commanders
Player: removed Leftover from Miracle
This commit is contained in:
@@ -15,6 +15,8 @@ public class DetachedCardEffect extends Card {
|
||||
addType("Effect");
|
||||
setOwner(card0.getOwner());
|
||||
setImmutable(true);
|
||||
|
||||
setEffectSource(card0);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -4024,6 +4024,15 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
if (!getExiledWith().equals(host)) {
|
||||
return false;
|
||||
}
|
||||
} else if (property.equals("EffectSource")) {
|
||||
if (!source.isEmblem() && !source.getType().hasSubtype("Effect")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final Card c = source.getEffectSource();
|
||||
if (!equals(c)) {
|
||||
return false;
|
||||
}
|
||||
} else if (property.equals("CanBeSacrificedBy")) {
|
||||
if (!canBeSacrificedBy(spellAbility)) {
|
||||
return false;
|
||||
|
||||
@@ -901,10 +901,13 @@ public class CardFactoryUtil {
|
||||
}
|
||||
|
||||
if (l[0].startsWith("CommanderCastFromCommandZone")) {
|
||||
// TODO fix it for multiple commanders
|
||||
// Read SVar CommanderCostRaise from Commander Effect
|
||||
Card commeff = CardLists.filter(cc.getCardsIn(ZoneType.Command),
|
||||
CardPredicates.nameEquals("Commander Effect")).get(0);
|
||||
Card commeff = CardLists.filter(cc.getCardsIn(ZoneType.Command), new Predicate<Card>() {
|
||||
@Override
|
||||
public boolean apply(Card input) {
|
||||
return c.equals(input.getEffectSource()) && input.getName().endsWith("Commander Effect");
|
||||
}
|
||||
}).get(0);
|
||||
return doXMath(xCount(commeff, commeff.getSVar("CommanderCostRaise")), "DivideEvenlyDown.2", c);
|
||||
}
|
||||
|
||||
|
||||
@@ -568,7 +568,7 @@ public class CardView extends GameEntityView {
|
||||
}
|
||||
if (isCommander()) {
|
||||
sb.append(getOwner()).append("'s Commander\r\n");
|
||||
sb.append(getOwner().getCommanderInfo()).append("\r\n");
|
||||
sb.append(getOwner().getCommanderInfo(this)).append("\r\n");
|
||||
}
|
||||
|
||||
if (isSplitCard()) {
|
||||
|
||||
@@ -27,7 +27,6 @@ import com.google.common.collect.Maps;
|
||||
|
||||
import forge.LobbyPlayer;
|
||||
import forge.card.MagicColor;
|
||||
import forge.card.mana.ManaCost;
|
||||
import forge.game.*;
|
||||
import forge.game.ability.AbilityFactory;
|
||||
import forge.game.ability.AbilityUtils;
|
||||
@@ -44,7 +43,6 @@ import forge.game.phase.PhaseHandler;
|
||||
import forge.game.phase.PhaseType;
|
||||
import forge.game.replacement.ReplacementHandler;
|
||||
import forge.game.replacement.ReplacementResult;
|
||||
import forge.game.spellability.Ability;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.staticability.StaticAbility;
|
||||
import forge.game.trigger.Trigger;
|
||||
@@ -1349,11 +1347,6 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
}
|
||||
view.updateNumDrawnThisTurn(this);
|
||||
|
||||
// Miracle draws
|
||||
if (numDrawnThisTurn == 1 && game.getAge() != GameStage.Mulligan) {
|
||||
drawMiracle(c);
|
||||
}
|
||||
|
||||
// Run triggers
|
||||
final HashMap<String, Object> runParams = new HashMap<String, Object>();
|
||||
runParams.put("Card", c);
|
||||
@@ -2773,26 +2766,6 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
}
|
||||
}
|
||||
|
||||
public final void drawMiracle(final Card card) {
|
||||
// Whenever a card with miracle is the first card drawn in a turn,
|
||||
// you may cast it for it's miracle cost
|
||||
if (card.getMiracleCost() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final SpellAbility playForMiracleCost = card.getFirstSpellAbility().copy();
|
||||
playForMiracleCost.setPayCosts(card.getMiracleCost());
|
||||
playForMiracleCost.setStackDescription(card.getName() + " - Cast via Miracle");
|
||||
|
||||
// TODO Convert this to a Trigger
|
||||
final Ability miracleTrigger = new MiracleTrigger(card, ManaCost.ZERO, playForMiracleCost);
|
||||
miracleTrigger.setStackDescription(card.getName() + " - Miracle.");
|
||||
miracleTrigger.setActivatingPlayer(card.getOwner());
|
||||
miracleTrigger.setTrigger(true);
|
||||
|
||||
game.getStack().add(miracleTrigger);
|
||||
}
|
||||
|
||||
public boolean isSkippingDraw() {
|
||||
if (hasKeyword("Skip your next draw step.")) {
|
||||
removeKeyword("Skip your next draw step.");
|
||||
@@ -2812,22 +2785,6 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
inboundTokens.remove(c);
|
||||
}
|
||||
|
||||
private final class MiracleTrigger extends Ability {
|
||||
private final SpellAbility miracle;
|
||||
|
||||
private MiracleTrigger(Card sourceCard0, ManaCost manaCost0, SpellAbility miracle0) {
|
||||
super(sourceCard0, manaCost0);
|
||||
miracle = miracle0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resolve() {
|
||||
miracle.setActivatingPlayer(getHostCard().getOwner());
|
||||
// pay miracle cost here.
|
||||
getHostCard().getOwner().getController().playMiracle(miracle, getHostCard());
|
||||
}
|
||||
}
|
||||
|
||||
public void onMulliganned() {
|
||||
game.fireEvent(new GameEventMulligan(this)); // quest listener may interfere here
|
||||
final int newHand = getCardsIn(ZoneType.Hand).size();
|
||||
@@ -2936,27 +2893,30 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
}
|
||||
|
||||
public static DetachedCardEffect createCommanderEffect(Game game, Card commander) {
|
||||
DetachedCardEffect eff = new DetachedCardEffect(commander, "Commander Effect");
|
||||
final String name = Lang.getPossesive(commander.getName()) + " Commander Effect";
|
||||
DetachedCardEffect eff = new DetachedCardEffect(commander, name);
|
||||
|
||||
eff.setSVar("CommanderMoveReplacement", "DB$ ChangeZone | Origin$ Battlefield,Graveyard,Exile,Library,Hand | Destination$ Command | Defined$ ReplacedCard");
|
||||
eff.setSVar("DBCommanderIncCast","DB$ StoreSVar | References$ CommanderCostRaise | SVar$ CommanderCostRaise | Type$ CountSVar | Expression$ CommanderCostRaise/Plus.2");
|
||||
eff.setSVar("CommanderCostRaise","Number$0");
|
||||
|
||||
Trigger t = TriggerHandler.parseTrigger("Mode$ SpellCast | Static$ True | ValidCard$ Card.YouOwn+IsCommander+wasCastFromCommand | References$ CommanderCostRaise | Execute$ DBCommanderIncCast", eff, true);
|
||||
Trigger t = TriggerHandler.parseTrigger("Mode$ SpellCast | Static$ True | ValidCard$ Card.YouOwn+EffectSource+wasCastFromCommand | References$ CommanderCostRaise | Execute$ DBCommanderIncCast", eff, true);
|
||||
eff.addTrigger(t);
|
||||
String moved = "Event$ Moved | ValidCard$ Card.IsCommander+YouOwn | Secondary$ True | Optional$ True | OptionalDecider$ You | ReplaceWith$ CommanderMoveReplacement ";
|
||||
|
||||
String moved = "Event$ Moved | ValidCard$ Card.EffectSource+YouOwn | Secondary$ True | Optional$ True | OptionalDecider$ You | ReplaceWith$ CommanderMoveReplacement ";
|
||||
if (game.getRules().hasAppliedVariant(GameType.TinyLeaders)) {
|
||||
moved += " | Destination$ Graveyard,Exile | Description$ If a commander would be put into its owner's graveyard or exile from anywhere, that player may put it into the command zone instead.";
|
||||
} else {
|
||||
moved += " | Destination$ Graveyard,Exile,Hand,Library | Description$ If a commander would be exiled or put into hand, graveyard, or library from anywhere, that player may put it into the command zone instead.";
|
||||
}
|
||||
eff.addReplacementEffect(ReplacementHandler.parseReplacement(moved, eff, true));
|
||||
String mayBePlayedAbility = "Mode$ Continuous | EffectZone$ Command | MayPlay$ True | Affected$ Card.YouOwn+IsCommander | AffectedZone$ Command";
|
||||
|
||||
String mayBePlayedAbility = "Mode$ Continuous | EffectZone$ Command | MayPlay$ True | Affected$ Card.YouOwn+EffectSource | AffectedZone$ Command";
|
||||
if (game.getRules().hasAppliedVariant(GameType.Planeswalker)) { //support paying for Planeswalker with any color mana
|
||||
mayBePlayedAbility += " | MayPlayIgnoreColor$ True";
|
||||
}
|
||||
eff.addStaticAbility(mayBePlayedAbility);
|
||||
eff.addStaticAbility("Mode$ RaiseCost | EffectZone$ Command | References$ CommanderCostRaise | Amount$ CommanderCostRaise | Type$ Spell | ValidCard$ Card.YouOwn+IsCommander+wasCastFromCommand | AffectedZone$ Command,Stack");
|
||||
eff.addStaticAbility("Mode$ RaiseCost | EffectZone$ Command | References$ CommanderCostRaise | Amount$ CommanderCostRaise | Type$ Spell | ValidCard$ Card.YouOwn+EffectSource+wasCastFromCommand | AffectedZone$ Command,Stack");
|
||||
return eff;
|
||||
}
|
||||
|
||||
|
||||
@@ -152,7 +152,6 @@ public abstract class PlayerController {
|
||||
/** p = target player, validCards - possible discards, min cards to discard */
|
||||
public abstract CardCollectionView chooseCardsToDiscardFrom(Player playerDiscard, SpellAbility sa, CardCollection validCards, int min, int max);
|
||||
|
||||
public abstract void playMiracle(SpellAbility miracle, Card card);
|
||||
public abstract CardCollectionView chooseCardsToDelve(int genericAmount, CardCollection grave);
|
||||
public abstract CardCollectionView chooseCardsToRevealFromHand(int min, int max, CardCollectionView valid);
|
||||
public abstract CardCollectionView chooseCardsToDiscardUnlessType(int min, CardCollectionView hand, String param, SpellAbility sa);
|
||||
|
||||
@@ -96,9 +96,8 @@ public class PlayerView extends GameEntityView {
|
||||
return opponents != null && opponents.contains(other);
|
||||
}
|
||||
|
||||
public final String getCommanderInfo() {
|
||||
final List<CardView> commanders = getCommanders();
|
||||
if (commanders == null || commanders.isEmpty()) {
|
||||
public final String getCommanderInfo(CardView v) {
|
||||
if (v == null) {
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
|
||||
@@ -108,12 +107,10 @@ public class PlayerView extends GameEntityView {
|
||||
opponents = Collections.emptyList();
|
||||
}
|
||||
for (final PlayerView p : Iterables.concat(Collections.singleton(this), opponents)) {
|
||||
for (final CardView v : this.getCommanders()) {
|
||||
final int damage = p.getCommanderDamage(v);
|
||||
if (damage > 0) {
|
||||
final String text = String.format("Commander damage to %s from %s:", p, v.getName());
|
||||
sb.append(String.format(text + " %d\r\n", damage));
|
||||
}
|
||||
final int damage = p.getCommanderDamage(v);
|
||||
if (damage > 0) {
|
||||
final String text = String.format("Commander damage to %s from %s:", p, v.getName());
|
||||
sb.append(String.format(text + " %d\r\n", damage));
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
|
||||
Reference in New Issue
Block a user