- Added an Effect to gain Control of Spells.

- Added Commandeer
This commit is contained in:
Sol
2014-02-16 17:15:44 +00:00
parent 4525633ad8
commit 1982f73e3d
8 changed files with 102 additions and 10 deletions

2
.gitattributes vendored
View File

@@ -306,6 +306,7 @@ forge-game/src/main/java/forge/game/ability/effects/CloneEffect.java -text
forge-game/src/main/java/forge/game/ability/effects/ControlExchangeEffect.java -text forge-game/src/main/java/forge/game/ability/effects/ControlExchangeEffect.java -text
forge-game/src/main/java/forge/game/ability/effects/ControlGainEffect.java -text forge-game/src/main/java/forge/game/ability/effects/ControlGainEffect.java -text
forge-game/src/main/java/forge/game/ability/effects/ControlPlayerEffect.java -text forge-game/src/main/java/forge/game/ability/effects/ControlPlayerEffect.java -text
forge-game/src/main/java/forge/game/ability/effects/ControlSpellEffect.java -text
forge-game/src/main/java/forge/game/ability/effects/CopyPermanentEffect.java -text forge-game/src/main/java/forge/game/ability/effects/CopyPermanentEffect.java -text
forge-game/src/main/java/forge/game/ability/effects/CopySpellAbilityEffect.java -text forge-game/src/main/java/forge/game/ability/effects/CopySpellAbilityEffect.java -text
forge-game/src/main/java/forge/game/ability/effects/CounterEffect.java -text forge-game/src/main/java/forge/game/ability/effects/CounterEffect.java -text
@@ -2710,6 +2711,7 @@ forge-gui/res/cardsfolder/c/combust.txt svneol=native#text/plain
forge-gui/res/cardsfolder/c/comet_storm.txt -text forge-gui/res/cardsfolder/c/comet_storm.txt -text
forge-gui/res/cardsfolder/c/command_of_unsummoning.txt svneol=native#text/plain forge-gui/res/cardsfolder/c/command_of_unsummoning.txt svneol=native#text/plain
forge-gui/res/cardsfolder/c/command_tower.txt -text forge-gui/res/cardsfolder/c/command_tower.txt -text
forge-gui/res/cardsfolder/c/commandeer.txt -text
forge-gui/res/cardsfolder/c/commander_eesha.txt svneol=native#text/plain forge-gui/res/cardsfolder/c/commander_eesha.txt svneol=native#text/plain
forge-gui/res/cardsfolder/c/commander_greven_il_vec.txt svneol=native#text/plain forge-gui/res/cardsfolder/c/commander_greven_il_vec.txt svneol=native#text/plain
forge-gui/res/cardsfolder/c/commanders_authority.txt -text forge-gui/res/cardsfolder/c/commanders_authority.txt -text

View File

