diff --git a/forge-game/src/main/java/forge/game/Game.java b/forge-game/src/main/java/forge/game/Game.java index c9f8171f7c2..b3335d35ea9 100644 --- a/forge-game/src/main/java/forge/game/Game.java +++ b/forge-game/src/main/java/forge/game/Game.java @@ -1292,6 +1292,11 @@ public class Game { return dmgList; } + public int getSingleMaxDamageDoneThisTurn() { + return globalDamageHistory.stream().flatMap(cdh -> cdh.getAllDmgInstances().stream()). + mapToInt(dmg -> dmg.getLeft()).max().orElse(0); + } + public void addGlobalDamageHistory(CardDamageHistory cdh, Pair dmg, Card source, GameEntity target) { globalDamageHistory.add(cdh); damageThisTurnLKI.put(dmg, Pair.of(source, target)); diff --git a/forge-game/src/main/java/forge/game/ability/AbilityUtils.java b/forge-game/src/main/java/forge/game/ability/AbilityUtils.java index 2f8d310fcc7..58ed6ff4e81 100644 --- a/forge-game/src/main/java/forge/game/ability/AbilityUtils.java +++ b/forge-game/src/main/java/forge/game/ability/AbilityUtils.java @@ -2426,6 +2426,11 @@ public class AbilityUtils { return doXMath(sum, expr, c, ctb); } + if (sq[0].equals("SingleMaxDamageThisTurn")) { + int sum = game.getSingleMaxDamageDoneThisTurn(); + return doXMath(sum, expr, c, ctb); + } + if (sq[0].contains("DamageThisTurn")) { String[] props = l[0].split(" "); Boolean isCombat = null; diff --git a/forge-game/src/main/java/forge/game/card/CardDamageHistory.java b/forge-game/src/main/java/forge/game/card/CardDamageHistory.java index 03dddee587f..8e204669d23 100644 --- a/forge-game/src/main/java/forge/game/card/CardDamageHistory.java +++ b/forge-game/src/main/java/forge/game/card/CardDamageHistory.java @@ -1,6 +1,5 @@ package forge.game.card; - import com.google.common.collect.Lists; import forge.game.CardTraitBase; import forge.game.GameEntity; @@ -250,6 +249,9 @@ public class CardDamageHistory { } public int getDamageDoneThisTurn(Boolean isCombat, boolean anyIsEnough, String validSourceCard, String validTargetEntity, Card source, Player sourceController, CardTraitBase ctb) { + return getDamageDoneThisTurn(isCombat, anyIsEnough, false, validSourceCard, validTargetEntity, source, sourceController, ctb); + } + public int getDamageDoneThisTurn(Boolean isCombat, boolean anyIsEnough, boolean times, String validSourceCard, String validTargetEntity, Card source, Player sourceController, CardTraitBase ctb) { int sum = 0; for (Pair damage : damageDoneThisTurn) { Pair sourceToTarget = sourceController.getGame().getDamageLKI(damage); @@ -265,7 +267,7 @@ public class CardDamageHistory { continue; } } - sum += damage.getLeft(); + sum += times ? 1 : damage.getLeft(); if (anyIsEnough) { break; } @@ -273,6 +275,10 @@ public class CardDamageHistory { return sum; } + public List> getAllDmgInstances() { + return damageDoneThisTurn; + } + public void newTurn() { attackedThisTurn.clear(); attackedBattleThisTurn = false; diff --git a/forge-game/src/main/java/forge/game/player/PlayerProperty.java b/forge-game/src/main/java/forge/game/player/PlayerProperty.java index 8407d9ee065..bafe3ebdd2b 100644 --- a/forge-game/src/main/java/forge/game/player/PlayerProperty.java +++ b/forge-game/src/main/java/forge/game/player/PlayerProperty.java @@ -132,32 +132,34 @@ public class PlayerProperty { return false; } } else if (property.startsWith("wasDealt")) { - boolean found = false; - String validCard = null; Boolean combat = null; if (property.contains("CombatDamage")) { combat = true; } - if (property.contains("ThisTurnBySource")) { - found = source.getDamageHistory().getDamageDoneThisTurn(combat, validCard == null, validCard, "You", source, player, spellAbility) > 0; - } else { - String comp = "GE"; - int right = 1; - int numValid = 0; + String validCard = null; + String comp = "GE"; + int right = 1; - if (property.contains("ThisTurnBy")) { - String[] props = property.split(" "); + if (property.contains("ThisTurnBy")) { + int idx = 2; + String[] props = property.split(" "); + if (property.contains("BySource")) { + idx--; + } else { validCard = props[1]; - if (props.length > 2) { - comp = props[2].substring(0, 2); - right = AbilityUtils.calculateAmount(source, props[2].substring(2), spellAbility); - } } - - numValid = game.getDamageDoneThisTurn(combat, validCard == null, validCard, "You", source, player, spellAbility).size(); - found = Expressions.compare(numValid, comp, right); + if (props.length > idx) { + comp = props[idx].substring(0, 2); + right = AbilityUtils.calculateAmount(source, props[idx].substring(2), spellAbility); + } } - if (!found) { + int result; + if (property.contains("BySource")) { + result = source.getDamageHistory().getDamageDoneThisTurn(combat, false, property.contains("SourceTimes"), null, "You", source, player, spellAbility); + } else { + result = game.getDamageDoneThisTurn(combat, validCard == null, validCard, "You", source, player, spellAbility).size(); + } + if (!Expressions.compare(result, comp, right)) { return false; } } else if (property.equals("attackedBySourceThisCombat")) { diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerDamageDone.java b/forge-game/src/main/java/forge/game/trigger/TriggerDamageDone.java index 371e764ec79..91fc5d8fc36 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerDamageDone.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerDamageDone.java @@ -22,7 +22,6 @@ import java.util.Map; import forge.game.ability.AbilityKey; import forge.game.card.Card; import forge.game.card.CardCopyService; -import forge.game.player.Player; import forge.game.spellability.SpellAbility; import forge.util.Expressions; import forge.util.Localizer; @@ -105,23 +104,6 @@ public class TriggerDamageDone extends Trigger { } } - if (hasParam("DamageToTargetThisTurnCondition")) { - final String fullParam = getParam("DamageToTargetThisTurnCondition"); - - final String operator = fullParam.substring(0, 2); - final int operand = Integer.parseInt(fullParam.substring(2)); - final Object target = runParams.get(AbilityKey.DamageTarget); - final Card source = (Card) runParams.get(AbilityKey.DamageSource); - - if (target instanceof Player trigTgt) { - if (!Expressions.compare(trigTgt.getAssignedDamage(null, source), operator, operand)) { - return false; - } - } else { - return false; //for now this is only used to check damage assigned to a player - } - } - return true; } diff --git a/forge-gui/res/cardsfolder/h/hidetsugu_consumes_all_vessel_of_the_all_consuming.txt b/forge-gui/res/cardsfolder/h/hidetsugu_consumes_all_vessel_of_the_all_consuming.txt index 1abc8404ce5..4820ae4311c 100644 --- a/forge-gui/res/cardsfolder/h/hidetsugu_consumes_all_vessel_of_the_all_consuming.txt +++ b/forge-gui/res/cardsfolder/h/hidetsugu_consumes_all_vessel_of_the_all_consuming.txt @@ -20,7 +20,7 @@ PT:3/3 K:Trample T:Mode$ DamageDealtOnce | ValidSource$ Card.Self | Execute$ TrigPutCounter | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME deals damage, put a +1/+1 counter on it. SVar:TrigPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1 -T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | Execute$ TrigLose | DamageToTargetThisTurnCondition$ GE10 | TriggerDescription$ Whenever CARDNAME deals damage to a player, if it has dealt 10 or more damage to that player this turn, they lose the game. +T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player.wasDealtDamageThisTurnBySource GE10 | Execute$ TrigLose | TriggerDescription$ Whenever CARDNAME deals damage to a player, if it has dealt 10 or more damage to that player this turn, they lose the game. SVar:TrigLose:DB$ LosesGame | Defined$ TriggeredTarget DeckHas:Ability$Counters Oracle:Trample\nWhenever Vessel of the All-Consuming deals damage, put a +1/+1 counter on it.\nWhenever Vessel of the All-Consuming deals damage to a player, if it has dealt 10 or more damage to that player this turn, they lose the game. diff --git a/forge-gui/res/cardsfolder/i/impact_resonance.txt b/forge-gui/res/cardsfolder/i/impact_resonance.txt index c3c78e332f2..c29cec314f9 100644 --- a/forge-gui/res/cardsfolder/i/impact_resonance.txt +++ b/forge-gui/res/cardsfolder/i/impact_resonance.txt @@ -2,6 +2,6 @@ Name:Impact Resonance ManaCost:1 R Types:Instant A:SP$ DealDamage | ValidTgts$ Creature | TargetMin$ 0 | TargetMax$ MaxTgts | NumDmg$ X | DividedAsYouChoose$ X | SpellDescription$ CARDNAME deals X damage divided as you choose among any number of target creatures, where X is the greatest amount of damage dealt by a source to a permanent or player this turn. -SVar:X:Count$MaxDamageThisTurn Card Permanent,Player +SVar:X:Count$SingleMaxDamageThisTurn SVar:MaxTgts:Count$Valid Creature Oracle:Impact Resonance deals X damage divided as you choose among any number of target creatures, where X is the greatest amount of damage dealt by a source to a permanent or player this turn. diff --git a/forge-gui/res/cardsfolder/upcoming/raphael_tag_team_tough.txt b/forge-gui/res/cardsfolder/upcoming/raphael_tag_team_tough.txt new file mode 100644 index 00000000000..cd2d5515265 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/raphael_tag_team_tough.txt @@ -0,0 +1,9 @@ +Name:Raphael, Tag Team Tough +ManaCost:4 R R +Types:Legendary Creature Mutant Ninja Turtle +PT:5/6 +K:Menace +T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player.wasDealtCombatDamageThisTurnBySourceTimes EQ1 | TriggerZones$ Battlefield | Execute$ TrigUntap | TriggerDescription$ Whenever NICKNAME deals combat damage to a player for the first time each turn, untap all attacking creatures. After this combat phase, there is an additional combat phase. +SVar:TrigUntap:DB$ UntapAll | ValidCards$ Creature.attacking | SubAbility$ DBAddCombat +SVar:DBAddCombat:DB$ AddPhase | ExtraPhase$ Combat | AfterPhase$ EndCombat +Oracle:Menace (This creature can’t be blocked except by two or more creatures.)\nWhenever Raphael deals combat damage to a player for the first time each turn, untap all attacking creatures. After this combat phase, there is an additional combat phase.