mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-15 18:28:00 +00:00
- Added an Effect to gain Control of Spells.
- Added Commandeer
This commit is contained in:
2
.gitattributes
vendored
2
.gitattributes
vendored
@@ -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
|
||||||
|
|||||||
@@ -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),
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -298,6 +295,14 @@ 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);
|
||||||
|
|||||||
9
forge-gui/res/cardsfolder/c/commandeer.txt
Normal file
9
forge-gui/res/cardsfolder/c/commandeer.txt
Normal 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.)
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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.)
|
||||||
Reference in New Issue
Block a user