@@ -38,6 +38,7 @@ public enum ApiType {
Clone (CloneEffect.class), Clone (CloneEffect.class),
CopyPermanent (CopyPermanentEffect.class), CopyPermanent (CopyPermanentEffect.class),
CopySpellAbility (CopySpellAbilityEffect.class), CopySpellAbility (CopySpellAbilityEffect.class),
ControlSpell (ControlSpellEffect.class),
ControlPlayer (ControlPlayerEffect.class), ControlPlayer (ControlPlayerEffect.class),
Counter (CounterEffect.class), Counter (CounterEffect.class),
DamageAll (DamageAllEffect.class), DamageAll (DamageAllEffect.class),

View File

@@ -45,6 +45,7 @@ public class ChangeTargetsEffect extends SpellAbilityEffect {
Player chooser = sa.getActivatingPlayer(); Player chooser = sa.getActivatingPlayer();
// Redirect rules read 'you MAY choose new targets' ... okay! // Redirect rules read 'you MAY choose new targets' ... okay!
// TODO: Don't even ask to change targets, if the SA and subs don't actually have targets
boolean isOptional = sa.hasParam("Optional"); boolean isOptional = sa.hasParam("Optional");
if( isOptional && !chooser.getController().confirmAction(sa, null, "Do you want to change targets of " + tgtSA.getHostCard() + "?")) if( isOptional && !chooser.getController().confirmAction(sa, null, "Do you want to change targets of " + tgtSA.getHostCard() + "?"))
continue; continue;
@@ -90,8 +91,8 @@ public class ChangeTargetsEffect extends SpellAbilityEffect {
GameObject choice = Aggregates.random(candidates); GameObject choice = Aggregates.random(candidates);
changingTgtSA.getTargets().add(choice); changingTgtSA.getTargets().add(choice);
changingTgtSI.updateTarget(changingTgtSA.getTargets()); changingTgtSI.updateTarget(changingTgtSA.getTargets());
} else if (sa.hasParam("Defined")){ } else if (sa.hasParam("DefinedMagnet")){
GameObject newTarget = Iterables.getFirst(getDefinedCardsOrTargeted(sa), null); GameObject newTarget = Iterables.getFirst(getDefinedCardsOrTargeted(sa, "DefinedMagnet"), null);
if(changingTgtSA.canTarget(newTarget)) { if(changingTgtSA.canTarget(newTarget)) {
changingTgtSA.resetTargets(); changingTgtSA.resetTargets();
changingTgtSA.getTargets().add(newTarget); changingTgtSA.getTargets().add(newTarget);

View File

@@ -0,0 +1,74 @@
package forge.game.ability.effects;
import forge.game.Game;
import forge.game.ability.SpellAbilityEffect;
import forge.game.card.Card;
import forge.game.player.Player;
import forge.game.spellability.SpellAbility;
import forge.game.spellability.SpellAbilityStackInstance;
import java.util.List;
public class ControlSpellEffect extends SpellAbilityEffect {
/* (non-Javadoc)
* @see forge.card.abilityfactory.SpellEffect#getStackDescription(java.util.Map, forge.card.spellability.SpellAbility)
*/
@Override
protected String getStackDescription(SpellAbility sa) {
final StringBuilder sb = new StringBuilder();
List<Player> newController = getTargetPlayers(sa, "NewController");
if (newController.isEmpty()) {
newController.add(sa.getActivatingPlayer());
}
sb.append(newController).append(" gains control of ");
for(SpellAbility spell : getTargetSpells(sa)) {
Card c = spell.getHostCard();
sb.append(" ");
if (c.isFaceDown()) {
sb.append("Morph");
} else {
sb.append(c);
}
}
sb.append(".");
return sb.toString();
}
@Override
public void resolve(SpellAbility sa) {
// Gaining Control of Spells is a permanent effect
Card source = sa.getHostCard();
boolean exchange = sa.getParam("Mode").equals("Exchange");
final List<Player> controllers = getDefinedPlayersOrTargeted(sa, "NewController");
final Player newController = controllers.isEmpty() ? sa.getActivatingPlayer() : controllers.get(0);
final Game game = newController.getGame();
List<SpellAbility> tgtSpells = getTargetSpells(sa);
// If an Exchange needs to happen, make sure both parties are still in the right zones
for(SpellAbility spell : tgtSpells) {
if (exchange) {
// Currently the only Exchange Control for Spells, is a Permanent Trigger
// Use "DefinedExchange" to Reference Object that is Exchanging the other direction
}
Card tgtC = spell.getHostCard();
if (!tgtC.equals(sa.getHostCard()) && !sa.getHostCard().getGainControlTargets().contains(tgtC)) {
sa.getHostCard().addGainControlTarget(tgtC);
}
long tStamp = game.getNextTimestamp();
tgtC.setController(newController, tStamp);
SpellAbilityStackInstance si = game.getStack().getInstanceFromSpellAbility(spell);
si.setActivator(newController);
}
}
}

View File

@@ -42,19 +42,16 @@ public class SpellAbilityStackInstance {
// gets cleared from the base SI // gets cleared from the base SI
// Coming off the Stack would work similarly, except it would just add the // Coming off the Stack would work similarly, except it would just add the
// full active SI instead of each of the parts // full active SI instead of each of the parts
/** The ability. */
private SpellAbility ability = null; private SpellAbility ability = null;
/** The sub instace. */
private SpellAbilityStackInstance subInstace = null; private SpellAbilityStackInstance subInstace = null;
private final Player activator; private Player activator;
// When going to a SubAbility that SA has a Instance Choice object // When going to a SubAbility that SA has a Instance Choice object
/** The tc. */
private TargetChoices tc = new TargetChoices(); private TargetChoices tc = new TargetChoices();
private List<Card> splicedCards = null; private List<Card> splicedCards = null;
/** The stack description. */
private String stackDescription = null; private String stackDescription = null;
// Adjusted Mana Cost // Adjusted Mana Cost
@@ -297,7 +294,15 @@ public class SpellAbilityStackInstance {
return true; return true;
} }
public Player getActivator() {
return activator;
}
public void setActivator(Player activator) {
this.activator = activator;
}
@Override @Override
public String toString() { public String toString() {
return String.format("%s->%s", getSourceCard(), stackDescription); return String.format("%s->%s", getSourceCard(), stackDescription);

View File

@@ -0,0 +1,9 @@
Name:Commandeer
ManaCost:5 U U
Types:Instant
A:SP$ ControlSpell | Cost$ 5 U U | ValidTgts$ Card.nonCreature | TgtZone$ Stack | Mode$ Gain | SubAbility$ DBChooseTargets | SpellDescription$ Gain control of target noncreature spell. You may choose new targets for it. (If that spell is an artifact, enchantment, or planeswalker, the permanent enters the battlefield under your control.)
SVar:DBChooseTargets:DB$ ChangeTargets | Defined$ Targeted | Optional$ True
SVar:AltCost:Cost$ ExileFromHand<2/Card.Blue> | Description$ You may exile two blue cards from your hand rather than pay CARDNAME's mana cost.
SVar:RemAIDeck:True
SVar:Picture:http://www.wizards.com/global/images/magic/general/commandeer.jpg
Oracle:You may exile two blue cards from your hand rather than pay Commandeer's mana cost.\nGain control of target noncreature spell. You may choose new targets for it. (If that spell is an artifact, enchantment, or planeswalker, the permanent enters the battlefield under your control.)

View File

@@ -4,7 +4,7 @@ Types:Creature Beast
PT:3/3 PT:3/3
K:Flash K:Flash
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigChange | TriggerDescription$ When CARDNAME enters the battlefield, change the target of target spell that targets only a single creature to Muck Drubb. T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigChange | TriggerDescription$ When CARDNAME enters the battlefield, change the target of target spell that targets only a single creature to Muck Drubb.
SVar:TrigChange:AB$ ChangeTargets | Cost$ 0 | TargetType$ Spell | ValidTgts$ Card | Defined$ Self | TargetsSingleTarget$ True | TargetValidTargeting$ Creature SVar:TrigChange:AB$ ChangeTargets | Cost$ 0 | TargetType$ Spell | ValidTgts$ Card | DefinedMagnet$ Self | TargetsSingleTarget$ True | TargetValidTargeting$ Creature
K:Madness:2 B K:Madness:2 B
SVar:RemAIDeck:True SVar:RemAIDeck:True
SVar:Picture:http://www.wizards.com/global/images/magic/general/muck_drubb.jpg SVar:Picture:http://www.wizards.com/global/images/magic/general/muck_drubb.jpg

View File

@@ -2,6 +2,6 @@ Name:Spellskite
ManaCost:2 ManaCost:2
Types:Artifact Creature Horror Types:Artifact Creature Horror
PT:0/4 PT:0/4
A:AB$ ChangeTargets | Cost$ PU | TargetType$ Spell,Activated,Triggered | ValidTgts$ Card | Defined$ Self | ChangeSingleTarget$ True | SpellDescription$ Change a target of target spell or ability to Spellskite. A:AB$ ChangeTargets | Cost$ PU | TargetType$ Spell,Activated,Triggered | ValidTgts$ Card | DefinedMagnet$ Self | ChangeSingleTarget$ True | SpellDescription$ Change a target of target spell or ability to Spellskite.
SVar:Picture:http://www.wizards.com/global/images/magic/general/spellskite.jpg SVar:Picture:http://www.wizards.com/global/images/magic/general/spellskite.jpg
Oracle:{U/P}: Change a target of target spell or ability to Spellskite. ({U/P} can be paid with either {U} or 2 life.) Oracle:{U/P}: Change a target of target spell or ability to Spellskite. ({U/P} can be paid with either {U} or 2 life.)