mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-11 16:26:22 +00:00
Raphael, Tag Team Tough and support (#8936)
This commit is contained in:
@@ -1292,6 +1292,11 @@ public class Game {
|
|||||||
return dmgList;
|
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<Integer, Boolean> dmg, Card source, GameEntity target) {
|
public void addGlobalDamageHistory(CardDamageHistory cdh, Pair<Integer, Boolean> dmg, Card source, GameEntity target) {
|
||||||
globalDamageHistory.add(cdh);
|
globalDamageHistory.add(cdh);
|
||||||
damageThisTurnLKI.put(dmg, Pair.of(source, target));
|
damageThisTurnLKI.put(dmg, Pair.of(source, target));
|
||||||
|
|||||||
@@ -2426,6 +2426,11 @@ public class AbilityUtils {
|
|||||||
return doXMath(sum, expr, c, ctb);
|
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")) {
|
if (sq[0].contains("DamageThisTurn")) {
|
||||||
String[] props = l[0].split(" ");
|
String[] props = l[0].split(" ");
|
||||||
Boolean isCombat = null;
|
Boolean isCombat = null;
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package forge.game.card;
|
package forge.game.card;
|
||||||
|
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import forge.game.CardTraitBase;
|
import forge.game.CardTraitBase;
|
||||||
import forge.game.GameEntity;
|
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) {
|
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;
|
int sum = 0;
|
||||||
for (Pair<Integer, Boolean> damage : damageDoneThisTurn) {
|
for (Pair<Integer, Boolean> damage : damageDoneThisTurn) {
|
||||||
Pair<Card, GameEntity> sourceToTarget = sourceController.getGame().getDamageLKI(damage);
|
Pair<Card, GameEntity> sourceToTarget = sourceController.getGame().getDamageLKI(damage);
|
||||||
@@ -265,7 +267,7 @@ public class CardDamageHistory {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sum += damage.getLeft();
|
sum += times ? 1 : damage.getLeft();
|
||||||
if (anyIsEnough) {
|
if (anyIsEnough) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -273,6 +275,10 @@ public class CardDamageHistory {
|
|||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Pair<Integer, Boolean>> getAllDmgInstances() {
|
||||||
|
return damageDoneThisTurn;
|
||||||
|
}
|
||||||
|
|
||||||
public void newTurn() {
|
public void newTurn() {
|
||||||
attackedThisTurn.clear();
|
attackedThisTurn.clear();
|
||||||
attackedBattleThisTurn = false;
|
attackedBattleThisTurn = false;
|
||||||
|
|||||||
@@ -132,32 +132,34 @@ public class PlayerProperty {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (property.startsWith("wasDealt")) {
|
} else if (property.startsWith("wasDealt")) {
|
||||||
boolean found = false;
|
|
||||||
String validCard = null;
|
|
||||||
Boolean combat = null;
|
Boolean combat = null;
|
||||||
if (property.contains("CombatDamage")) {
|
if (property.contains("CombatDamage")) {
|
||||||
combat = true;
|
combat = true;
|
||||||
}
|
}
|
||||||
if (property.contains("ThisTurnBySource")) {
|
String validCard = null;
|
||||||
found = source.getDamageHistory().getDamageDoneThisTurn(combat, validCard == null, validCard, "You", source, player, spellAbility) > 0;
|
String comp = "GE";
|
||||||
} else {
|
int right = 1;
|
||||||
String comp = "GE";
|
|
||||||
int right = 1;
|
|
||||||
int numValid = 0;
|
|
||||||
|
|
||||||
if (property.contains("ThisTurnBy")) {
|
if (property.contains("ThisTurnBy")) {
|
||||||
String[] props = property.split(" ");
|
int idx = 2;
|
||||||
|
String[] props = property.split(" ");
|
||||||
|
if (property.contains("BySource")) {
|
||||||
|
idx--;
|
||||||
|
} else {
|
||||||
validCard = props[1];
|
validCard = props[1];
|
||||||
if (props.length > 2) {
|
|
||||||
comp = props[2].substring(0, 2);
|
|
||||||
right = AbilityUtils.calculateAmount(source, props[2].substring(2), spellAbility);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (props.length > idx) {
|
||||||
numValid = game.getDamageDoneThisTurn(combat, validCard == null, validCard, "You", source, player, spellAbility).size();
|
comp = props[idx].substring(0, 2);
|
||||||
found = Expressions.compare(numValid, comp, right);
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (property.equals("attackedBySourceThisCombat")) {
|
} else if (property.equals("attackedBySourceThisCombat")) {
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ import java.util.Map;
|
|||||||
import forge.game.ability.AbilityKey;
|
import forge.game.ability.AbilityKey;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.card.CardCopyService;
|
import forge.game.card.CardCopyService;
|
||||||
import forge.game.player.Player;
|
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
import forge.util.Expressions;
|
import forge.util.Expressions;
|
||||||
import forge.util.Localizer;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ PT:3/3
|
|||||||
K:Trample
|
K:Trample
|
||||||
T:Mode$ DamageDealtOnce | ValidSource$ Card.Self | Execute$ TrigPutCounter | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME deals damage, put a +1/+1 counter on it.
|
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
|
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
|
SVar:TrigLose:DB$ LosesGame | Defined$ TriggeredTarget
|
||||||
DeckHas:Ability$Counters
|
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.
|
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.
|
||||||
|
|||||||
@@ -2,6 +2,6 @@ Name:Impact Resonance
|
|||||||
ManaCost:1 R
|
ManaCost:1 R
|
||||||
Types:Instant
|
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.
|
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
|
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.
|
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.
|
||||||
|
|||||||
@@ -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.
|
||||||
Reference in New Issue
Block a user