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

View File

@@ -25,14 +25,14 @@ public class CardDamageMap extends ForwardingTable<Card, GameEntity, Integer> {
private Table<Card, GameEntity, Integer> dataMap = HashBasedTable.create();
public CardDamageMap(Table<Card, GameEntity, Integer> damageMap) {
this.putAll(damageMap);
putAll(damageMap);
}
public CardDamageMap() {
}
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;
for (final int i : e.getValue().values()) {
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) {
// 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();
int sum = 0;
for (final Integer i : e.getValue().values()) {
@@ -71,7 +71,7 @@ public class CardDamageMap extends ForwardingTable<Card, GameEntity, Integer> {
}
}
// 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;
for (final int i : e.getValue().values()) {
sum += i;
@@ -106,9 +106,16 @@ public class CardDamageMap extends ForwardingTable<Card, GameEntity, Integer> {
return dataMap;
}
public int filteredAmount(String validSource, String validTarget, Card host, SpellAbility sa) {
public int totalAmount() {
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<GameEntity> filteredTarget = null;
if (validSource != null) {
@@ -125,7 +132,8 @@ public class CardDamageMap extends ForwardingTable<Card, GameEntity, Integer> {
if (filteredTarget != null && !filteredTarget.contains(c.getColumnKey())) {
continue;
}
result += c.getValue();
result.put(c.getRowKey(), c.getColumnKey(), c.getValue());
}
return result;

View File

@@ -29,24 +29,25 @@ public class TriggerDamageAll extends Trigger {
}
}
final CardDamageMap table = (CardDamageMap) runParams.get(AbilityKey.DamageMap);
return filterTable(table) > 0;
return !table.filteredMap(getParam("ValidSource"), getParam("ValidTarget"), getHostCard(), null).isEmpty();
}
@Override
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
public String getImportantStackObjects(SpellAbility sa) {
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));
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.)