Merge branch 'triggerDamageAllExtend' into 'master'

TriggerDamageAll: add triggered objects for Sources and Targets, AbilityUtils supports Sets now

Closes #1620

See merge request core-developers/forge!3307
This commit is contained in:
Michael Kamensky
2020-10-30 03:43:47 +00:00
5 changed files with 54 additions and 31 deletions

View File

@@ -168,8 +168,8 @@ public class AbilityUtils {
if (crd instanceof Card) { if (crd instanceof Card) {
c = game.getCardState((Card) crd); c = game.getCardState((Card) crd);
} else if (crd instanceof List<?>) { } else if (crd instanceof Iterable<?>) {
cards.addAll((CardCollection) crd); cards.addAll(Iterables.filter((Iterable<?>) crd, Card.class));
} }
} }
else if (defined.equals("Remembered") || defined.equals("RememberedCard")) { else if (defined.equals("Remembered") || defined.equals("RememberedCard")) {
@@ -657,9 +657,7 @@ public class AbilityUtils {
if (calcX[0].startsWith("TriggeredPlayers")) { if (calcX[0].startsWith("TriggeredPlayers")) {
key = "Triggered" + key.substring(16); key = "Triggered" + key.substring(16);
} }
final List<Player> players = new ArrayList<>(); return CardFactoryUtil.playerXCount(getDefinedPlayers(card, key, sa), calcX[1], card) * multiplier;
Iterables.addAll(players, getDefinedPlayers(card, key, sa));
return CardFactoryUtil.playerXCount(players, calcX[1], card) * multiplier;
} }
if (calcX[0].startsWith("TriggeredPlayer") || calcX[0].startsWith("TriggeredTarget")) { if (calcX[0].startsWith("TriggeredPlayer") || calcX[0].startsWith("TriggeredTarget")) {
final SpellAbility root = sa.getRootAbility(); final SpellAbility root = sa.getRootAbility();
@@ -1078,20 +1076,10 @@ public class AbilityUtils {
} }
if (o != null) { if (o != null) {
if (o instanceof Player) { if (o instanceof Player) {
final Player p = (Player) o; players.add((Player) o);
if (!players.contains(p)) {
players.add(p);
}
} }
if (o instanceof List) { if (o instanceof Iterable) {
final List<?> pList = (List<?>)o; players.addAll(Iterables.filter((Iterable<?>)o, Player.class));
if (!pList.isEmpty()) {
for (final Object p : pList) {
if (p instanceof Player && !players.contains(p)) {
players.add((Player) p);
}
}
}
} }
} }
} }

View File

