From 7519e22d670ec9481a0605fda76c9f7ae02940d9 Mon Sep 17 00:00:00 2001 From: Hanmac Date: Sat, 10 Jun 2017 16:38:25 +0000 Subject: [PATCH] DamageDealBaseEffect: add base Class for Damage Effects: add replaceDying --- .gitattributes | 1 + .../game/ability/SpellAbilityEffect.java | 18 ++++ .../game/ability/effects/DamageAllEffect.java | 11 ++- .../ability/effects/DamageBaseEffect.java | 97 +++++++++++++++++++ .../ability/effects/DamageDealEffect.java | 12 ++- .../ability/effects/DamageEachEffect.java | 5 +- .../game/ability/effects/EffectEffect.java | 16 +-- .../game/ability/effects/FightEffect.java | 14 ++- 8 files changed, 149 insertions(+), 25 deletions(-) create mode 100644 forge-game/src/main/java/forge/game/ability/effects/DamageBaseEffect.java diff --git a/.gitattributes b/.gitattributes index 3b9e075fc82..647e03d3eb9 100644 --- a/.gitattributes +++ b/.gitattributes @@ -386,6 +386,7 @@ forge-game/src/main/java/forge/game/ability/effects/CountersPutOrRemoveEffect.ja forge-game/src/main/java/forge/game/ability/effects/CountersRemoveAllEffect.java -text forge-game/src/main/java/forge/game/ability/effects/CountersRemoveEffect.java -text forge-game/src/main/java/forge/game/ability/effects/DamageAllEffect.java -text +forge-game/src/main/java/forge/game/ability/effects/DamageBaseEffect.java -text svneol=unset#text/plain forge-game/src/main/java/forge/game/ability/effects/DamageDealEffect.java -text forge-game/src/main/java/forge/game/ability/effects/DamageEachEffect.java -text forge-game/src/main/java/forge/game/ability/effects/DamagePreventAllEffect.java -text diff --git a/forge-game/src/main/java/forge/game/ability/SpellAbilityEffect.java b/forge-game/src/main/java/forge/game/ability/SpellAbilityEffect.java index 5af0ad61144..27f566ba77a 100644 --- a/forge-game/src/main/java/forge/game/ability/SpellAbilityEffect.java +++ b/forge-game/src/main/java/forge/game/ability/SpellAbilityEffect.java @@ -264,4 +264,22 @@ public abstract class SpellAbilityEffect { trig.setOverridingAbility(AbilityFactory.getAbility(trigSA, card)); card.addTrigger(trig); } + + protected static void addForgetOnMovedTrigger(final Card card, final String zone) { + String trig = "Mode$ ChangesZone | ValidCard$ Card.IsRemembered | Origin$ " + zone + " | Destination$ Any | TriggerZones$ Command | Static$ True"; + String effect = "DB$ Pump | ForgetObjects$ TriggeredCard"; + final Trigger parsedTrigger = TriggerHandler.parseTrigger(trig, card, true); + parsedTrigger.setOverridingAbility(AbilityFactory.getAbility(effect, card)); + final Trigger addedTrigger = card.addTrigger(parsedTrigger); + addedTrigger.setIntrinsic(true); + } + + protected static void addExileOnMovedTrigger(final Card card, final String zone) { + String trig = "Mode$ ChangesZone | ValidCard$ Card.IsRemembered | Origin$ " + zone + " | Destination$ Any | TriggerZones$ Command | Static$ True"; + String effect = "DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile"; + final Trigger parsedTrigger = TriggerHandler.parseTrigger(trig, card, true); + parsedTrigger.setOverridingAbility(AbilityFactory.getAbility(effect, card)); + final Trigger addedTrigger = card.addTrigger(parsedTrigger); + addedTrigger.setIntrinsic(true); + } } diff --git a/forge-game/src/main/java/forge/game/ability/effects/DamageAllEffect.java b/forge-game/src/main/java/forge/game/ability/effects/DamageAllEffect.java index 31efc581a28..1c7b7e2bec5 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/DamageAllEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/DamageAllEffect.java @@ -3,7 +3,6 @@ package forge.game.ability.effects; import forge.game.Game; import forge.game.GameEntity; import forge.game.ability.AbilityUtils; -import forge.game.ability.SpellAbilityEffect; import forge.game.card.Card; import forge.game.card.CardCollection; import forge.game.card.CardCollectionView; @@ -15,7 +14,10 @@ import forge.game.zone.ZoneType; import java.util.List; -public class DamageAllEffect extends SpellAbilityEffect { +public class DamageAllEffect extends DamageBaseEffect { + /* (non-Javadoc) + * @see forge.game.ability.SpellAbilityEffect#getStackDescription(forge.game.spellability.SpellAbility) + */ @Override protected String getStackDescription(SpellAbility sa) { final StringBuilder sb = new StringBuilder(); @@ -44,6 +46,9 @@ public class DamageAllEffect extends SpellAbilityEffect { return sb.toString(); } + /* (non-Javadoc) + * @see forge.game.ability.SpellAbilityEffect#resolve(forge.game.spellability.SpellAbility) + */ @Override public void resolve(SpellAbility sa) { final List definedSources = AbilityUtils.getDefinedCards(sa.getHostCard(), sa.getParam("DamageSource"), sa); @@ -107,5 +112,7 @@ public class DamageAllEffect extends SpellAbilityEffect { preventMap.triggerPreventDamage(false); damageMap.dealLifelinkDamage(); + + replaceDying(sa); } } diff --git a/forge-game/src/main/java/forge/game/ability/effects/DamageBaseEffect.java b/forge-game/src/main/java/forge/game/ability/effects/DamageBaseEffect.java new file mode 100644 index 00000000000..2fbb37ab0f5 --- /dev/null +++ b/forge-game/src/main/java/forge/game/ability/effects/DamageBaseEffect.java @@ -0,0 +1,97 @@ +package forge.game.ability.effects; + +import forge.GameCommand; +import forge.game.Game; +import forge.game.ability.AbilityFactory; +import forge.game.ability.AbilityUtils; +import forge.game.ability.SpellAbilityEffect; +import forge.game.card.Card; +import forge.game.card.CardCollection; +import forge.game.player.Player; +import forge.game.replacement.ReplacementEffect; +import forge.game.replacement.ReplacementHandler; +import forge.game.replacement.ReplacementLayer; +import forge.game.spellability.SpellAbility; +import forge.game.trigger.TriggerType; +import forge.game.zone.ZoneType; + +abstract public class DamageBaseEffect extends SpellAbilityEffect { + + static void replaceDying(final SpellAbility sa) { + if (sa.hasParam("ReplaceDyingDefined")) { + + if (sa.hasParam("ReplaceDyingCondition")) { + // currently there is only one with Kicker + final String condition = sa.getParam("ReplaceDyingCondition"); + if ("Kicker".equals(condition)) { + if (!sa.isKicked()) { + return; + } + } + } + + final Card host = sa.getHostCard(); + final Player controller = sa.getActivatingPlayer(); + final Game game = host.getGame(); + String zone = sa.getParamOrDefault("ReplaceDyingZone", "Exile"); + CardCollection cards = AbilityUtils.getDefinedCards(host, sa.getParam("ReplaceDyingDefined"), sa); + // no cards, no need for Effect + if (cards.isEmpty()) { + return; + } + + // build an Effect with that infomation + String name = host.getName() + "'s Effect"; + + final Card eff = new Card(game.nextCardId(), game); + eff.setTimestamp(game.getNextTimestamp()); + eff.setName(name); + eff.addType("Effect"); + eff.setToken(true); // Set token to true, so when leaving play it gets nuked + eff.setOwner(controller); + + eff.setImageKey(host.getImageKey()); + eff.setColor(host.determineColor().getColor()); + eff.setImmutable(true); + eff.setEffectSource(host); + + eff.addRemembered(cards); + + String repeffstr = "Event$ Moved | ValidCard$ Card.IsRemembered | Destination$ Graveyard " + + "| Description$ If the creature would die this turn, exile it instead."; + String effect = "DB$ ChangeZone | Defined$ ReplacedCard | Origin$ Battlefield | Destination$ " + zone; + + ReplacementEffect re = ReplacementHandler.parseReplacement(repeffstr, eff, true); + re.setLayer(ReplacementLayer.Other); + + re.setOverridingAbility(AbilityFactory.getAbility(effect, eff)); + eff.addReplacementEffect(re); + + // Add forgot trigger + addForgetOnMovedTrigger(eff, "Battlefield"); + + // Copy text changes + if (sa.isIntrinsic()) { + eff.copyChangedTextFrom(host); + } + + final GameCommand endEffect = new GameCommand() { + private static final long serialVersionUID = -5861759814760561373L; + + @Override + public void run() { + game.getAction().exile(eff, null); + } + }; + + game.getEndOfTurn().addUntil(endEffect); + + eff.updateStateForView(); + + // TODO: Add targeting to the effect so it knows who it's dealing with + game.getTriggerHandler().suppressMode(TriggerType.ChangesZone); + game.getAction().moveTo(ZoneType.Command, eff, sa); + game.getTriggerHandler().clearSuppression(TriggerType.ChangesZone); + } + } +} diff --git a/forge-game/src/main/java/forge/game/ability/effects/DamageDealEffect.java b/forge-game/src/main/java/forge/game/ability/effects/DamageDealEffect.java index aaa7db0dba1..2f651a80fdf 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/DamageDealEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/DamageDealEffect.java @@ -3,7 +3,6 @@ package forge.game.ability.effects; import forge.game.Game; import forge.game.GameObject; import forge.game.ability.AbilityUtils; -import forge.game.ability.SpellAbilityEffect; import forge.game.card.Card; import forge.game.card.CardCollection; import forge.game.card.CardDamageMap; @@ -18,10 +17,10 @@ import java.util.Map.Entry; import com.google.common.collect.Iterables; -public class DamageDealEffect extends SpellAbilityEffect { +public class DamageDealEffect extends DamageBaseEffect { /* (non-Javadoc) - * @see forge.card.abilityfactory.SpellEffect#getStackDescription(java.util.Map, forge.card.spellability.SpellAbility) + * @see forge.game.ability.SpellAbilityEffect#getStackDescription(forge.game.spellability.SpellAbility) */ @Override protected String getStackDescription(SpellAbility sa) { @@ -65,6 +64,9 @@ public class DamageDealEffect extends SpellAbilityEffect { return sb.toString(); } + /* (non-Javadoc) + * @see forge.game.ability.SpellAbilityEffect#resolve(forge.game.spellability.SpellAbility) + */ @Override public void resolve(SpellAbility sa) { final Card hostCard = sa.getHostCard(); @@ -152,8 +154,10 @@ public class DamageDealEffect extends SpellAbilityEffect { if (combatDmg) { game.getCombat().getDamageMap().putAll(damageMap); } else { + preventMap.triggerPreventDamage(false); // non combat damage cause lifegain there damageMap.dealLifelinkDamage(); + replaceDying(sa); } return; } @@ -192,5 +196,7 @@ public class DamageDealEffect extends SpellAbilityEffect { // non combat damage cause lifegain there damageMap.dealLifelinkDamage(); } + + replaceDying(sa); } } diff --git a/forge-game/src/main/java/forge/game/ability/effects/DamageEachEffect.java b/forge-game/src/main/java/forge/game/ability/effects/DamageEachEffect.java index b144588b52c..f97cd9f9cb5 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/DamageEachEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/DamageEachEffect.java @@ -2,7 +2,6 @@ package forge.game.ability.effects; import forge.game.GameObject; import forge.game.ability.AbilityUtils; -import forge.game.ability.SpellAbilityEffect; import forge.game.card.Card; import forge.game.card.CardDamageMap; import forge.game.card.CardFactoryUtil; @@ -14,7 +13,7 @@ import forge.util.collect.FCollectionView; import java.util.List; -public class DamageEachEffect extends SpellAbilityEffect { +public class DamageEachEffect extends DamageBaseEffect { /* (non-Javadoc) * @see forge.card.abilityfactory.SpellEffect#getStackDescription(java.util.Map, forge.card.spellability.SpellAbility) @@ -123,5 +122,7 @@ public class DamageEachEffect extends SpellAbilityEffect { preventMap.triggerPreventDamage(false); damageMap.dealLifelinkDamage(); + + replaceDying(sa); } } diff --git a/forge-game/src/main/java/forge/game/ability/effects/EffectEffect.java b/forge-game/src/main/java/forge/game/ability/effects/EffectEffect.java index 7109db29291..a8851a9847b 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/EffectEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/EffectEffect.java @@ -199,21 +199,9 @@ public class EffectEffect extends SpellAbilityEffect { } } if (sa.hasParam("ForgetOnMoved")) { - String zone = sa.getParam("ForgetOnMoved"); - String trig = "Mode$ ChangesZone | ValidCard$ Card.IsRemembered | Origin$ " + zone + " | Destination$ Any | TriggerZones$ Command | Static$ True"; - String effect = "DB$ Pump | ForgetObjects$ TriggeredCard"; - final Trigger parsedTrigger = TriggerHandler.parseTrigger(trig, eff, true); - parsedTrigger.setOverridingAbility(AbilityFactory.getAbility(effect, eff)); - final Trigger addedTrigger = eff.addTrigger(parsedTrigger); - addedTrigger.setIntrinsic(true); + addForgetOnMovedTrigger(eff, sa.getParam("ForgetOnMoved")); } else if (sa.hasParam("ExileOnMoved")) { - String zone = sa.getParam("ExileOnMoved"); - String trig = "Mode$ ChangesZone | ValidCard$ Card.IsRemembered | Origin$ " + zone + " | Destination$ Any | TriggerZones$ Command | Static$ True"; - String effect = "DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile"; - final Trigger parsedTrigger = TriggerHandler.parseTrigger(trig, eff, true); - parsedTrigger.setOverridingAbility(AbilityFactory.getAbility(effect, eff)); - final Trigger addedTrigger = eff.addTrigger(parsedTrigger); - addedTrigger.setIntrinsic(true); + addExileOnMovedTrigger(eff, sa.getParam("ExileOnMoved")); } } diff --git a/forge-game/src/main/java/forge/game/ability/effects/FightEffect.java b/forge-game/src/main/java/forge/game/ability/effects/FightEffect.java index 78687d4ee6e..2f0dcb53109 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/FightEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/FightEffect.java @@ -5,7 +5,6 @@ import com.google.common.collect.Maps; import forge.game.Game; import forge.game.ability.AbilityUtils; -import forge.game.ability.SpellAbilityEffect; import forge.game.card.Card; import forge.game.card.CardDamageMap; import forge.game.spellability.SpellAbility; @@ -14,8 +13,11 @@ import forge.game.trigger.TriggerType; import java.util.List; import java.util.Map; -public class FightEffect extends SpellAbilityEffect { +public class FightEffect extends DamageBaseEffect { + /* (non-Javadoc) + * @see forge.game.ability.SpellAbilityEffect#getStackDescription(forge.game.spellability.SpellAbility) + */ @Override protected String getStackDescription(SpellAbility sa) { final StringBuilder sb = new StringBuilder(); @@ -31,8 +33,9 @@ public class FightEffect extends SpellAbilityEffect { return sb.toString(); } + /* (non-Javadoc) - * @see forge.card.abilityfactory.SpellEffect#resolve(java.util.Map, forge.card.spellability.SpellAbility) + * @see forge.game.ability.SpellAbilityEffect#resolve(forge.game.spellability.SpellAbility) */ @Override public void resolve(SpellAbility sa) { @@ -61,6 +64,8 @@ public class FightEffect extends SpellAbilityEffect { preventMap.triggerPreventDamage(false); damageMap.dealLifelinkDamage(); + + replaceDying(sa); for (Card c : fighters) { final Map runParams = Maps.newHashMap(); @@ -112,7 +117,8 @@ public class FightEffect extends SpellAbilityEffect { return fighterList; } - private void dealDamage(Card source, Card target, boolean fightToughness, CardDamageMap damageMap, CardDamageMap preventMap) { + private void dealDamage(Card source, Card target, boolean fightToughness, CardDamageMap damageMap, + CardDamageMap preventMap) { final int dmg = fightToughness ? source.getNetToughness() : source.getNetPower(); target.addDamage(dmg, source, damageMap, preventMap);