- Added Cairn Wanderer, Concerted Effort, and Death-Mask Duplicant

This commit is contained in:
swordshine
2013-04-07 05:04:12 +00:00
parent 0dbfc078e0
commit 4c6e09b8be
7 changed files with 150 additions and 55 deletions

3
.gitattributes vendored
View File

@@ -1420,6 +1420,7 @@ res/cardsfolder/c/cadaverous_bloom.txt svneol=native#text/plain
res/cardsfolder/c/cadaverous_knight.txt svneol=native#text/plain res/cardsfolder/c/cadaverous_knight.txt svneol=native#text/plain
res/cardsfolder/c/cage_of_hands.txt svneol=native#text/plain res/cardsfolder/c/cage_of_hands.txt svneol=native#text/plain
res/cardsfolder/c/cagemail.txt svneol=native#text/plain res/cardsfolder/c/cagemail.txt svneol=native#text/plain
res/cardsfolder/c/cairn_wanderer.txt -text
res/cardsfolder/c/calciderm.txt svneol=native#text/plain res/cardsfolder/c/calciderm.txt svneol=native#text/plain
res/cardsfolder/c/calciform_pools.txt svneol=native#text/plain res/cardsfolder/c/calciform_pools.txt svneol=native#text/plain
res/cardsfolder/c/calcite_snapper.txt svneol=native#text/plain res/cardsfolder/c/calcite_snapper.txt svneol=native#text/plain
@@ -1925,6 +1926,7 @@ res/cardsfolder/c/compost.txt svneol=native#text/plain
res/cardsfolder/c/compulsion.txt svneol=native#text/plain res/cardsfolder/c/compulsion.txt svneol=native#text/plain
res/cardsfolder/c/compulsive_research.txt svneol=native#text/plain res/cardsfolder/c/compulsive_research.txt svneol=native#text/plain
res/cardsfolder/c/concentrate.txt svneol=native#text/plain res/cardsfolder/c/concentrate.txt svneol=native#text/plain
res/cardsfolder/c/concerted_effort.txt -text
res/cardsfolder/c/conch_horn.txt svneol=native#text/plain res/cardsfolder/c/conch_horn.txt svneol=native#text/plain
res/cardsfolder/c/conclave_equenaut.txt -text res/cardsfolder/c/conclave_equenaut.txt -text
res/cardsfolder/c/conclave_phalanx.txt -text res/cardsfolder/c/conclave_phalanx.txt -text
@@ -2414,6 +2416,7 @@ res/cardsfolder/d/death_cultist.txt svneol=native#text/plain
res/cardsfolder/d/death_denied.txt svneol=native#text/plain res/cardsfolder/d/death_denied.txt svneol=native#text/plain
res/cardsfolder/d/death_grasp.txt svneol=native#text/plain res/cardsfolder/d/death_grasp.txt svneol=native#text/plain
res/cardsfolder/d/death_hood_cobra.txt svneol=native#text/plain res/cardsfolder/d/death_hood_cobra.txt svneol=native#text/plain
res/cardsfolder/d/death_mask_duplicant.txt -text
res/cardsfolder/d/death_mutation.txt svneol=native#text/plain res/cardsfolder/d/death_mutation.txt svneol=native#text/plain
res/cardsfolder/d/death_of_a_thousand_stings.txt svneol=native#text/plain res/cardsfolder/d/death_of_a_thousand_stings.txt svneol=native#text/plain
res/cardsfolder/d/death_or_glory.txt -text res/cardsfolder/d/death_or_glory.txt -text

View File

@@ -0,0 +1,9 @@
Name:Cairn Wanderer
ManaCost:4 B
Types:Creature Shapeshifter
PT:4/4
S:Mode$ Continuous | EffectZone$ All | Affected$ Card.Self | CharacteristicDefining$ True | AddType$ AllCreatureTypes | Description$ Changeling (This card is every creature type at all times.)
S:Mode$ Continuous | EffectZone$ All | Affected$ Card.Self | CharacteristicDefining$ True | AddKeyword$ Flying & Fear & First Strike & Double Strike & Deathtouch & Haste & Landwalk & Lifelink & Protection & Reach & Trample & Shroud & Vigilance | SharedKeywordsZone$ Graveyard | SharedRestrictions$ Creature | Description$ As long as a creature card with flying is in a graveyard, CARDNAME has flying. The same is true for fear, first strike, double strike, deathtouch, haste, landwalk, lifelink, protection, reach, trample, shroud, and vigilance.
SVar:Picture:http://www.wizards.com/global/images/magic/general/cairn_wanderer.jpg
Oracle:Changeling (This card is every creature type at all times.)\nAs long as a creature card with flying is in a graveyard, Cairn Wanderer has flying. The same is true for fear, first strike, double strike, deathtouch, haste, landwalk, lifelink, protection, reach, trample, shroud, and vigilance.
SetInfo:LRW Rare

View File

