mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 03:08:02 +00:00
- Added support for damage prevention shields with effects.
- Added: Candles' Glow, Temper, Test of Faith and Vengeful Archon
This commit is contained in:
4
.gitattributes
vendored
4
.gitattributes
vendored
@@ -707,6 +707,7 @@ res/cardsfolder/a/azors_elocutors.txt -text
|
||||
res/cardsfolder/a/azure_drake.txt svneol=native#text/plain
|
||||
res/cardsfolder/a/azure_mage.txt svneol=native#text/plain
|
||||
res/cardsfolder/a/azusa_lost_but_seeking.txt svneol=native#text/plain
|
||||
res/cardsfolder/a/vengeful_archon.txt -text
|
||||
res/cardsfolder/b/back_from_the_brink.txt -text
|
||||
res/cardsfolder/b/back_to_basics.txt svneol=native#text/plain
|
||||
res/cardsfolder/b/back_to_nature.txt svneol=native#text/plain
|
||||
@@ -1496,6 +1497,7 @@ res/cardsfolder/c/caltrops.txt svneol=native#text/plain
|
||||
res/cardsfolder/c/camel.txt -text
|
||||
res/cardsfolder/c/cancel.txt svneol=native#text/plain
|
||||
res/cardsfolder/c/candelabra_of_tawnos.txt svneol=native#text/plain
|
||||
res/cardsfolder/c/candles_glow.txt -text
|
||||
res/cardsfolder/c/candles_of_leng.txt -text svneol=unset#text/plain
|
||||
res/cardsfolder/c/canker_abomination.txt svneol=native#text/plain
|
||||
res/cardsfolder/c/cankerous_thirst.txt -text
|
||||
@@ -11142,6 +11144,7 @@ res/cardsfolder/t/telimtors_edict.txt svneol=native#text/plain
|
||||
res/cardsfolder/t/teller_of_tales.txt svneol=native#text/plain
|
||||
res/cardsfolder/t/telling_time.txt svneol=native#text/plain
|
||||
res/cardsfolder/t/tember_city.txt -text
|
||||
res/cardsfolder/t/temper.txt -text
|
||||
res/cardsfolder/t/tempered_steel.txt svneol=native#text/plain
|
||||
res/cardsfolder/t/tempest_drake.txt svneol=native#text/plain
|
||||
res/cardsfolder/t/tempest_of_light.txt svneol=native#text/plain
|
||||
@@ -11197,6 +11200,7 @@ res/cardsfolder/t/territorial_dispute.txt -text
|
||||
res/cardsfolder/t/terror.txt svneol=native#text/plain
|
||||
res/cardsfolder/t/terrus_wurm.txt -text
|
||||
res/cardsfolder/t/test_of_endurance.txt svneol=native#text/plain
|
||||
res/cardsfolder/t/test_of_faith.txt -text
|
||||
res/cardsfolder/t/testament_of_faith.txt svneol=native#text/plain
|
||||
res/cardsfolder/t/tethered_griffin.txt svneol=native#text/plain
|
||||
res/cardsfolder/t/tethered_skirge.txt svneol=native#text/plain
|
||||
|
||||
13
res/cardsfolder/a/vengeful_archon.txt
Normal file
13
res/cardsfolder/a/vengeful_archon.txt
Normal file
@@ -0,0 +1,13 @@
|
||||
Name:Vengeful Archon
|
||||
ManaCost:4 W W W
|
||||
Types:Creature Archon
|
||||
PT:7/7
|
||||
K:Flying
|
||||
A:AB$ Pump | Cost$ X | ValidTgts$ Player | TgtPrompt$ Select target player damaged by shield effect | IsCurse$ True | References$ X | RememberObjects$ Targeted | SubAbility$ ArchonPrevention | StackDescription$ none | SpellDescription$ Prevent the next X damage that would be dealt to you this turn. If damage is prevented this way, CARDNAME deals that much damage to target player.
|
||||
SVar:ArchonPrevention:DB$ PreventDamage | Defined$ You | Amount$ X | References$ X | PreventionSubAbility$ ArchonsVengeance | ShieldEffectTarget$ Remembered | SubAbility$ DBCleanup
|
||||
SVar:ArchonsVengeance:AB$ DealDamage | Cost$ 0 | Defined$ ShieldEffectTarget | NumDmg$ PreventedDamage | SpellDescription$ CARDNAME deals damage to target player for each damage prevented this way.
|
||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||
SVar:X:Count$xPaid
|
||||
SVar:RemAIDeck:True
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/vengeful_archon.jpg
|
||||
Oracle:Flying\n{X}: Prevent the next X damage that would be dealt to you this turn. If damage is prevented this way, Vengeful Archon deals that much damage to target player.
|
||||
8
res/cardsfolder/c/candles_glow.txt
Normal file
8
res/cardsfolder/c/candles_glow.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
Name:Candles' Glow
|
||||
ManaCost:1 W
|
||||
Types:Instant Arcane
|
||||
A:SP$ PreventDamage | Cost$ 1 W | ValidTgts$ Player,Creature | Amount$ 3 | PreventionSubAbility$ GlowOfLife | References$ GlowOfLife | ShieldEffectTarget$ You | TgtPrompt$ Select target creature or player | SpellDescription$ Prevent the next 3 damage that would be dealt to target creature or player this turn. You gain life equal to the damage prevented this way.
|
||||
SVar:GlowOfLife:AB$ GainLife | Cost$ 0 | Defined$ ShieldEffectTarget | LifeAmount$ PreventedDamage | SpellDescription$ You gain life equal to the damage prevented this way.
|
||||
K:Splice onto Arcane 1 W
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/candles_glow.jpg
|
||||
Oracle:Prevent the next 3 damage that would be dealt to target creature or player this turn. You gain life equal to the damage prevented this way.\nSplice onto Arcane {1}{W} (As you cast an Arcane spell, you may reveal this card from your hand and pay its splice cost. If you do, add this card's effects to that spell.)
|
||||
8
res/cardsfolder/t/temper.txt
Normal file
8
res/cardsfolder/t/temper.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
Name:Temper
|
||||
ManaCost:X 1 W
|
||||
Types:Instant
|
||||
A:SP$ PreventDamage | Cost$ X 1 W | ValidTgts$ Creature | Amount$ X | References$ X | PreventionSubAbility$ EvenTemper | ShieldEffectTarget$ Targeted | TgtPrompt$ Select target creature | SpellDescription$ Prevent the next X damage that would be dealt to target creature this turn. For each 1 damage prevented this way, put a +1/+1 counter on that creature.
|
||||
SVar:EvenTemper:AB$ PutCounter | Cost$ 0 | Defined$ ShieldEffectTarget | CounterType$ P1P1 | CounterNum$ PreventedDamage | SpellDescription$ Put a +1/+1 counter on this creature for each 1 damage prevented this way.
|
||||
SVar:X:Count$xPaid
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/temper.jpg
|
||||
Oracle:Prevent the next X damage that would be dealt to target creature this turn. For each 1 damage prevented this way, put a +1/+1 counter on that creature.
|
||||
7
res/cardsfolder/t/test_of_faith.txt
Normal file
7
res/cardsfolder/t/test_of_faith.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
Name:Test of Faith
|
||||
ManaCost:1 W
|
||||
Types:Instant
|
||||
A:SP$ PreventDamage | Cost$ 1 W | ValidTgts$ Creature | Amount$ 3 | PreventionSubAbility$ FaithsReward | ShieldEffectTarget$ Targeted | TgtPrompt$ Select target creature | SpellDescription$ Prevent the next 3 damage that would be dealt to target creature this turn, and put a +1/+1 counter on that creature for each 1 damage prevented this way.
|
||||
SVar:FaithsReward:AB$ PutCounter | Cost$ 0 | Defined$ ShieldEffectTarget | CounterType$ P1P1 | CounterNum$ PreventedDamage | SpellDescription$ Put a +1/+1 counter on this creature for each 1 damage prevented this way.
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/test_of_faith.jpg
|
||||
Oracle:Prevent the next 3 damage that would be dealt to target creature this turn, and put a +1/+1 counter on that creature for each 1 damage prevented this way.
|
||||
@@ -48,6 +48,7 @@ import forge.card.CardRarity;
|
||||
import forge.card.CardRules;
|
||||
import forge.card.ColorSet;
|
||||
import forge.card.MagicColor;
|
||||
import forge.card.ability.AbilityFactory;
|
||||
import forge.card.ability.AbilityUtils;
|
||||
import forge.card.ability.ApiType;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
@@ -7341,6 +7342,66 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
|
||||
int restDamage = damage;
|
||||
|
||||
boolean DEBUGShieldsWithEffects = false;
|
||||
while (!this.getPreventNextDamageWithEffect().isEmpty() && restDamage != 0) {
|
||||
TreeMap<Card, Map<String, String>> shieldMap = this.getPreventNextDamageWithEffect();
|
||||
List<Card> preventionEffectSources = new ArrayList<Card>(shieldMap.keySet());
|
||||
Card shieldSource = preventionEffectSources.get(0);
|
||||
if (preventionEffectSources.size() > 1) {
|
||||
Map<String, Card> choiceMap = new TreeMap<String, Card>();
|
||||
List<String> choices = new ArrayList<String>();
|
||||
for (final Card key : preventionEffectSources) {
|
||||
String effDesc = shieldMap.get(key).get("EffectString");
|
||||
int descIndex = effDesc.indexOf("SpellDescription");
|
||||
effDesc = effDesc.substring(descIndex + 18);
|
||||
String shieldDescription = key.toString() + " - " + shieldMap.get(key).get("ShieldAmount")
|
||||
+ " shields - " + effDesc;
|
||||
choices.add(shieldDescription);
|
||||
choiceMap.put(shieldDescription, key);
|
||||
}
|
||||
shieldSource = this.getController().getController().chooseProtectionShield(this, choices, choiceMap);
|
||||
}
|
||||
if (DEBUGShieldsWithEffects) {
|
||||
System.out.println("Prevention shield source: " + shieldSource);
|
||||
}
|
||||
|
||||
int shieldAmount = Integer.valueOf(shieldMap.get(shieldSource).get("ShieldAmount"));
|
||||
int dmgToBePrevented = Math.min(restDamage, shieldAmount);
|
||||
if (DEBUGShieldsWithEffects) {
|
||||
System.out.println("Selected source initial shield amount: " + shieldAmount);
|
||||
System.out.println("Incoming damage: " + restDamage);
|
||||
System.out.println("Damage to be prevented: " + dmgToBePrevented);
|
||||
}
|
||||
|
||||
//Set up ability
|
||||
SpellAbility shieldSA = null;
|
||||
String effectAbString = shieldMap.get(shieldSource).get("EffectString");
|
||||
effectAbString = effectAbString.replace("PreventedDamage", Integer.toString(dmgToBePrevented));
|
||||
effectAbString = effectAbString.replace("ShieldEffectTarget", shieldMap.get(shieldSource).get("ShieldEffectTarget"));
|
||||
if (DEBUGShieldsWithEffects) {
|
||||
System.out.println("Final shield ability string: " + effectAbString);
|
||||
}
|
||||
shieldSA = AbilityFactory.getAbility(effectAbString, shieldSource);
|
||||
if (shieldSA.usesTargeting()) {
|
||||
System.err.println(shieldSource + " - Targeting for prevention shield's effect should be done with initial spell");
|
||||
}
|
||||
|
||||
if (restDamage >= shieldAmount) {
|
||||
this.getController().getController().playSpellAbilityNoStack(this.getController(), shieldSA);
|
||||
this.subtractPreventNextDamageWithEffect(shieldSource, restDamage);
|
||||
restDamage = restDamage - shieldAmount;
|
||||
} else {
|
||||
this.subtractPreventNextDamageWithEffect(shieldSource, restDamage);
|
||||
this.getController().getController().playSpellAbilityNoStack(this.getController(), shieldSA);
|
||||
restDamage = 0;
|
||||
}
|
||||
if (DEBUGShieldsWithEffects) {
|
||||
System.out.println("Remaining shields: "
|
||||
+ (shieldMap.containsKey(shieldSource) ? shieldMap.get(shieldSource).get("ShieldAmount") : "all shields used"));
|
||||
System.out.println("Remaining damage: " + restDamage);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.getName().equals("Swans of Bryn Argoll")) {
|
||||
source.getController().drawCards(restDamage);
|
||||
return 0;
|
||||
@@ -8228,6 +8289,7 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
public void onCleanupPhase(final Player turn) {
|
||||
setDamage(0);
|
||||
resetPreventNextDamage();
|
||||
resetPreventNextDamageWithEffect();
|
||||
resetReceivedDamageFromThisTurn();
|
||||
resetDealtDamageToThisTurn();
|
||||
resetDealtDamageToPlayerThisTurn();
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
package forge;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import forge.game.Game;
|
||||
import forge.game.player.Player;
|
||||
@@ -34,6 +36,7 @@ import forge.util.MyObservable;
|
||||
public abstract class GameEntity extends MyObservable implements ITargetable {
|
||||
private String name = "";
|
||||
private int preventNextDamage = 0;
|
||||
private TreeMap<Card, Map<String, String>> preventionShieldsWithEffects = new TreeMap<Card, Map<String, String>>();
|
||||
|
||||
/** The enchanted by. */
|
||||
private ArrayList<Card> enchantedBy = new ArrayList<Card>();
|
||||
@@ -255,6 +258,78 @@ public abstract class GameEntity extends MyObservable implements ITargetable {
|
||||
this.preventNextDamage = 0;
|
||||
}
|
||||
|
||||
// PreventNextDamageWithEffect
|
||||
/**
|
||||
* <p>
|
||||
* Gets the map of damage prevention shields with effects.
|
||||
* </p>
|
||||
*
|
||||
* @return the map of damage prevention shields with effects.
|
||||
*/
|
||||
public TreeMap<Card, Map<String, String>> getPreventNextDamageWithEffect() {
|
||||
return this.preventionShieldsWithEffects;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Adds a damage prevention shield with an effect that happens at time of prevention.
|
||||
* </p>
|
||||
*
|
||||
* @param shieldSource The source card which generated the shield
|
||||
* @param effectMap A map of the effect occurring with the damage prevention
|
||||
*/
|
||||
public void addPreventNextDamageWithEffect(final Card shieldSource, TreeMap<String, String> effectMap) {
|
||||
if (this.preventionShieldsWithEffects.containsKey(shieldSource)) {
|
||||
int currentShields = Integer.valueOf(this.preventionShieldsWithEffects.get(shieldSource).get("ShieldAmount"));
|
||||
currentShields += Integer.valueOf(effectMap.get("ShieldAmount"));
|
||||
effectMap.put("ShieldAmount", Integer.toString(currentShields));
|
||||
this.preventionShieldsWithEffects.put(shieldSource, effectMap);
|
||||
} else {
|
||||
this.preventionShieldsWithEffects.put(shieldSource, effectMap);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* subtractPreventNextDamageWithEffect.
|
||||
* </p>
|
||||
*
|
||||
* @param shieldSource The source card which generated the shield
|
||||
* @param n The number of shields to remove originating from shieldSource
|
||||
*/
|
||||
public void subtractPreventNextDamageWithEffect(final Card shieldSource, final int n) {
|
||||
int currentShields = Integer.valueOf(this.preventionShieldsWithEffects.get(shieldSource).get("ShieldAmount"));
|
||||
if (currentShields > n) {
|
||||
this.preventionShieldsWithEffects.get(shieldSource).put("ShieldAmount", String.valueOf(currentShields - n));
|
||||
} else {
|
||||
this.preventionShieldsWithEffects.remove(shieldSource);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* resetPreventNextDamageWithEffect.
|
||||
* </p>
|
||||
*/
|
||||
public void resetPreventNextDamageWithEffect() {
|
||||
this.preventionShieldsWithEffects = new TreeMap<Card, Map<String, String>>();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Gets the total amount of damage prevention shields.
|
||||
* </p>
|
||||
*
|
||||
* @return the number of damage prevention shields with and without effects.
|
||||
*/
|
||||
public int getPreventNextDamageTotalShields() {
|
||||
int shields = this.preventNextDamage;
|
||||
for (final Map<String, String> value : this.preventionShieldsWithEffects.values()) {
|
||||
shields += Integer.valueOf(value.get("ShieldAmount"));
|
||||
}
|
||||
return shields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for keyword.
|
||||
*
|
||||
|
||||
@@ -166,6 +166,10 @@ public final class AbilityFactory {
|
||||
}
|
||||
}
|
||||
|
||||
if (mapParams.containsKey("PreventionSubAbility")) {
|
||||
spellAbility.setSVar(mapParams.get("PreventionSubAbility"), hostCard.getSVar(mapParams.get("PreventionSubAbility")));
|
||||
}
|
||||
|
||||
if (mapParams.containsKey("SubAbility")) {
|
||||
spellAbility.setSubAbility(getSubAbility(hostCard, hostCard.getSVar(mapParams.get("SubAbility"))));
|
||||
}
|
||||
|
||||
@@ -204,6 +204,14 @@ public class AbilityUtils {
|
||||
for (final Card chosen : hostCard.getChosenCard()) {
|
||||
cards.add(game.getCardState(chosen));
|
||||
}
|
||||
}
|
||||
else if (defined.startsWith("CardUID_")) {
|
||||
String idString = defined.substring(8);
|
||||
for (final Card cardByID : game.getCardsInGame()) {
|
||||
if (cardByID.getUniqueNumber() == Integer.valueOf(idString)) {
|
||||
cards.add(game.getCardState(cardByID));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
List<Card> list = null;
|
||||
if (defined.startsWith("Sacrificed")) {
|
||||
@@ -905,6 +913,13 @@ public class AbilityUtils {
|
||||
if (!players.contains(p)) {
|
||||
players.add(p);
|
||||
}
|
||||
} else if (defined.startsWith("PlayerNamed_")) {
|
||||
for (Player p : game.getPlayers()) {
|
||||
System.out.println("Named player " + defined.substring(12));
|
||||
if (p.getName().equals(defined.substring(12))) {
|
||||
players.add(p);
|
||||
}
|
||||
}
|
||||
} else if (defined.startsWith("Flipped")) {
|
||||
for (Player p : game.getPlayers()) {
|
||||
if (null != sa.getSourceCard().getFlipResult(p)) {
|
||||
|
||||
@@ -2,6 +2,7 @@ package forge.card.ability.effects;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import forge.Card;
|
||||
import forge.CardUtil;
|
||||
@@ -86,22 +87,65 @@ public class DamagePreventEffect extends SpellAbilityEffect {
|
||||
}
|
||||
|
||||
final boolean targeted = (sa.usesTargeting());
|
||||
final boolean preventionWithEffect = sa.hasParam("PreventionSubAbility");
|
||||
|
||||
for (final Object o : tgts) {
|
||||
numDam = (sa.usesTargeting() && sa.hasParam("DividedAsYouChoose")) ? sa.getTargetRestrictions().getDividedValue(o) : numDam;
|
||||
if (o instanceof Card) {
|
||||
final Card c = (Card) o;
|
||||
if (c.isInPlay() && (!targeted || c.canBeTargetedBy(sa))) {
|
||||
if (preventionWithEffect) {
|
||||
TreeMap<String, String> effectMap = new TreeMap<String, String>();
|
||||
effectMap.put("EffectString", sa.getSVar(sa.getParam("PreventionSubAbility")));
|
||||
effectMap.put("ShieldAmount", String.valueOf(numDam));
|
||||
if (sa.hasParam("ShieldEffectTarget")) {
|
||||
String effTgtString = "";
|
||||
List<ITargetable> effTgts = new ArrayList<ITargetable>();
|
||||
effTgts = AbilityUtils.getDefinedObjects(host, sa.getParam("ShieldEffectTarget"), sa);
|
||||
for (final Object effTgt : effTgts) {
|
||||
if (effTgt instanceof Card) {
|
||||
effTgtString = String.valueOf(((Card) effTgt).getUniqueNumber());
|
||||
effectMap.put("ShieldEffectTarget", "CardUID_" + effTgtString);
|
||||
} else if (effTgt instanceof Player) {
|
||||
effTgtString = ((Player) effTgt).getName();
|
||||
effectMap.put("ShieldEffectTarget", "PlayerNamed_" + effTgtString);
|
||||
}
|
||||
}
|
||||
}
|
||||
c.addPreventNextDamageWithEffect(host, effectMap);
|
||||
} else {
|
||||
c.addPreventNextDamage(numDam);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (o instanceof Player) {
|
||||
final Player p = (Player) o;
|
||||
if (!targeted || p.canBeTargetedBy(sa)) {
|
||||
if (preventionWithEffect) {
|
||||
TreeMap<String, String> effectMap = new TreeMap<String, String>();
|
||||
effectMap.put("EffectString", sa.getSVar(sa.getParam("PreventionSubAbility")));
|
||||
effectMap.put("ShieldAmount", String.valueOf(numDam));
|
||||
if (sa.hasParam("ShieldEffectTarget")) {
|
||||
String effTgtString = "";
|
||||
List<ITargetable> effTgts = new ArrayList<ITargetable>();
|
||||
effTgts = AbilityUtils.getDefinedObjects(host, sa.getParam("ShieldEffectTarget"), sa);
|
||||
for (final Object effTgt : effTgts) {
|
||||
if (effTgt instanceof Card) {
|
||||
effTgtString = String.valueOf(((Card) effTgt).getUniqueNumber());
|
||||
effectMap.put("ShieldEffectTarget", "CardUID_" + effTgtString);
|
||||
} else if (effTgt instanceof Player) {
|
||||
effTgtString = ((Player) effTgt).getName();
|
||||
effectMap.put("ShieldEffectTarget", "PlayerNamed_" + effTgtString);
|
||||
}
|
||||
}
|
||||
}
|
||||
p.addPreventNextDamageWithEffect(host, effectMap);
|
||||
} else {
|
||||
p.addPreventNextDamage(numDam);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (final Card c : untargetedCards) {
|
||||
if (c.isInPlay()) {
|
||||
|
||||
@@ -240,12 +240,7 @@ public class ReplacementHandler {
|
||||
}
|
||||
|
||||
Player player = replacementEffect.getHostCard().getController();
|
||||
//player.getController().playNoStack()
|
||||
if (player.isHuman()) {
|
||||
HumanPlay.playSpellAbilityNoStack(player, effectSA);
|
||||
} else {
|
||||
ComputerUtil.playNoStack(player, effectSA, game);
|
||||
}
|
||||
player.getController().playSpellAbilityNoStack(player, effectSA);
|
||||
|
||||
return ReplacementResult.Replaced;
|
||||
}
|
||||
|
||||
@@ -1828,10 +1828,10 @@ public class ComputerUtilCombat {
|
||||
* @return a int.
|
||||
*/
|
||||
public final static int getDamageToKill(final Card c) {
|
||||
int killDamage = c.getLethalDamage() + c.getPreventNextDamage();
|
||||
if ((killDamage > c.getPreventNextDamage())
|
||||
int killDamage = c.getLethalDamage() + c.getPreventNextDamageTotalShields();
|
||||
if ((killDamage > c.getPreventNextDamageTotalShields())
|
||||
&& c.hasStartOfKeyword("When CARDNAME is dealt damage, destroy it.")) {
|
||||
killDamage = 1 + c.getPreventNextDamage();
|
||||
killDamage = 1 + c.getPreventNextDamageTotalShields();
|
||||
}
|
||||
|
||||
return killDamage;
|
||||
|
||||
@@ -25,6 +25,7 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
@@ -887,6 +888,66 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
|
||||
int restDamage = damage;
|
||||
|
||||
boolean DEBUGShieldsWithEffects = false;
|
||||
while (!this.getPreventNextDamageWithEffect().isEmpty() && restDamage != 0) {
|
||||
TreeMap<Card, Map<String, String>> shieldMap = this.getPreventNextDamageWithEffect();
|
||||
List<Card> preventionEffectSources = new ArrayList<Card>(shieldMap.keySet());
|
||||
Card shieldSource = preventionEffectSources.get(0);
|
||||
if (preventionEffectSources.size() > 1) {
|
||||
Map<String, Card> choiceMap = new TreeMap<String, Card>();
|
||||
List<String> choices = new ArrayList<String>();
|
||||
for (final Card key : preventionEffectSources) {
|
||||
String effDesc = shieldMap.get(key).get("EffectString");
|
||||
int descIndex = effDesc.indexOf("SpellDescription");
|
||||
effDesc = effDesc.substring(descIndex + 18);
|
||||
String shieldDescription = key.toString() + " - " + shieldMap.get(shieldSource).get("ShieldAmount")
|
||||
+ " shields - " + effDesc;
|
||||
choices.add(shieldDescription);
|
||||
choiceMap.put(shieldDescription, key);
|
||||
}
|
||||
shieldSource = this.getController().chooseProtectionShield(this, choices, choiceMap);
|
||||
}
|
||||
if (DEBUGShieldsWithEffects) {
|
||||
System.out.println("Prevention shield source: " + shieldSource);
|
||||
}
|
||||
|
||||
int shieldAmount = Integer.valueOf(shieldMap.get(shieldSource).get("ShieldAmount"));
|
||||
int dmgToBePrevented = Math.min(restDamage, shieldAmount);
|
||||
if (DEBUGShieldsWithEffects) {
|
||||
System.out.println("Selected source initial shield amount: " + shieldAmount);
|
||||
System.out.println("Incoming damage: " + restDamage);
|
||||
System.out.println("Damage to be prevented: " + dmgToBePrevented);
|
||||
}
|
||||
|
||||
//Set up ability
|
||||
SpellAbility shieldSA = null;
|
||||
String effectAbString = shieldMap.get(shieldSource).get("EffectString");
|
||||
effectAbString = effectAbString.replace("PreventedDamage", Integer.toString(dmgToBePrevented));
|
||||
effectAbString = effectAbString.replace("ShieldEffectTarget", shieldMap.get(shieldSource).get("ShieldEffectTarget"));
|
||||
if (DEBUGShieldsWithEffects) {
|
||||
System.out.println("Final shield ability string: " + effectAbString);
|
||||
}
|
||||
shieldSA = AbilityFactory.getAbility(effectAbString, shieldSource);
|
||||
if (shieldSA.usesTargeting()) {
|
||||
System.err.println(shieldSource + " - Targeting for prevention shield's effect should be done with initial spell");
|
||||
}
|
||||
|
||||
if (restDamage >= shieldAmount) {
|
||||
this.getController().playSpellAbilityNoStack(this, shieldSA);
|
||||
this.subtractPreventNextDamageWithEffect(shieldSource, restDamage);
|
||||
restDamage = restDamage - shieldAmount;
|
||||
} else {
|
||||
this.subtractPreventNextDamageWithEffect(shieldSource, restDamage);
|
||||
this.getController().playSpellAbilityNoStack(this, shieldSA);
|
||||
restDamage = 0;
|
||||
}
|
||||
if (DEBUGShieldsWithEffects) {
|
||||
System.out.println("Remaining shields: "
|
||||
+ (shieldMap.containsKey(shieldSource) ? shieldMap.get(shieldSource).get("ShieldAmount") : "all shields used"));
|
||||
System.out.println("Remaining damage: " + restDamage);
|
||||
}
|
||||
}
|
||||
|
||||
final HashMap<String, Object> repParams = new HashMap<String, Object>();
|
||||
repParams.put("Event", "DamageDone");
|
||||
repParams.put("Affected", this);
|
||||
@@ -2757,6 +2818,7 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
c.setDrawnThisTurn(false);
|
||||
}
|
||||
resetPreventNextDamage();
|
||||
resetPreventNextDamageWithEffect();
|
||||
resetNumDrawnThisTurn();
|
||||
resetNumDiscardedThisTurn();
|
||||
setAttackedWithCreatureThisTurn(false);
|
||||
|
||||
@@ -96,6 +96,7 @@ public abstract class PlayerController {
|
||||
//public abstract void playFromSuspend(Card c);
|
||||
public abstract boolean playCascade(Card cascadedCard, Card sourceCard);
|
||||
public abstract void playSpellAbilityForFree(SpellAbility copySA, boolean mayChoseNewTargets);
|
||||
public abstract void playSpellAbilityNoStack(Player player, SpellAbility effectSA);
|
||||
|
||||
public abstract Deck sideboard(final Deck deck, GameType gameType);
|
||||
|
||||
@@ -157,5 +158,6 @@ public abstract class PlayerController {
|
||||
|
||||
public abstract boolean chooseBinary(SpellAbility sa, String question, boolean isCoin);
|
||||
public abstract boolean chooseFilpResult(SpellAbility sa, Player flipper, boolean[] results, boolean call);
|
||||
public abstract Card chooseProtectionShield(GameEntity entityBeingDamaged, List<String> options, Map<String, Card> choiceMap);
|
||||
|
||||
}
|
||||
|
||||
@@ -248,6 +248,11 @@ public class PlayerControllerAi extends PlayerController {
|
||||
ComputerUtil.playSpellAbilityForFree(player, copySA);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playSpellAbilityNoStack(Player player, SpellAbility effectSA) {
|
||||
ComputerUtil.playNoStack(player, effectSA, game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playMiracle(SpellAbility miracle, Card card) {
|
||||
getAi().chooseAndPlaySa(false, false, miracle);
|
||||
@@ -412,4 +417,10 @@ public class PlayerControllerAi extends PlayerController {
|
||||
public boolean chooseBinary(SpellAbility sa, String question, boolean isCoin) {
|
||||
return MyRandom.getRandom().nextBoolean();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Card chooseProtectionShield(GameEntity entityBeingDamaged, List<String> options, Map<String, Card> choiceMap) {
|
||||
int i = MyRandom.getRandom().nextInt(options.size());
|
||||
return choiceMap.get(options.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,6 +121,11 @@ public class PlayerControllerHuman extends PlayerController {
|
||||
HumanPlay.playSaWithoutPayingManaCost(player.getGame(), copySA, mayChoseNewTargets);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playSpellAbilityNoStack(Player player, SpellAbility effectSA) {
|
||||
HumanPlay.playSpellAbilityNoStack(player, effectSA);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.game.player.PlayerController#sideboard(forge.deck.Deck)
|
||||
*/
|
||||
@@ -645,6 +650,12 @@ public class PlayerControllerHuman extends PlayerController {
|
||||
return GuiChoose.one(sa.getSourceCard().getName() + " - Choose a result", strResults) == labelsSrc[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Card chooseProtectionShield(GameEntity entityBeingDamaged, List<String> options, Map<String, Card> choiceMap) {
|
||||
String title = entityBeingDamaged + " - select which prevention shield to use";
|
||||
return choiceMap.get(GuiChoose.one(title, options));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Pair<SpellAbilityStackInstance, ITargetable> chooseTarget(SpellAbility saSpellskite, List<Pair<SpellAbilityStackInstance, ITargetable>> allTargets) {
|
||||
|
||||
@@ -400,7 +400,7 @@ public class CardDetailPanel extends FPanel {
|
||||
}
|
||||
|
||||
// Damage Prevention
|
||||
final int preventNextDamage = card.getPreventNextDamage();
|
||||
final int preventNextDamage = card.getPreventNextDamageTotalShields();
|
||||
if (preventNextDamage > 0) {
|
||||
area.append("\n");
|
||||
area.append("Prevent the next ").append(preventNextDamage).append(" damage that would be dealt to ");
|
||||
|
||||
@@ -152,7 +152,7 @@ public enum VPlayers implements IVDoc<CPlayers> {
|
||||
+ String.valueOf(p0.getPoisonCounters()));
|
||||
temp[2].setText("Maximum hand size: " + String.valueOf(p0.getMaxHandSize()));
|
||||
temp[3].setText("Cards drawn this turn: " + String.valueOf(p0.getNumDrawnThisTurn()));
|
||||
temp[4].setText("Damage Prevention: " + String.valueOf(p0.getPreventNextDamage()));
|
||||
temp[4].setText("Damage Prevention: " + String.valueOf(p0.getPreventNextDamageTotalShields()));
|
||||
if (!p0.getKeywords().isEmpty()) {
|
||||
temp[5].setText(p0.getKeywords().toString());
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user