Card & Player: changed Commander Effect to work with multiple Commanders

Player: removed Leftover from Miracle
This commit is contained in:
Hanmac
2016-11-19 16:47:09 +00:00
parent a78cd7cb54
commit 7400baf1c7
7 changed files with 32 additions and 62 deletions

View File

@@ -15,6 +15,8 @@ public class DetachedCardEffect extends Card {
addType("Effect");
setOwner(card0.getOwner());
setImmutable(true);
setEffectSource(card0);
}
@Override

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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()) {

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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();