- Updated token images

- Added Darksteel Garrison
This commit is contained in:
swordshine
2013-06-17 00:21:53 +00:00
parent 2c88d952d2
commit abcb758a56
17 changed files with 360 additions and 24 deletions

1
.gitattributes vendored
View File

@@ -2395,6 +2395,7 @@ res/cardsfolder/d/darksteel_citadel.txt svneol=native#text/plain
res/cardsfolder/d/darksteel_colossus.txt svneol=native#text/plain
res/cardsfolder/d/darksteel_forge.txt svneol=native#text/plain
res/cardsfolder/d/darksteel_gargoyle.txt svneol=native#text/plain
res/cardsfolder/d/darksteel_garrison.txt -text
res/cardsfolder/d/darksteel_ingot.txt svneol=native#text/plain
res/cardsfolder/d/darksteel_juggernaut.txt svneol=native#text/plain
res/cardsfolder/d/darksteel_myr.txt svneol=native#text/plain

View File

@@ -0,0 +1,9 @@
Name:Darksteel Garrison
ManaCost:2
Types:Artifact Fortification
K:Fortify 3
S:Mode$ Continuous | Affected$ Land.FortifiedBy | AddKeyword$ Indestructible | Description$ Fortified land is indestructible.
T:Mode$ Taps | ValidCard$ Land.FortifiedBy | Execute$ TrigPump | TriggerDescription$ Whenever fortified land becomes tapped, target creature gets +1/+1 until end of turn.
SVar:TrigPump:AB$ Pump | Cost$ 0 | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumAtt$ 1 | NumDef$ 1
SVar:Picture:http://www.wizards.com/global/images/magic/general/darksteel_garrison.jpg
Oracle:Fortified land is indestructible.\nWhenever fortified land becomes tapped, target creature gets +1/+1 until end of turn.\nFortify {3} ({3}: Attach to target land you control. Fortify only as a sorcery. This card enters the battlefield unattached and stays on the battlefield if the land leaves.)

View File

@@ -195,6 +195,7 @@ w_1_1_goldmeadow_harrier.jpg http://www.cardforge.org/fpics/tokens/w_1
w_1_1_human_dka.jpg http://www.cardforge.org/fpics/tokens/w_1_1_human_dka.jpg
w_1_1_human_avr.jpg http://www.cardforge.org/fpics/tokens/w_1_1_human_avr.jpg
w_1_1_kithkin_soldier.jpg http://www.cardforge.org/fpics/tokens/w_1_1_kithkin_soldier.jpg
w_1_1_knight.jpg http://www.cardforge.org/fpics/tokens/w_1_1_knight.jpg
w_1_1_kor_soldier.jpg http://www.cardforge.org/fpics/tokens/w_1_1_kor_soldier.jpg
w_1_1_pegasus.jpg http://www.cardforge.org/fpics/tokens/w_1_1_pegasus.jpg
w_1_1_soldier.jpg http://www.cardforge.org/fpics/tokens/w_1_1_soldier.jpg
@@ -238,4 +239,3 @@ morph.jpg http://www.cardforge.org/fpics/effects/mo
# //These tokens are not currently used by any cards in Forge, but links provided should they be scripted so the correct name is used:
# //g_1_1_wolves_of_the_hunt.jpg http://www.cardforge.org/fpics/tokens/g_1_1_wolves_of_the_hunt.jpg [LEG] Master of the Hunt
# //rg_1_1_goblin_warrior.jpg http://www.cardforge.org/fpics/tokens/rg_1_1_goblin_warrior.jpg [SHM] Wort, the Raidmother
# //w_1_1_knight.jpg http://www.cardforge.org/fpics/tokens/w_1_1_knight.jpg [ALL] Errand of Duty

View File