@@ -25,14 +25,14 @@ public class CardDamageMap extends ForwardingTable<Card, GameEntity, Integer> {
private Table<Card, GameEntity, Integer> dataMap = HashBasedTable.create(); private Table<Card, GameEntity, Integer> dataMap = HashBasedTable.create();
public CardDamageMap(Table<Card, GameEntity, Integer> damageMap) { public CardDamageMap(Table<Card, GameEntity, Integer> damageMap) {
this.putAll(damageMap); putAll(damageMap);
} }
public CardDamageMap() { public CardDamageMap() {
} }
public void triggerPreventDamage(boolean isCombat) { public void triggerPreventDamage(boolean isCombat) {
for (Map.Entry<GameEntity, Map<Card, Integer>> e : this.columnMap().entrySet()) { for (Map.Entry<GameEntity, Map<Card, Integer>> e : columnMap().entrySet()) {
int sum = 0; int sum = 0;
for (final int i : e.getValue().values()) { for (final int i : e.getValue().values()) {
sum += i; sum += i;
@@ -51,7 +51,7 @@ public class CardDamageMap extends ForwardingTable<Card, GameEntity, Integer> {
public void triggerDamageDoneOnce(boolean isCombat, final Game game, final SpellAbility sa) { public void triggerDamageDoneOnce(boolean isCombat, final Game game, final SpellAbility sa) {
// Source -> Targets // Source -> Targets
for (Map.Entry<Card, Map<GameEntity, Integer>> e : this.rowMap().entrySet()) { for (Map.Entry<Card, Map<GameEntity, Integer>> e : rowMap().entrySet()) {
final Card sourceLKI = e.getKey(); final Card sourceLKI = e.getKey();
int sum = 0; int sum = 0;
for (final Integer i : e.getValue().values()) { for (final Integer i : e.getValue().values()) {
@@ -71,7 +71,7 @@ public class CardDamageMap extends ForwardingTable<Card, GameEntity, Integer> {
} }
} }
// Targets -> Source // Targets -> Source
for (Map.Entry<GameEntity, Map<Card, Integer>> e : this.columnMap().entrySet()) { for (Map.Entry<GameEntity, Map<Card, Integer>> e : columnMap().entrySet()) {
int sum = 0; int sum = 0;
for (final int i : e.getValue().values()) { for (final int i : e.getValue().values()) {
sum += i; sum += i;
@@ -106,9 +106,16 @@ public class CardDamageMap extends ForwardingTable<Card, GameEntity, Integer> {
return dataMap; return dataMap;
} }
public int filteredAmount(String validSource, String validTarget, Card host, SpellAbility sa) { public int totalAmount() {
int result = 0; int result = 0;
for (int i : values()) {
result += i;
}
return result;
}
public CardDamageMap filteredMap(String validSource, String validTarget, Card host, SpellAbility sa) {
CardDamageMap result = new CardDamageMap();
Set<Card> filteredSource = null; Set<Card> filteredSource = null;
Set<GameEntity> filteredTarget = null; Set<GameEntity> filteredTarget = null;
if (validSource != null) { if (validSource != null) {
@@ -125,7 +132,8 @@ public class CardDamageMap extends ForwardingTable<Card, GameEntity, Integer> {
if (filteredTarget != null && !filteredTarget.contains(c.getColumnKey())) { if (filteredTarget != null && !filteredTarget.contains(c.getColumnKey())) {
continue; continue;
} }
result += c.getValue();
result.put(c.getRowKey(), c.getColumnKey(), c.getValue());
} }
return result; return result;

View File

@@ -29,24 +29,25 @@ public class TriggerDamageAll extends Trigger {
} }
} }
final CardDamageMap table = (CardDamageMap) runParams.get(AbilityKey.DamageMap); final CardDamageMap table = (CardDamageMap) runParams.get(AbilityKey.DamageMap);
return filterTable(table) > 0; return !table.filteredMap(getParam("ValidSource"), getParam("ValidTarget"), getHostCard(), null).isEmpty();
} }
@Override @Override
public void setTriggeringObjects(SpellAbility sa, Map<AbilityKey, Object> runParams) { public void setTriggeringObjects(SpellAbility sa, Map<AbilityKey, Object> runParams) {
final CardDamageMap table = (CardDamageMap) runParams.get(AbilityKey.DamageMap); CardDamageMap table = (CardDamageMap) runParams.get(AbilityKey.DamageMap);
table = table.filteredMap(getParam("ValidSource"), getParam("ValidTarget"), getHostCard(), null);
sa.setTriggeringObject(AbilityKey.DamageAmount, filterTable(table)); sa.setTriggeringObject(AbilityKey.DamageAmount, table.totalAmount());
sa.setTriggeringObject(AbilityKey.Sources, table.rowKeySet());
sa.setTriggeringObject(AbilityKey.Targets, table.columnKeySet());
} }
@Override @Override
public String getImportantStackObjects(SpellAbility sa) { public String getImportantStackObjects(SpellAbility sa) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append(Localizer.getInstance().getMessage("lblDamageSource")).append(": ").append(sa.getTriggeringObject(AbilityKey.Sources)).append(", ");
sb.append(Localizer.getInstance().getMessage("lblDamaged")).append(": ").append(sa.getTriggeringObject(AbilityKey.Targets)).append(", ");
sb.append(Localizer.getInstance().getMessage("lblAmount")).append(": ").append(sa.getTriggeringObject(AbilityKey.DamageAmount)); sb.append(Localizer.getInstance().getMessage("lblAmount")).append(": ").append(sa.getTriggeringObject(AbilityKey.DamageAmount));
return sb.toString(); return sb.toString();
} }
private int filterTable(CardDamageMap table) {
return table.filteredAmount(getParam("ValidSource"), getParam("ValidTarget"), getHostCard(), null);
}
} }

View File

@@ -0,0 +1,14 @@
Name:Breeches, Brazen Plunderer
ManaCost:3 R
Types:Legendary Creature Goblin Pirate
PT:3/3
K:Menace
K:Partner
T:Mode$ DamageAll | ValidSource$ Pirate.YouCtrl | ValidTarget$ Opponent | TriggerZones$ Battlefield | Execute$ TrigExileTop | TriggerDescription$ Whenever one or more Pirates you control deal damage to your opponents, exile the top card of each of those opponents' libraries. You may play those cards this turn, and you may spend mana as though it were mana of any color to cast those spells.
SVar:TrigExileTop:DB$ Dig | DigNum$ 1 | ChangeNum$ All | Defined$ TriggeredTargets | DestinationZone$ Exile | RememberChanged$ True | SubAbility$ DBEffect
SVar:DBEffect:DB$ Effect | StaticAbilities$ EffPlay | EffectOwner$ You | RememberObjects$ Remembered | ForgetOnMoved$ Exile | SubAbility$ DBCleanup
SVar:EffPlay:Mode$ Continuous | MayPlay$ True | MayPlayIgnoreType$ True | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Exile | Description$ You may play those cards this turn, and you may spend mana as though it were mana of any color to cast those spells.
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
DeckHints:Type$Pirate
Oracle:Menace\nWhenever one or more Pirates you control deal damage to your opponents, exile the top card of each of those opponents' libraries. You may play those cards this turn, and you may spend mana as though it were mana of any color to cast those spells.\nPartner (You can have two commanders if both have partner.)

View File

@@ -0,0 +1,12 @@
Name:Malcolm, Keen-Eyed Navigator
ManaCost:2 U
Types:Legendary Creature Siren Pirate
PT:2/2
K:Flying
K:Partner
T:Mode$ DamageAll | ValidSource$ Pirate.YouCtrl | ValidTarget$ Opponent | TriggerZones$ Battlefield | Execute$ TrigToken | TriggerDescription$ Whenever one or more Pirates you control deal damage to your opponents, you create a Treasure token for each opponent dealt damage. (It's an artifact with "{T}, Sacrifice this artifact: Add one mana of any color.")
SVar:TrigToken:DB$ Token | TokenAmount$ X | References$ X | TokenScript$ c_a_treasure_sac | TokenOwner$ You
SVar:X:TriggeredPlayersTargets$Amount
DeckHints:Type$Pirate
DeckHas:Ability$Token
Oracle:Flying\nWhenever one or more Pirates you control deal damage to your opponents, you create a Treasure token for each opponent dealt damage. (It's an artifact with "{T}, Sacrifice this artifact: Add one mana of any color.")\nPartner (You can have two commanders if both have partner.)