@@ -0,0 +1,8 @@
Name:Concerted Effort
ManaCost:2 W W
Types:Enchantment
T:Mode$ Phase | Phase$ Upkeep | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ At the beginning of each upkeep, all creatures you control gain flying until end of turn if a creature you control has flying. The same is true for fear, first strike, double strike, landwalk, protection, trample, and vigilance.
SVar:TrigPump:AB$ PumpAll | Cost$ 0 | ValidCards$ Creature.YouCtrl | KW$ Flying & Fear & First Strike & Double Strike & Landwalk & Protection & Trample & Vigilance | SharedKeywordsZone$ Battlefield | SharedRestrictions$ Creature.YouCtrl
SVar:Picture:http://www.wizards.com/global/images/magic/general/concerted_effort.jpg
Oracle:At the beginning of each upkeep, all creatures you control gain flying until end of turn if a creature you control has flying. The same is true for fear, first strike, double strike, landwalk, protection, trample, and vigilance.
SetInfo:RAV Rare

View File

@@ -0,0 +1,12 @@
Name:Death-Mask Duplicant
ManaCost:7
Types:Artifact Creature Shapeshifter
PT:5/5
A:AB$ ChangeZone | PrecostDesc$ Imprint - | Cost$ 1 | Imprint$ True | Origin$ Graveyard | Destination$ Exile | ValidTgts$ Creature.YouOwn | SpellDescription$ Exile target creature card from your graveyard.
S:Mode$ Continuous | EffectZone$ All | Affected$ Card.Self | CharacteristicDefining$ True | AddKeyword$ Flying & Fear & First Strike & Double Strike & Haste & Landwalk & Protection & Trample | SharedKeywordsZone$ Exile | SharedRestrictions$ Card.IsImprinted | Description$ As long as a card exiled with CARDNAME has flying, CARDNAME has flying. The same is true for fear, first strike, double strike, haste, landwalk, protection, and trample.
T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Battlefield | Destination$ Any | Execute$ TrigForget | Static$ True
SVar:TrigForget:DB$ Cleanup | ClearImprinted$ True
SVar:RemAIDeck:True
SVar:Picture:http://www.wizards.com/global/images/magic/general/death_mask_duplicant.jpg
Oracle:Imprint - {1}: Exile target creature card from your graveyard.\nAs long as a card exiled with Death-Mask Duplicant has flying, Death-Mask Duplicant has flying. The same is true for fear, first strike, double strike, haste, landwalk, protection, and trample.
SetInfo:DST Uncommon

View File