@@ -113,8 +113,14 @@ public class Card extends GameEntity implements Comparable<Card> {
// equipping size will always be 0 or 1
// if this card is of the type equipment, what card is it currently equipping?
private ArrayList<Card> equipping = new ArrayList<Card>();
// which auras enchanted this card?
// which fortification cards are fortifying this card?
private ArrayList<Card> fortifiedBy = new ArrayList<Card>();
// fortifying size will always be 0 or 1
// if this card is of the type fortification, what card is it currently fortifying?
private ArrayList<Card> fortifying = new ArrayList<Card>();
// which auras enchanted this card?
// if this card is an Aura, what Entity is it enchanting?
private GameEntity enchanting = null;
@@ -2153,7 +2159,7 @@ public class Card extends GameEntity implements Comparable<Card> {
sbLong.append("with another unpaired creature when either ");
sbLong.append("enters the battlefield. They remain paired for ");
sbLong.append("as long as you control both of them)");
} else if (keyword.startsWith("Equip")) {
} else if (keyword.startsWith("Equip") || keyword.startsWith("Fortification")) {
// keyword parsing takes care of adding a proper description
continue;
} else {
@@ -3042,6 +3048,17 @@ public class Card extends GameEntity implements Comparable<Card> {
return this.equippedBy;
}
/**
* <p>
* Getter for the field <code>fortifiedBy</code>.
* </p>
*
* @return a {@link java.util.ArrayList} object.
*/
public final ArrayList<Card> getFortifiedBy() {
return this.fortifiedBy;
}
/**
* <p>
* Setter for the field <code>equippedBy</code>.
@@ -3054,6 +3071,18 @@ public class Card extends GameEntity implements Comparable<Card> {
this.equippedBy = list;
}
/**
* <p>
* Setter for the field <code>fortifiedBy</code>.
* </p>
*
* @param list
* a {@link java.util.ArrayList} object.
*/
public final void setFortifiedBy(final ArrayList<Card> list) {
this.fortifiedBy = list;
}
/**
* <p>
* Getter for the field <code>equipping</code>.
@@ -3065,6 +3094,17 @@ public class Card extends GameEntity implements Comparable<Card> {
return this.equipping;
}
/**
* <p>
* Getter for the field <code>fortifying</code>.
* </p>
*
* @return a {@link java.util.ArrayList} object.
*/
public final ArrayList<Card> getFortifying() {
return this.fortifying;
}
/**
* <p>
* getEquippingCard.
@@ -3079,6 +3119,20 @@ public class Card extends GameEntity implements Comparable<Card> {
return this.equipping.get(0);
}
/**
* <p>
* getFortifyingCard.
* </p>
*
* @return a {@link forge.Card} object.
*/
public final Card getFortifyingCard() {
if (this.fortifying.isEmpty()) {
return null;
}
return this.fortifying.get(0);
}
/**
* <p>
* Setter for the field <code>equipping</code>.
@@ -3091,6 +3145,18 @@ public class Card extends GameEntity implements Comparable<Card> {
this.equipping = list;
}
/**
* <p>
* Setter for the field <code>fortifying</code>.
* </p>
*
* @param list
* a {@link java.util.ArrayList} object.
*/
public final void setFortifying(final ArrayList<Card> list) {
this.fortifying = list;
}
/**
* <p>
* isEquipped.
@@ -3102,6 +3168,17 @@ public class Card extends GameEntity implements Comparable<Card> {
return !this.equippedBy.isEmpty();
}
/**
* <p>
* isFortified.
* </p>
*
* @return a boolean.
*/
public final boolean isFortified() {
return !this.fortifiedBy.isEmpty();
}
/**
* <p>
* isEquipping.
@@ -3113,6 +3190,17 @@ public class Card extends GameEntity implements Comparable<Card> {
return this.equipping.size() != 0;
}
/**
* <p>
* isFortifying.
* </p>
*
* @return a boolean.
*/
public final boolean isFortifying() {
return !this.fortifying.isEmpty();
}
/**
* <p>
* addEquippedBy.
@@ -3126,6 +3214,19 @@ public class Card extends GameEntity implements Comparable<Card> {
this.updateObservers();
}
/**
* <p>
* addFortifiedBy.
* </p>
*
* @param c
* a {@link forge.Card} object.
*/
public final void addFortifiedBy(final Card c) {
this.fortifiedBy.add(c);
this.updateObservers();
}
/**
* <p>
* removeEquippedBy.
@@ -3139,6 +3240,19 @@ public class Card extends GameEntity implements Comparable<Card> {
this.updateObservers();
}
/**
* <p>
* removeFortifiedBy.
* </p>
*
* @param c
* a {@link forge.Card} object.
*/
public final void removeFortifiedBy(final Card c) {
this.fortifiedBy.remove(c);
this.updateObservers();
}
/**
* <p>
* addEquipping.
@@ -3153,6 +3267,33 @@ public class Card extends GameEntity implements Comparable<Card> {
this.updateObservers();
}
/**
* <p>
* addFortifying.
* </p>
*
* @param c
* a {@link forge.Card} object.
*/
public final void addFortifying(final Card c) {
this.fortifying.add(c);
this.setTimestamp(getGame().getNextTimestamp());
this.updateObservers();
}
/**
* <p>
* removeFortifying.
* </p>
*
* @param c
* a {@link forge.Card} object.
*/
public final void removeFortifying(final Card c) {
this.fortifying.remove(c);
this.updateObservers();
}
/**
* <p>
* removeEquipping.
@@ -3205,6 +3346,31 @@ public class Card extends GameEntity implements Comparable<Card> {
this.getController().getGame().getTriggerHandler().runTrigger(TriggerType.Attached, runParams, false);
}
/**
* <p>
* fortifyCard.
* </p>
* fortification.fortifyCard(cardToBeFortified)
*
* @param c
* a {@link forge.Card} object.
*/
public final void fortifyCard(final Card c) {
if (this.isFortifying()) {
this.unFortifyCard(this.getFortifying().get(0));
}
this.addFortifying(c);
c.addFortifiedBy(this);
// Play the Equip sound
getGame().fireEvent(new GameEventCardEquipped());
// run trigger
final HashMap<String, Object> runParams = new HashMap<String, Object>();
runParams.put("AttachSource", this);
runParams.put("AttachTarget", c);
this.getController().getGame().getTriggerHandler().runTrigger(TriggerType.Attached, runParams, false);
}
/**
* <p>
* unEquipCard.
@@ -3225,6 +3391,19 @@ public class Card extends GameEntity implements Comparable<Card> {
getGame().getTriggerHandler().runTrigger(TriggerType.Unequip, runParams, false);
}
/**
* <p>
* unFortifyCard.
* </p>
*
* @param c
* a {@link forge.Card} object.
*/
public final void unFortifyCard(final Card c) { // fortification.unEquipCard(fortifiedCard);
this.fortifying.remove(c);
c.removeFortifiedBy(this);
}
/**
* <p>
* unEquipAllCards.
@@ -4542,6 +4721,7 @@ public class Card extends GameEntity implements Comparable<Card> {
public final boolean isCreature() { return this.typeContains("Creature"); }
public final boolean isArtifact() { return this.typeContains("Artifact"); }
public final boolean isEquipment() { return this.typeContains("Equipment"); }
public final boolean isFortification() { return this.typeContains("Fortification"); }
public final boolean isScheme() { return this.typeContains("Scheme"); }
@@ -4802,6 +4982,12 @@ public class Card extends GameEntity implements Comparable<Card> {
}
}
for (final Card f : this.getFortifiedBy()) {
if (f.isPhasedOut() == phasingIn) {
f.phase(false);
}
}
for (final Card aura : this.getEnchantedBy()) {
if (aura.isPhasedOut() == phasingIn) {
aura.phase(false);
@@ -5319,11 +5505,11 @@ public class Card extends GameEntity implements Comparable<Card> {
return false;
}
} else if (property.startsWith("AttachedBy")) {
if (!this.equippedBy.contains(source) && !this.getEnchantedBy().contains(source)) {
if (!this.equippedBy.contains(source) && !this.getEnchantedBy().contains(source) && !this.getFortifiedBy().contains(source)) {
return false;
}
} else if (property.equals("Attached")) {
if (!this.equipping.contains(source) && !source.equals(this.enchanting)) {
if (!this.equipping.contains(source) && !source.equals(this.enchanting) && !this.fortifying.contains(source)) {
return false;
}
} else if (property.startsWith("AttachedTo")) {
@@ -5351,8 +5537,8 @@ public class Card extends GameEntity implements Comparable<Card> {
}
} else {
if (((this.enchanting == null) || !this.enchanting.isValid(restriction, sourceController, source))
&& (this.equipping.isEmpty() || !this.equipping.get(0).isValid(restriction, sourceController,
source))) {
&& (this.equipping.isEmpty() || !this.equipping.get(0).isValid(restriction, sourceController, source))
&& (this.fortifying.isEmpty() || !this.fortifying.get(0).isValid(restriction, sourceController, source))) {
return false;
}
}
@@ -5369,7 +5555,7 @@ public class Card extends GameEntity implements Comparable<Card> {
}
}
} else if (property.equals("NotAttachedTo")) {
if (this.equipping.contains(source) || source.equals(this.enchanting)) {
if (this.equipping.contains(source) || source.equals(this.enchanting) || this.fortifying.contains(source)) {
return false;
}
} else if (property.startsWith("EnchantedBy")) {
@@ -5477,6 +5663,10 @@ public class Card extends GameEntity implements Comparable<Card> {
return false;
}
}
} else if (property.startsWith("FortifiedBy")) {
if (!this.fortifiedBy.contains(source)) {
return false;
}
} else if (property.startsWith("CanBeEquippedBy")) {
if (!this.canBeEquippedBy(source)) {
return false;
@@ -5485,6 +5675,10 @@ public class Card extends GameEntity implements Comparable<Card> {
if (!this.equipping.contains(source)) {
return false;
}
} else if (property.startsWith("Fortified")) {
if (!this.fortifying.contains(source)) {
return false;
}
} else if (property.startsWith("HauntedBy")) {
if (!this.hauntedBy.contains(source)) {
return false;

View File

@@ -220,6 +220,15 @@ public final class CardPredicates {
return c.isEquipment();
}
};
/**
* a Predicate<Card> to get all fortification.
*/
public static final Predicate<Card> Fortification = new Predicate<Card>() {
@Override
public boolean apply(Card c) {
return c.isFortification();
}
};
/**
* a Predicate<Card> to get all unenchanted cards in a list.
*/

View File

@@ -147,6 +147,8 @@ public final class CardUtil {
newCopy.setEnchantedBy(new ArrayList<Card> (in.getEnchantedBy()));
newCopy.setEquipping(new ArrayList<Card> (in.getEquipping()));
newCopy.setEquippedBy(new ArrayList<Card> (in.getEquippedBy()));
newCopy.setFortifying(new ArrayList<Card> (in.getFortifying()));
newCopy.setFortifiedBy(new ArrayList<Card> (in.getFortifiedBy()));
newCopy.setClones(in.getClones());
newCopy.setHaunting(in.getHaunting());
for (final Card haunter : in.getHauntedBy()) {

View File

@@ -93,8 +93,8 @@ public class AttachEffect extends SpellAbilityEffect {
handleAura(card, c);
} else if (card.isEquipment()) {
card.equipCard(c);
// else if (card.isFortification())
// card.fortifyCard(c);
} else if (card.isFortification()) {
card.fortifyCard(c);
}
} else if (o instanceof Player) {
// Currently, a few cards can enchant players

View File

@@ -481,12 +481,18 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
tgtC.removeEnchanting(oldEnchanted);
}
tgtC.enchantEntity(attachedTo);
} else { //Equipment
} else if (tgtC.isEquipment()) { //Equipment
if (tgtC.isEquipping()) {
final Card oldEquiped = tgtC.getEquippingCard();
tgtC.removeEquipping(oldEquiped);
}
tgtC.equipCard(attachedTo);
} else { // fortification
if (tgtC.isFortifying()) {
final Card oldFortified = tgtC.getFortifyingCard();
tgtC.removeFortifying(oldFortified);
}
tgtC.fortifyCard(attachedTo);
}
} else { // When it should enter the battlefield attached to an illegal permanent it fails
continue;
@@ -815,12 +821,18 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
c.removeEnchanting(oldEnchanted);
}
c.enchantEntity(attachedTo);
} else { //Equipment
} else if (c.isEquipment()) { //Equipment
if (c.isEquipping()) {
final Card oldEquiped = c.getEquippingCard();
c.removeEquipping(oldEquiped);
}
c.equipCard(attachedTo);
} else {
if (c.isFortifying()) {
final Card oldFortified = c.getFortifyingCard();
c.removeFortifying(oldFortified);
}
c.fortifyCard(attachedTo);
}
} else { // When it should enter the battlefield attached to an illegal permanent it fails
continue;

View File

@@ -235,8 +235,14 @@ public class CopyPermanentEffect extends SpellAbilityEffect {
} else {//can't enchant
continue;
}
} else { //Equipment
copy.equipCard(attachedTo);
} else if (copy.isEquipment()) { //Equipment
if (attachedTo.canBeEquippedBy(copy)) {
copy.equipCard(attachedTo);
} else {
continue;
}
} else { // Fortification
copy.fortifyCard(attachedTo);
}
} else {
continue;

View File

@@ -26,7 +26,10 @@ public class UnattachAllEffect extends SpellAbilityEffect {
if (cardToUnattach.isEquipping() && c.getEquippedBy().contains(cardToUnattach)) {
cardToUnattach.unEquipCard(cardToUnattach.getEquipping().get(0));
}
//TODO - unfortify would also be handled here
} else if (cardToUnattach.isFortification()) {
if (cardToUnattach.isFortifying() && c.getFortifiedBy().contains(cardToUnattach)) {
cardToUnattach.unFortifyCard(cardToUnattach.getFortifying().get(0));
}
}
} else if (o instanceof Player) {
final Player p = (Player) o;

View File

@@ -107,6 +107,8 @@ public class CardFactory {
// I'm not sure if we really should be copying enchant/equip stuff over.
out.setEquipping(in.getEquipping());
out.setEquippedBy(in.getEquippedBy());
out.setFortifying(in.getFortifying());
out.setFortifiedBy(in.getFortifiedBy());
out.setEnchantedBy(in.getEnchantedBy());
out.setEnchanting(in.getEnchanting());
out.setClones(in.getClones());

View File

@@ -2598,6 +2598,35 @@ public class CardFactoryUtil {
card.getUnparsedAbilities().add(abilityStr.toString());
}
if (card.hasStartOfKeyword("Fortify")) {
final int equipPos = card.getKeywordPosition("Fortify");
final String equipString = card.getKeyword().get(equipPos).substring(7);
final String[] equipExtras = equipString.contains("\\|") ? equipString.split("\\|", 2) : null;
// Get cost string
String equipCost = "";
if (equipExtras != null) {
equipCost = equipExtras[0].trim();
} else {
equipCost = equipString.trim();
}
// Create attach ability string
final StringBuilder abilityStr = new StringBuilder();
abilityStr.append("AB$ Attach | Cost$ ");
abilityStr.append(equipCost);
abilityStr.append(" | ValidTgts$ Land.YouCtrl | TgtPrompt$ Select target land you control ");
abilityStr.append("| SorcerySpeed$ True | AILogic$ Pump | IsPresent$ Card.Self+nonCreature ");
if (equipExtras != null) {
abilityStr.append("| ").append(equipExtras[1]).append(" ");
}
abilityStr.append("| PrecostDesc$ Fortify | SpellDescription$ (Attach to target land you control. Fortify only as a sorcery.)");
// instantiate attach ability
final SpellAbility sa = AbilityFactory.getAbility(abilityStr.toString(), card);
card.addSpellAbility(sa);
// add ability to instrinic strings so copies/clones create the ability also
card.getUnparsedAbilities().add(abilityStr.toString());
}
setupEtbKeywords(card);
}

View File

@@ -278,12 +278,12 @@ public class GameAction {
}
}
}
// Handle unequipping creatures
if (copied.isEquipped()) {
final List<Card> equipments = new ArrayList<Card>(copied.getEquippedBy());
for (final Card equipment : equipments) {
if (equipment.isInPlay()) {
equipment.unEquipCard(copied);
// Handle unfortifying lands
if (copied.isFortified()) {
final List<Card> fortifications = new ArrayList<Card>(copied.getFortifiedBy());
for (final Card f : fortifications) {
if (f.isInPlay()) {
f.unFortifyCard(copied);
}
}
}
@@ -294,6 +294,13 @@ public class GameAction {
copied.unEquipCard(equippedCreature);
}
}
// fortifications moving off battlefield
if (copied.isFortifying()) {
final Card fortifiedLand = copied.getFortifying().get(0);
if (fortifiedLand.isInPlay()) {
copied.unFortifyCard(fortifiedLand);
}
}
// remove enchantments from creatures
if (copied.isEnchanted()) {
final List<Card> auras = new ArrayList<Card>(copied.getEnchantedBy());
@@ -888,6 +895,16 @@ public class GameAction {
}
} // if isEquipped()
if (c.isFortified()) {
final List<Card> fortifications = new ArrayList<Card>(c.getFortifiedBy());
for (final Card f : fortifications) {
if (!f.isInPlay()) {
f.unFortifyCard(c);
checkAgain = true;
}
}
} // if isFortified()
if (c.isEquipping()) {
final Card equippedCreature = c.getEquipping().get(0);
if (!equippedCreature.isCreature() || !equippedCreature.isInPlay()
@@ -902,6 +919,19 @@ public class GameAction {
}
} // if isEquipping()
if (c.isFortifying()) {
final Card fortifiedLand = c.getFortifying().get(0);
if (!fortifiedLand.isLand() || !fortifiedLand.isInPlay()) {
c.unFortifyCard(fortifiedLand);
checkAgain = true;
}
// make sure any fortification that has become a creature stops fortifying
if (c.isCreature()) {
c.unFortifyCard(fortifiedLand);
checkAgain = true;
}
} // if isFortifying()
if (c.isAura()) {
// Check if Card Aura is attached to is a legal target
final GameEntity entity = c.getEnchanting();

View File

@@ -473,6 +473,8 @@ public class Combat {
attacker = source.getEnchantingCard();
} else if (source.isEquipment()) {
attacker = source.getEquippingCard();
} else if (source.isFortification()) {
attacker = source.getFortifyingCard();
}
// return the corresponding defender

View File

@@ -303,8 +303,11 @@ public class Untap extends Phase {
if (list.contains(c.getEquippingCard())) {
continue;
}
} else if (c.isFortification() && c.isFortifying()) {
if (list.contains(c.getFortifyingCard())) {
continue;
}
}
// TODO: Fortification
c.phase();
}
}

View File

@@ -128,8 +128,10 @@ public enum TargetingOverlay {
Card enchanting = c.getEnchantingCard();
Card equipping = c.getEquippingCard();
Card fortifying = c.getFortifyingCard();
List<Card> enchantedBy = c.getEnchantedBy();
List<Card> equippedBy = c.getEquippedBy();
List<Card> fortifiedBy = c.getFortifiedBy();
Card paired = c.getPairedWith();
if (null != enchanting) {
@@ -150,6 +152,15 @@ public enum TargetingOverlay {
}
}
if (null != fortifying) {
if (!fortifying.getController().equals(c.getController())) {
arcs.add(new Point[] {
endpoints.get(fortifying.getUniqueNumber()),
endpoints.get(c.getUniqueNumber())
});
}
}
if (null != enchantedBy) {
for (Card enc : enchantedBy) {
if (!enc.getController().equals(c.getController())) {
@@ -172,6 +183,17 @@ public enum TargetingOverlay {
}
}
if (null != fortifiedBy) {
for (Card eq : fortifiedBy) {
if (!eq.getController().equals(c.getController())) {
arcs.add(new Point[] {
endpoints.get(c.getUniqueNumber()),
endpoints.get(eq.getUniqueNumber())
});
}
}
}
if (null != paired) {
arcs.add(new Point[] {
endpoints.get(paired.getUniqueNumber()),

View File

@@ -590,10 +590,22 @@ public class PlayArea extends CardPanelContainer implements CardPanelMouseListen
}
}
if (card.isFortified()) {
final ArrayList<Card> fortifications = card.getFortifiedBy();
for (final Card e : fortifications) {
final forge.view.arcane.CardPanel cardE = getCardPanel(e.getUniqueNumber());
if (cardE != null) {
toPanel.getAttachedPanels().add(cardE);
}
}
}
if (card.isEnchantingCard()) {
toPanel.setAttachedToPanel(getCardPanel(card.getEnchantingCard().getUniqueNumber()));
} else if (card.isEquipping()) {
toPanel.setAttachedToPanel(getCardPanel(card.getEquipping().get(0).getUniqueNumber()));
} else if (card.isFortifying()) {
toPanel.setAttachedToPanel(getCardPanel(card.getFortifying().get(0).getUniqueNumber()));
} else {
toPanel.setAttachedToPanel(null);
}