DamageMap: TriggerDamageDealtOnce and TriggerDamageDoneOnce now filter the amount

This commit is contained in:
Hans Mackowiak
2020-04-28 08:09:59 +02:00
parent 3a53ab8a9c
commit 2df5373902
4 changed files with 78 additions and 53 deletions

View File

@@ -9,6 +9,7 @@ import java.util.Set;
import com.google.common.collect.ForwardingTable;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.common.collect.Table;
@@ -59,8 +60,7 @@ public class CardDamageMap extends ForwardingTable<Card, GameEntity, Integer> {
if (sum > 0) {
final Map<AbilityKey, Object> runParams = AbilityKey.newMap();
runParams.put(AbilityKey.DamageSource, sourceLKI);
runParams.put(AbilityKey.DamageTargets, Sets.newHashSet(e.getValue().keySet()));
runParams.put(AbilityKey.DamageAmount, sum);
runParams.put(AbilityKey.DamageMap, Maps.newHashMap(e.getValue()));
runParams.put(AbilityKey.IsCombatDamage, isCombat);
game.getTriggerHandler().runTrigger(TriggerType.DamageDealtOnce, runParams, false);
@@ -80,8 +80,7 @@ public class CardDamageMap extends ForwardingTable<Card, GameEntity, Integer> {
final GameEntity ge = e.getKey();
final Map<AbilityKey, Object> runParams = AbilityKey.newMap();
runParams.put(AbilityKey.DamageTarget, ge);
runParams.put(AbilityKey.DamageSources, Sets.newHashSet(e.getValue().keySet()));
runParams.put(AbilityKey.DamageAmount, sum);
runParams.put(AbilityKey.DamageMap, Maps.newHashMap(e.getValue()));
runParams.put(AbilityKey.IsCombatDamage, isCombat);
game.getTriggerHandler().runTrigger(TriggerType.DamageDoneOnce, runParams, false);

View File

@@ -21,12 +21,13 @@ import forge.game.GameEntity;
import forge.game.ability.AbilityKey;
import forge.game.card.Card;
import forge.game.spellability.SpellAbility;
import forge.util.Expressions;
import forge.util.Localizer;
import java.util.Map;
import java.util.Set;
import com.google.common.collect.Sets;
/**
* <p>
* Trigger_DamageDone class.
@@ -59,7 +60,6 @@ public class TriggerDamageDealtOnce extends Trigger {
@Override
public final boolean performTest(final Map<AbilityKey, Object> runParams) {
final Card srcs = (Card) runParams.get(AbilityKey.DamageSource);
final Set<GameEntity> tgt = (Set<GameEntity>) runParams.get(AbilityKey.DamageTargets);
if (hasParam("CombatDamage")) {
if (getParam("CombatDamage").equals("True")) {
@@ -72,33 +72,17 @@ public class TriggerDamageDealtOnce extends Trigger {
}
}
}
if (hasParam("ValidTarget")) {
boolean valid = false;
for (GameEntity c : tgt) {
if (c.isValid(getParam("ValidTarget").split(","), this.getHostCard().getController(),this.getHostCard(), null)) {
valid = true;
}
}
if (!valid) {
final Map<GameEntity, Integer> damageMap = (Map<GameEntity, Integer>) runParams.get(AbilityKey.DamageMap);
if (getDamageAmount(damageMap) <= 0) {
return false;
}
}
if (hasParam("ValidSource")) {
if (!matchesValid(srcs, getParam("ValidSource").split(","), this.getHostCard())) {
return false;
}
}
if (hasParam("DamageAmount")) {
final String fullParam = getParam("DamageAmount");
final String operator = fullParam.substring(0, 2);
final int operand = Integer.parseInt(fullParam.substring(2));
final int actualAmount = (Integer) runParams.get(AbilityKey.DamageAmount);
if (!Expressions.compare(actualAmount, operator, operand)) {
if (!matchesValid(srcs, getParam("ValidSource").split(","), getHostCard())) {
return false;
}
}
@@ -109,9 +93,12 @@ public class TriggerDamageDealtOnce extends Trigger {
/** {@inheritDoc} */
@Override
public final void setTriggeringObjects(final SpellAbility sa, Map<AbilityKey, Object> runParams) {
sa.setTriggeringObjectsFrom(runParams, AbilityKey.DamageAmount);
@SuppressWarnings("unchecked")
final Map<GameEntity, Integer> damageMap = (Map<GameEntity, Integer>) runParams.get(AbilityKey.DamageMap);
sa.setTriggeringObject(AbilityKey.Source, runParams.get(AbilityKey.DamageSource));
sa.setTriggeringObject(AbilityKey.Targets, runParams.get(AbilityKey.DamageTargets));
sa.setTriggeringObject(AbilityKey.Targets, getDamageTargets(damageMap));
sa.setTriggeringObject(AbilityKey.DamageAmount, getDamageAmount(damageMap));
}
@Override
@@ -122,4 +109,24 @@ public class TriggerDamageDealtOnce extends Trigger {
sb.append(Localizer.getInstance().getMessage("lblAmount")).append(": ").append(sa.getTriggeringObject(AbilityKey.DamageAmount));
return sb.toString();
}
public int getDamageAmount(Map<GameEntity, Integer> damageMap) {
int result = 0;
for (Map.Entry<GameEntity, Integer> e : damageMap.entrySet()) {
if (matchesValid(e.getKey(), getParam("ValidTarget").split(","), getHostCard())) {
result += e.getValue();
}
}
return result;
}
public Set<GameEntity> getDamageTargets(Map<GameEntity, Integer> damageMap) {
Set<GameEntity> result = Sets.newHashSet();
for (GameEntity e : damageMap.keySet()) {
if (matchesValid(e, getParam("ValidTarget").split(","), getHostCard())) {
result.add(e);
}
}
return result;
}
}

View File

@@ -3,6 +3,8 @@ package forge.game.trigger;
import java.util.Map;
import java.util.Set;
import com.google.common.collect.Sets;
import forge.game.GameEntity;
import forge.game.ability.AbilityKey;
import forge.game.card.Card;
@@ -19,7 +21,6 @@ public class TriggerDamageDoneOnce extends Trigger {
@SuppressWarnings("unchecked")
@Override
public boolean performTest(Map<AbilityKey, Object> runParams) {
final Set<Card> srcs = (Set<Card>) runParams.get(AbilityKey.DamageSources);
final GameEntity tgt = (GameEntity) runParams.get(AbilityKey.DamageTarget);
if (hasParam("CombatDamage")) {
@@ -33,35 +34,34 @@ public class TriggerDamageDoneOnce extends Trigger {
}
}
}
if (hasParam("ValidSource")) {
boolean valid = false;
for (Card c : srcs) {
if (c.isValid(getParam("ValidSource").split(","), this.getHostCard().getController(),this.getHostCard(), null)) {
valid = true;
}
}
if (!valid) {
return false;
}
}
if (hasParam("ValidTarget")) {
if (!matchesValid(tgt, getParam("ValidTarget").split(","), this.getHostCard())) {
return false;
}
}
if (hasParam("ValidSource")) {
final Map<Card, Integer> damageMap = (Map<Card, Integer>) runParams.get(AbilityKey.DamageMap);
if (getDamageAmount(damageMap) <= 0) {
return false;
}
}
if (hasParam("ValidTarget")) {
if (!matchesValid(tgt, getParam("ValidTarget").split(","), getHostCard())) {
return false;
}
}
return true;
}
@Override
public void setTriggeringObjects(SpellAbility sa, Map<AbilityKey, Object> runParams) {
@SuppressWarnings("unchecked")
final Map<Card, Integer> damageMap = (Map<Card, Integer>) runParams.get(AbilityKey.DamageMap);
sa.setTriggeringObject(AbilityKey.Target, runParams.get(AbilityKey.DamageTarget));
sa.setTriggeringObject(AbilityKey.Sources, runParams.get(AbilityKey.DamageSources));
sa.setTriggeringObjectsFrom(runParams, AbilityKey.DamageAmount);
sa.setTriggeringObject(AbilityKey.Sources, getDamageSources(damageMap));
sa.setTriggeringObject(AbilityKey.DamageAmount, getDamageAmount(damageMap));
}
@Override
@@ -74,4 +74,23 @@ public class TriggerDamageDoneOnce extends Trigger {
return sb.toString();
}
public int getDamageAmount(Map<Card, Integer> damageMap) {
int result = 0;
for (Map.Entry<Card, Integer> e : damageMap.entrySet()) {
if (matchesValid(e.getKey(), getParam("ValidSource").split(","), getHostCard())) {
result += e.getValue();
}
}
return result;
}
public Set<Card> getDamageSources(Map<Card, Integer> damageMap) {
Set<Card> result = Sets.newHashSet();
for (Card c : damageMap.keySet()) {
if (matchesValid(c, getParam("ValidSource").split(","), getHostCard())) {
result.add(c);
}
}
return result;
}
}

View File

@@ -3,7 +3,7 @@ ManaCost:1 B R
Types:Creature Ogre Warrior
PT:3/4
T:Mode$ DamageDoneOnce | ValidTarget$ Card.Self | Execute$ TrigYouDiscard | TriggerDescription$ Whenever CARDNAME is dealt damage, discard that many cards.
T:Mode$ DamageDealtOnce | ValidSource$ Card.Self | ValidTarget$ Player | CombatDamage$ True | Hellbent$ True | Execute$ TrigOppDiscard | TriggerDescription$ Hellbent — Whenever CARDNAME deals combat damage to a player, if you have no cards in hand, that player discards cards equal to the damage.
T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | CombatDamage$ True | Hellbent$ True | Execute$ TrigOppDiscard | TriggerDescription$ Hellbent — Whenever CARDNAME deals combat damage to a player, if you have no cards in hand, that player discards cards equal to the damage.
SVar:TrigYouDiscard:DB$ Discard | Defined$ You | NumCards$ X | Mode$ TgtChoose | References$ X
SVar:TrigOppDiscard:DB$ Discard | Defined$ TriggeredTarget | NumCards$ X | Mode$ TgtChoose | References$ X
SVar:X:TriggerCount$DamageAmount