@@ -9,11 +9,70 @@ import forge.Command;
import forge.Singletons; import forge.Singletons;
import forge.card.ability.AbilityUtils; import forge.card.ability.AbilityUtils;
import forge.card.ability.SpellAbilityEffect; import forge.card.ability.SpellAbilityEffect;
import forge.card.cardfactory.CardFactoryUtil;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
public class PumpAllEffect extends SpellAbilityEffect { public class PumpAllEffect extends SpellAbilityEffect {
private void applyPumpAll(final SpellAbility sa, final List<Card> list, final int a,
final int d, final List<String> keywords, final ArrayList<ZoneType> affectedZones) {
for (final Card tgtC : list) {
// only pump things in the affected zones.
boolean found = false;
for (final ZoneType z : affectedZones) {
if (tgtC.isInZone(z)) {
found = true;
break;
}
}
if (!found) {
continue;
}
tgtC.addTempAttackBoost(a);
tgtC.addTempDefenseBoost(d);
for (int i = 0; i < keywords.size(); i++) {
tgtC.addExtrinsicKeyword(keywords.get(i));
if (keywords.get(i).equals("Suspend")) {
tgtC.setSuspend(true);
}
}
if (sa.hasParam("RememberAllPumped")) {
sa.getSourceCard().addRemembered(tgtC);
}
if (!sa.hasParam("Permanent")) {
// If not Permanent, remove Pumped at EOT
final Command untilEOT = new Command() {
private static final long serialVersionUID = 5415795460189457660L;
@Override
public void execute() {
tgtC.addTempAttackBoost(-1 * a);
tgtC.addTempDefenseBoost(-1 * d);
if (keywords.size() > 0) {
for (int i = 0; i < keywords.size(); i++) {
tgtC.removeExtrinsicKeyword(keywords.get(i));
}
}
}
};
if (sa.hasParam("UntilUntaps")) {
sa.getSourceCard().addUntapCommand(untilEOT);
} else if (sa.hasParam("UntilEndOfCombat")) {
Singletons.getModel().getGame().getEndOfCombat().addUntil(untilEOT);
} else {
Singletons.getModel().getGame().getEndOfTurn().addUntil(untilEOT);
}
}
}
}
@Override @Override
protected String getStackDescription(SpellAbility sa) { protected String getStackDescription(SpellAbility sa) {
final StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
@@ -65,65 +124,16 @@ public class PumpAllEffect extends SpellAbilityEffect {
list = AbilityUtils.filterListByType(list, valid, sa); list = AbilityUtils.filterListByType(list, valid, sa);
final List<String> keywords = sa.hasParam("KW") ? Arrays.asList(sa.getParam("KW").split(" & ")) : new ArrayList<String>(); List<String> keywords = sa.hasParam("KW") ? Arrays.asList(sa.getParam("KW").split(" & ")) : new ArrayList<String>();
final int a = AbilityUtils.calculateAmount(sa.getSourceCard(), sa.getParam("NumAtt"), sa); final int a = AbilityUtils.calculateAmount(sa.getSourceCard(), sa.getParam("NumAtt"), sa);
final int d = AbilityUtils.calculateAmount(sa.getSourceCard(), sa.getParam("NumDef"), sa); final int d = AbilityUtils.calculateAmount(sa.getSourceCard(), sa.getParam("NumDef"), sa);
final String remember = sa.getParam("RememberAllPumped");
for (final Card tgtC : list) { if (sa.hasParam("SharedKeywordsZone")) {
List<ZoneType> zones = ZoneType.listValueOf(sa.getParam("SharedKeywordsZone"));
// only pump things in the affected zones. String[] restrictions = sa.hasParam("SharedRestrictions") ? sa.getParam("SharedRestrictions").split(",") : new String[] {"Card"};
boolean found = false; keywords = CardFactoryUtil.sharedKeywords(sa.getParam("KW").split(" & "), restrictions, zones, sa.getSourceCard());
for (final ZoneType z : affectedZones) {
if (tgtC.isInZone(z)) {
found = true;
break;
}
}
if (!found) {
continue;
}
tgtC.addTempAttackBoost(a);
tgtC.addTempDefenseBoost(d);
for (int i = 0; i < keywords.size(); i++) {
tgtC.addExtrinsicKeyword(keywords.get(i));
if (keywords.get(i).equals("Suspend")) {
tgtC.setSuspend(true);
}
}
if (remember != null) {
sa.getSourceCard().addRemembered(tgtC);
}
if (!sa.hasParam("Permanent")) {
// If not Permanent, remove Pumped at EOT
final Command untilEOT = new Command() {
private static final long serialVersionUID = 5415795460189457660L;
@Override
public void execute() {
tgtC.addTempAttackBoost(-1 * a);
tgtC.addTempDefenseBoost(-1 * d);
if (keywords.size() > 0) {
for (int i = 0; i < keywords.size(); i++) {
tgtC.removeExtrinsicKeyword(keywords.get(i));
}
}
}
};
if (sa.hasParam("UntilUntaps")) {
sa.getSourceCard().addUntapCommand(untilEOT);
} else if (sa.hasParam("UntilEndOfCombat")) {
Singletons.getModel().getGame().getEndOfCombat().addUntil(untilEOT);
} else {
Singletons.getModel().getGame().getEndOfTurn().addUntil(untilEOT);
}
}
} }
this.applyPumpAll(sa, list, a, d, keywords, affectedZones);
} // pumpAllResolve() } // pumpAllResolve()
} }

View File

@@ -2171,6 +2171,53 @@ public class CardFactoryUtil {
return true; return true;
} }
/**
* <p>
* sharedKeywords.
* </p>
*
* @param kw
* a {@link forge.CardList} object.
* @return a List<String>.
*/
public static List<String> sharedKeywords(final String[] kw, final String[] restrictions,
final List<ZoneType> zones, final Card host) {
final List<String> filteredkw = new ArrayList<String>();
final Player p = host.getController();
List<Card> cardlist = new ArrayList<Card>(p.getGame().getCardsIn(zones));
final List<String> landkw = new ArrayList<String>();
final List<String> protectionkw = new ArrayList<String>();
final List<String> allkw = new ArrayList<String>();
cardlist = CardLists.getValidCards(cardlist, restrictions, p, host);
for (Card c : cardlist) {
for (String k : c.getKeyword()) {
if (k.endsWith("walk")) {
if (!landkw.contains(k)) {
landkw.add(k);
}
} else if (k.startsWith("Protection")) {
if (!protectionkw.contains(k)) {
protectionkw.add(k);
}
}
if (!allkw.contains(k)) {
allkw.add(k);
}
}
}
for (String keyword : kw) {
if (keyword.equals("Protection")) {
filteredkw.addAll(protectionkw);
} else if (keyword.equals("Landwalk")) {
filteredkw.addAll(landkw);
} else if (allkw.contains(keyword)) {
filteredkw.add(keyword);
}
}
return filteredkw;
}
/** /**
* <p> * <p>
* getBushidoEffects. * getBushidoEffects.

View File

@@ -160,6 +160,12 @@ public class StaticAbilityContinuous {
addKeywords[w] = addKeywords[w].replaceAll("ChosenName", "Card.named" + chosenName); addKeywords[w] = addKeywords[w].replaceAll("ChosenName", "Card.named" + chosenName);
} }
} }
if (params.containsKey("SharedKeywordsZone")) {
List<ZoneType> zones = ZoneType.listValueOf(params.get("SharedKeywordsZone"));
String[] restrictions = params.containsKey("SharedRestrictions") ? params.get("SharedRestrictions").split(",") : new String[] {"Card"};
List<String> kw = CardFactoryUtil.sharedKeywords(addKeywords, restrictions, zones, hostCard);
addKeywords = kw.toArray(new String[kw.size()]);
}
} }
if (params.containsKey("AddHiddenKeyword")) { if (params.containsKey("AddHiddenKeyword")) {