diff --git a/.gitattributes b/.gitattributes index 768cb14de29..d2879b36b47 100644 --- a/.gitattributes +++ b/.gitattributes @@ -355,6 +355,7 @@ src/com/cloudgarden/layout/AnchorLayout.java -text svneol=native#text/plain src/com/esotericsoftware/minlog/Log.java svneol=native#text/plain src/forge/Ability.java svneol=native#text/plain src/forge/Ability_Activated.java svneol=native#text/plain +src/forge/Ability_Cost.java -text svneol=native#text/plain src/forge/Ability_Hand.java svneol=native#text/plain src/forge/Ability_Mana.java -text svneol=native#text/plain src/forge/Ability_Reflected_Mana.java svneol=native#text/plain diff --git a/res/card-pictures.txt b/res/card-pictures.txt index 82a942d2fce..6f20fdd25de 100644 --- a/res/card-pictures.txt +++ b/res/card-pictures.txt @@ -3855,4 +3855,16 @@ caustic_rain.jpg http://www.wizards.com/global/images/magic/general/caustic_rai erase.jpg http://www.wizards.com/global/images/magic/general/erase.jpg ionas_judgment.jpg http://www.wizards.com/global/images/magic/general/ionas_judgment.jpg wipe_clean.jpg http://www.wizards.com/global/images/magic/general/wipe_clean.jpg -deja_vu.jpg http://serv3.tcgimages.eu/img/cards/Portal/deja_vu.jpg \ No newline at end of file +deja_vu.jpg http://serv3.tcgimages.eu/img/cards/Portal/deja_vu.jpg +unyaro_bees.jpg http://www.wizards.com/global/images/magic/general/unyaro_bees.jpg +ticking_gnomes.jpg http://www.wizards.com/global/images/magic/general/ticking_gnomes.jpg +shock_troops.jpg http://www.wizards.com/global/images/magic/general/shock_troops.jpg +ember_hauler.jpg http://www.wizards.com/global/images/magic/general/ember_hauler.jpg +aeolipile.jpg http://www.wizards.com/global/images/magic/general/aeolipile.jpg +blasting_station.jpg http://www.wizards.com/global/images/magic/general/blasting_station.jpg +blood_rites.jpg http://www.wizards.com/global/images/magic/general/blood_rites.jpg +keldon_necropolis.jpg http://www.wizards.com/global/images/magic/general/keldon_necropolis.jpg +orcish_bloodpainter.jpg http://www.wizards.com/global/images/magic/general/orcish_bloodpainter.jpg +orcish_mechanics.jpg http://www.wizards.com/global/images/magic/general/orcish_mechanics.jpg +scorched_rusalka.jpg http://www.wizards.com/global/images/magic/general/scorched_rusalka.jpg +tar_pitcher.jpg http://www.wizards.com/global/images/magic/general/tar_pitcher.jpg diff --git a/res/cards.txt b/res/cards.txt index 25c5da0cd77..2d0c8ec78bc 100644 --- a/res/cards.txt +++ b/res/cards.txt @@ -1,3 +1,40 @@ +Unyaro Bees +G G G +Creature Insect +no text +0/1 +Flying +abPump G:+1/+1 +abDamageTgtCP 3 G Sac-CARDNAME:2 + +Ticking Gnomes +3 +Artifact Creature Gnome +no text +3/3 +Echo:3 +abDamageTgtCP 0 Sac-CARDNAME:1 + +Shock Troops +3 R +Creature Human Soldier +no text +2/2 +abDamageTgtCP 0 Sac-CARDNAME:2 + +Ember Hauler +R R +Creature Goblin +no text +2/2 +abDamageTgtCP 1 Sac-CARDNAME:2 + +Aeolipile +2 +Artifact +no text +abDamageTgtCP 1 T Sac-CARDNAME:2 + Blasting Station 3 Artifact diff --git a/res/common.txt b/res/common.txt index e32d6e64c4a..2f448902c45 100644 --- a/res/common.txt +++ b/res/common.txt @@ -1734,3 +1734,7 @@ Sage's Knowledge Erase Iona's Judgment Wipe Clean +Shock Troops +Aeolipile +Orcish Bloodpainter +Orcish Mechanics diff --git a/res/quest/common.txt b/res/quest/common.txt index e32d6e64c4a..2f448902c45 100644 --- a/res/quest/common.txt +++ b/res/quest/common.txt @@ -1734,3 +1734,7 @@ Sage's Knowledge Erase Iona's Judgment Wipe Clean +Shock Troops +Aeolipile +Orcish Bloodpainter +Orcish Mechanics diff --git a/res/quest/rare.txt b/res/quest/rare.txt index 556539aa408..5da2232fca3 100644 --- a/res/quest/rare.txt +++ b/res/quest/rare.txt @@ -1004,3 +1004,5 @@ Battle Squadron Need for Speed Megatog Auratog +Unyaro Bees +Keldon Necropolis diff --git a/res/quest/uncommon.txt b/res/quest/uncommon.txt index 327ded62a22..17cfd3fe1f9 100644 --- a/res/quest/uncommon.txt +++ b/res/quest/uncommon.txt @@ -1068,3 +1068,9 @@ Lithatog Foratog Altar's Light Caustic Rain +Ticking Gnomes +Ember Hauler +Blasting Station +Blood Rites +Scorched Rusalka +Tar Pitcher diff --git a/res/rare.txt b/res/rare.txt index 556539aa408..5da2232fca3 100644 --- a/res/rare.txt +++ b/res/rare.txt @@ -1004,3 +1004,5 @@ Battle Squadron Need for Speed Megatog Auratog +Unyaro Bees +Keldon Necropolis diff --git a/res/uncommon.txt b/res/uncommon.txt index 327ded62a22..17cfd3fe1f9 100644 --- a/res/uncommon.txt +++ b/res/uncommon.txt @@ -1068,3 +1068,9 @@ Lithatog Foratog Altar's Light Caustic Rain +Ticking Gnomes +Ember Hauler +Blasting Station +Blood Rites +Scorched Rusalka +Tar Pitcher diff --git a/src/forge/Ability_Cost.java b/src/forge/Ability_Cost.java new file mode 100644 index 00000000000..38b9ae85d15 --- /dev/null +++ b/src/forge/Ability_Cost.java @@ -0,0 +1,102 @@ +package forge; + +public class Ability_Cost { + private boolean sacCost = false; + public boolean getSacCost() { return sacCost; } + private String sacType = ""; // or CARDNAME + public String getSacType() { return sacType; } + private boolean sacThis = false; + public boolean getSacThis() { return sacThis; } + + private boolean tapCost = false; + public boolean getTap() { return tapCost; } + + // future expansion of Ability_Cost class: untap, and lifeCost + // private boolean untapCost = false; + + private boolean lifeCost = false; + private int lifeAmount = 0; + + public boolean hasNoManaCost() { return manaCost.equals("") || manaCost.equals("0"); }; + private String manaCost = ""; + public String getMana() { return manaCost; } + + private String name; + + public Ability_Cost(String parse, String cardName) + { + name = cardName; + if(parse.contains("Sac-")) { + sacCost = true; + int sacPos = parse.indexOf("Sac-"); + sacType = parse.substring(sacPos).replace("Sac-", "").trim(); + sacThis = (sacType.equals("CARDNAME")); + parse = parse.substring(0,sacPos-1).trim(); + } + + if(parse.contains("T")) { + tapCost = true; + parse = parse.replace("T", ""); + parse = parse.trim(); + } + manaCost = parse.trim(); + if (manaCost == "") + manaCost = "0"; + } + + public String toString() + { + StringBuilder cost = new StringBuilder(); + boolean caps = true; + if (!(manaCost.equals("0") || manaCost.equals(""))){ + cost.append(manaCost); + caps = false; + } + + if (tapCost){ + if (caps) + cost.append("Tap"); + else + cost.append(", tap"); + } + + if (lifeCost){ + if (caps) + cost.append("Pay "); + else + cost.append(", Pay"); + cost.append(lifeAmount); + } + + cost.append(sacString(caps)); + + cost.append(": "); + return cost.toString(); + } + + public String sacString(boolean caps) + { + StringBuilder cost = new StringBuilder(); + if (sacCost){ + if (caps) + cost.append("Sacrifice "); + else + cost.append(", Sacrifice "); + + if (sacType.equals("CARDNAME")) + cost.append(name); + else{ + String part; + String firstLetter = sacType.substring(0, 0); + if (firstLetter.equalsIgnoreCase("a") || firstLetter.equalsIgnoreCase("e") || firstLetter.equalsIgnoreCase("i") + || firstLetter.equalsIgnoreCase("o") || firstLetter.equalsIgnoreCase("u")) + part = "an"; + part = "a"; + cost.append(part + " "); + cost.append(sacType); + } + } + return cost.toString(); + } + +} diff --git a/src/forge/CardFactory.java b/src/forge/CardFactory.java index 87d97da2497..70989edc49c 100644 --- a/src/forge/CardFactory.java +++ b/src/forge/CardFactory.java @@ -951,30 +951,7 @@ public class CardFactory implements NewConstants { if(Tgt[0]) tmpCost = k[0].substring(9); else tmpCost = k[0].substring(6); - final boolean sacCost[] = {false}; - boolean sacFirstCost = false; - final String sacType[] = {""}; - boolean sacThis = false; - - if(tmpCost.contains("Sac-")) { - sacCost[0] = true; - int sacPos = tmpCost.indexOf("Sac-"); - sacType[0] = tmpCost.substring(sacPos).replace("Sac-", "").trim(); - sacThis = (sacType[0].equals("CARDNAME")); - tmpCost = tmpCost.substring(0,sacPos-1).trim(); - sacFirstCost = (tmpCost.length() == 0); - } - - boolean tapCost = false; - boolean tapFirstCost = false; - - if(tmpCost.contains("T")) { - tapCost = true; - tmpCost = tmpCost.replace("T", ""); - tmpCost = tmpCost.trim(); - tapFirstCost = tmpCost.length() == 0; - } - final String manaCost = tmpCost.trim(); + final Ability_Cost abCost = new Ability_Cost(tmpCost, card.getName()); final int NumAttack[] = {-1138}; final String AttackX[] = {"none"}; @@ -1111,33 +1088,13 @@ public class CardFactory implements NewConstants { } if(!d.equals("none")) { - StringBuilder abCost = new StringBuilder(); - abCost.append(manaCost); - if (tapCost){ - if (tapFirstCost) - abCost.append("T"); - else - abCost.append(", t"); - abCost.append("ap"); - } - if (sacCost[0]){ - if (sacFirstCost) - abCost.append("S"); - else - abCost.append(", s"); - abCost.append("acrifice "); - if (!sacThis) - abCost.append("a "); - abCost.append(sacType[0]); - } - abCost.append(": "); - - spDesc[0] = abCost + d; + spDesc[0] = abCost.toString() + d; stDesc[0] = d; } - if(!tapCost) { - final SpellAbility ability = new Ability_Activated(card, manaCost) { + // start ability here: + if(!abCost.getTap()) { + final SpellAbility ability = new Ability_Activated(card, abCost.getMana()) { private static final long serialVersionUID = -1118592153328758083L; private int defense; @@ -1161,7 +1118,7 @@ public class CardFactory implements NewConstants { @Override public boolean canPlayAI() { - if (sacCost[0]) return false; + if (abCost.getSacCost()) return false; defense = getNumDefense(); keyword = Keyword[0]; @@ -1226,7 +1183,7 @@ public class CardFactory implements NewConstants { return false; } }); - if (sacCost[0] && sacType[0].equals("CARDNAME")) // if sacrifice , don't self-target + if (abCost.getSacCost() && abCost.getSacThis()) // if sacrifice , don't self-target list.remove(card); return list; }//getCreatures() @@ -1286,15 +1243,15 @@ public class CardFactory implements NewConstants { if(Tgt[0] == true) ability.setBeforePayMana(CardFactoryUtil.input_targetCreature(ability)); else ability.setTargetCard(card); - if(sacCost[0]){ - if (sacType[0].equals("CARDNAME")) + if(abCost.getSacCost()){ + if (abCost.getSacThis()) ability.setAfterPayMana(CardFactoryUtil.input_sacrificeThis(ability)); else - ability.setAfterPayMana(CardFactoryUtil.input_sacrificeType(ability, sacType[0], "Sacrifice a "+sacType[0])); + ability.setAfterPayMana(CardFactoryUtil.input_sacrificeType(ability, abCost.getSacType(), abCost.sacString(true))); } card.addSpellAbility(ability); } - if(tapCost) { + else{ final SpellAbility ability = new Ability_Tap(card) { private static final long serialVersionUID = 5252594757468128739L; @@ -1319,7 +1276,7 @@ public class CardFactory implements NewConstants { @Override public boolean canPlayAI() { - if (sacCost[0]) return false; + if (abCost.getSacCost()) return false; defense = getNumDefense(); keyword = Keyword[0]; @@ -1428,14 +1385,14 @@ public class CardFactory implements NewConstants { if(Tgt[0] == true) ability.setBeforePayMana(CardFactoryUtil.input_targetCreature(ability)); else ability.setTargetCard(card); - if(sacCost[0]){ - if (sacType[0].equals("CARDNAME") || sacType[0].equals(card.getName())) + if(abCost.getSacCost()){ + if (abCost.getSacThis()) ability.setAfterPayMana(CardFactoryUtil.input_sacrificeThis(ability)); else - ability.setAfterPayMana(CardFactoryUtil.input_sacrificeType(ability, sacType[0], "Sacrifice a "+sacType[0])); + ability.setAfterPayMana(CardFactoryUtil.input_sacrificeType(ability, abCost.getSacType(), abCost.sacString(true))); } - if(!tapFirstCost && !sacFirstCost) ability.setManaCost(manaCost); + if(!abCost.hasNoManaCost()) ability.setManaCost(abCost.getMana()); card.addSpellAbility(ability); } @@ -1734,31 +1691,7 @@ public class CardFactory implements NewConstants { tmpCost = k[0].substring(12); } - final boolean sacCost[] = {false}; - boolean sacFirstCost = false; - final String sacType[] = {""}; - - if(tmpCost.contains("Sac-")) { - sacCost[0] = true; - int sacPos = tmpCost.indexOf("Sac-"); - sacType[0] = tmpCost.substring(sacPos).replace("Sac-", "").trim(); - tmpCost = tmpCost.substring(0,sacPos-1).trim(); - sacFirstCost = (tmpCost.length() == 0); - } - - boolean tapCost = false; - boolean tapFirstCost = false; - - if(tmpCost.contains("T")) { - tapCost = true; - tmpCost = tmpCost.replace("T", ""); - tmpCost = tmpCost.trim(); - tapFirstCost = (tmpCost.length() == 0); - } - - if (tmpCost == "") tmpCost = "0"; // this doesn't seem to do anything - - final String manaCost = tmpCost; + final Ability_Cost abCost = new Ability_Cost(tmpCost, card.getName()); final int NumDmg[] = {-1}; final String NumDmgX[] = {"none"}; @@ -1798,31 +1731,12 @@ public class CardFactory implements NewConstants { stDesc[0] = card.getName() + " -" + sb.toString(); } - StringBuilder abCost = new StringBuilder(); - abCost.append(manaCost); - if (tapCost){ - if (tapFirstCost) - abCost.append("T"); - else - abCost.append(", t"); - abCost.append("ap"); - } - if (sacCost[0]){ - if (sacFirstCost) - abCost.append("S"); - else - abCost.append(", s"); - abCost.append("acrifice a "); - abCost.append(sacType[0]); - } - abCost.append(": "); - - spDesc[0] = abCost + spDesc[0]; + spDesc[0] = abCost.toString() + spDesc[0]; // Damage ability starts here - if(!tapCost) { + if(!abCost.getTap()) { // adDamage starts here - final SpellAbility abDamage = new Ability_Activated(card, manaCost) { + final SpellAbility abDamage = new Ability_Activated(card, abCost.getMana()) { private static final long serialVersionUID = -7560349014757367722L; private int damage; @@ -1886,7 +1800,7 @@ public class CardFactory implements NewConstants { @Override public boolean canPlayAI() { - if (sacCost[0]) return false; + if (abCost.getSacCost()) return false; damage = getNumDamage(); Random r = new Random(); // prevent run-away activations @@ -1953,17 +1867,19 @@ public class CardFactory implements NewConstants { if(TgtCP[0] == true) - abDamage.setBeforePayMana(CardFactoryUtil.input_targetCreaturePlayer(abDamage, true, sacFirstCost)); + abDamage.setBeforePayMana(CardFactoryUtil.input_targetCreaturePlayer(abDamage, true, abCost.hasNoManaCost())); else if(TgtCreature[0] == true) abDamage.setBeforePayMana(CardFactoryUtil.input_targetCreature(abDamage)); else if(TgtPlayer[0] == true) abDamage.setBeforePayMana(CardFactoryUtil.input_targetPlayer(abDamage)); - if (sacCost[0]) - abDamage.setAfterPayMana(CardFactoryUtil.input_sacrificeType(abDamage, sacType[0], "Sacrifice a "+sacType[0])); - + if(abCost.getSacCost()){ + if (abCost.getSacThis()) + abDamage.setAfterPayMana(CardFactoryUtil.input_sacrificeThis(abDamage)); + else + abDamage.setAfterPayMana(CardFactoryUtil.input_sacrificeType(abDamage, abCost.getSacType(), abCost.sacString(true))); + } card.addSpellAbility(abDamage); }//!tapCost - else { //tapCost final SpellAbility abDamage = new Ability_Tap(card) { private static final long serialVersionUID = -7960649024757327722L; @@ -2029,7 +1945,7 @@ public class CardFactory implements NewConstants { @Override public boolean canPlayAI() { - if (sacCost[0]) return false; + if (abCost.getSacCost()) return false; damage = getNumDamage(); boolean na = false; @@ -2098,10 +2014,14 @@ public class CardFactory implements NewConstants { else if(TgtCreature[0] == true) abDamage.setBeforePayMana(CardFactoryUtil.input_targetCreature(abDamage)); else if(TgtPlayer[0] == true) abDamage.setBeforePayMana(CardFactoryUtil.input_targetPlayer(abDamage)); - if (sacCost[0]) - abDamage.setAfterPayMana(CardFactoryUtil.input_sacrificeType(abDamage, sacType[0], "Sacrifice a "+sacType[0])); - - if(!tapFirstCost && !sacFirstCost) abDamage.setManaCost(manaCost); + if(abCost.getSacCost()){ + if (abCost.getSacThis()) + abDamage.setAfterPayMana(CardFactoryUtil.input_sacrificeThis(abDamage)); + else + abDamage.setAfterPayMana(CardFactoryUtil.input_sacrificeType(abDamage, abCost.getSacType(), abCost.sacString(true))); + } + + if(!abCost.hasNoManaCost()) abDamage.setManaCost(abCost.getMana()); card.addSpellAbility(abDamage); }//tapCost