mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-16 18:58:00 +00:00
Merge pull request #617 from tool4ever/thefallen
Fix The Fallen ignoring planeswalkers
This commit is contained in:
@@ -752,14 +752,16 @@ public class CountersPutAi extends CountersAi {
|
|||||||
final int amount = AbilityUtils.calculateAmount(source, amountStr, sa);
|
final int amount = AbilityUtils.calculateAmount(source, amountStr, sa);
|
||||||
int left = amount;
|
int left = amount;
|
||||||
final String[] types;
|
final String[] types;
|
||||||
|
String type = "";
|
||||||
if (sa.hasParam("CounterType")) {
|
if (sa.hasParam("CounterType")) {
|
||||||
// TODO some cards let you choose types, should check each
|
// TODO some cards let you choose types, should check each
|
||||||
types = sa.getParam("CounterType").split(",");
|
types = sa.getParam("CounterType").split(",");
|
||||||
} else {
|
type = types[0];
|
||||||
|
} else if (sa.hasParam("CounterTypes")) {
|
||||||
// all types will be added
|
// all types will be added
|
||||||
types = sa.getParam("CounterTypes").split(",");
|
types = sa.getParam("CounterTypes").split(",");
|
||||||
|
type = types[0];
|
||||||
}
|
}
|
||||||
final String type = types[0];
|
|
||||||
|
|
||||||
if (!sa.usesTargeting()) {
|
if (!sa.usesTargeting()) {
|
||||||
// No target. So must be defined
|
// No target. So must be defined
|
||||||
|
|||||||
@@ -94,10 +94,12 @@ public class GameEntityCounterTable extends ForwardingTable<Optional<Player>, Ga
|
|||||||
for (Map<CounterType, Integer> cm : gm.getValue().values()) {
|
for (Map<CounterType, Integer> cm : gm.getValue().values()) {
|
||||||
Integer old = ObjectUtils.firstNonNull(result.get(gm.getKey()), 0);
|
Integer old = ObjectUtils.firstNonNull(result.get(gm.getKey()), 0);
|
||||||
Integer v = ObjectUtils.firstNonNull(cm.get(type), 0);
|
Integer v = ObjectUtils.firstNonNull(cm.get(type), 0);
|
||||||
|
if (old + v > 0) {
|
||||||
result.put(gm.getKey(), old + v);
|
result.put(gm.getKey(), old + v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ import com.google.common.collect.Maps;
|
|||||||
|
|
||||||
import forge.game.GameEntity;
|
import forge.game.GameEntity;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
|
import forge.game.zone.ZoneType;
|
||||||
|
import forge.util.collect.FCollection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: Write javadoc for this type.
|
* TODO: Write javadoc for this type.
|
||||||
@@ -19,7 +21,8 @@ public class CardDamageHistory {
|
|||||||
private boolean creatureAttackedThisCombat = false;
|
private boolean creatureAttackedThisCombat = false;
|
||||||
private boolean creatureBlockedThisCombat = false;
|
private boolean creatureBlockedThisCombat = false;
|
||||||
private boolean creatureGotBlockedThisCombat = false;
|
private boolean creatureGotBlockedThisCombat = false;
|
||||||
private boolean receivedNonCombatDamageThisTurn = false;
|
|
||||||
|
boolean hasdealtDamagetoAny = false;
|
||||||
private List<GameEntity> attackedThisTurn = Lists.newArrayList();
|
private List<GameEntity> attackedThisTurn = Lists.newArrayList();
|
||||||
|
|
||||||
private final List<Player> creatureAttackedLastTurnOf = Lists.newArrayList();
|
private final List<Player> creatureAttackedLastTurnOf = Lists.newArrayList();
|
||||||
@@ -27,13 +30,17 @@ public class CardDamageHistory {
|
|||||||
private final List<Player> NotBlockedSinceLastUpkeepOf = Lists.newArrayList();
|
private final List<Player> NotBlockedSinceLastUpkeepOf = Lists.newArrayList();
|
||||||
private final List<Player> NotBeenBlockedSinceLastUpkeepOf = Lists.newArrayList();
|
private final List<Player> NotBeenBlockedSinceLastUpkeepOf = Lists.newArrayList();
|
||||||
|
|
||||||
private final Map<GameEntity, Integer> damagedThisCombat = Maps.newHashMap();
|
// only needed for Glen Elendra (Plane)
|
||||||
|
private final List<Player> damagedThisCombat = Lists.newArrayList();
|
||||||
|
// only needed for The Fallen
|
||||||
|
private final FCollection<GameEntity> damagedThisGame = new FCollection<>();
|
||||||
|
|
||||||
private final Map<GameEntity, Integer> damagedThisTurn = Maps.newHashMap();
|
private final Map<GameEntity, Integer> damagedThisTurn = Maps.newHashMap();
|
||||||
private final Map<GameEntity, Integer> damagedThisTurnInCombat = Maps.newHashMap();
|
private final Map<GameEntity, Integer> damagedThisTurnInCombat = Maps.newHashMap();
|
||||||
private final Map<GameEntity, Integer> damagedThisGame = Maps.newHashMap();
|
private boolean receivedNonCombatDamageThisTurn = false;
|
||||||
|
|
||||||
public final boolean getHasdealtDamagetoAny() {
|
public final boolean getHasdealtDamagetoAny() {
|
||||||
return !damagedThisGame.isEmpty();
|
return hasdealtDamagetoAny;
|
||||||
}
|
}
|
||||||
|
|
||||||
// used to see if an attacking creature with a triggering attack ability
|
// used to see if an attacking creature with a triggering attack ability
|
||||||
@@ -241,7 +248,7 @@ public class CardDamageHistory {
|
|||||||
this.receivedNonCombatDamageThisTurn = b;
|
this.receivedNonCombatDamageThisTurn = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final Map<GameEntity, Integer> getThisCombatDamaged() {
|
public final List<Player> getThisCombatDamaged() {
|
||||||
return damagedThisCombat;
|
return damagedThisCombat;
|
||||||
}
|
}
|
||||||
public final Map<GameEntity, Integer> getThisTurnDamaged() {
|
public final Map<GameEntity, Integer> getThisTurnDamaged() {
|
||||||
@@ -250,7 +257,7 @@ public class CardDamageHistory {
|
|||||||
public final Map<GameEntity, Integer> getThisTurnCombatDamaged() {
|
public final Map<GameEntity, Integer> getThisTurnCombatDamaged() {
|
||||||
return damagedThisTurnInCombat;
|
return damagedThisTurnInCombat;
|
||||||
}
|
}
|
||||||
public final Map<GameEntity, Integer> getThisGameDamaged() {
|
public final FCollection<GameEntity> getThisGameDamaged() {
|
||||||
return damagedThisGame;
|
return damagedThisGame;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@@ -259,29 +266,15 @@ public class CardDamageHistory {
|
|||||||
*/
|
*/
|
||||||
public void registerCombatDamage(GameEntity entity, int amount) {
|
public void registerCombatDamage(GameEntity entity, int amount) {
|
||||||
int old = 0;
|
int old = 0;
|
||||||
if (damagedThisCombat.containsKey(entity)) {
|
if (entity instanceof Player) {
|
||||||
old = damagedThisCombat.get(entity);
|
damagedThisCombat.add((Player) entity);
|
||||||
}
|
}
|
||||||
damagedThisCombat.put(entity, old + amount);
|
|
||||||
old = 0;
|
old = 0;
|
||||||
if (damagedThisTurnInCombat.containsKey(entity)) {
|
if (damagedThisTurnInCombat.containsKey(entity)) {
|
||||||
old = damagedThisTurnInCombat.get(entity);
|
old = damagedThisTurnInCombat.get(entity);
|
||||||
}
|
}
|
||||||
damagedThisTurnInCombat.put(entity, old + amount);
|
damagedThisTurnInCombat.put(entity, old + amount);
|
||||||
}
|
hasdealtDamagetoAny = true;
|
||||||
/**
|
|
||||||
* TODO: Write javadoc for this method.
|
|
||||||
*/
|
|
||||||
public void newTurn() {
|
|
||||||
damagedThisCombat.clear();
|
|
||||||
damagedThisTurnInCombat.clear();
|
|
||||||
damagedThisTurn.clear();
|
|
||||||
attackedThisTurn.clear();
|
|
||||||
setHasBeenDealtNonCombatDamageThisTurn(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void endCombat() {
|
|
||||||
damagedThisCombat.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -294,11 +287,30 @@ public class CardDamageHistory {
|
|||||||
old = damagedThisTurn.get(entity);
|
old = damagedThisTurn.get(entity);
|
||||||
}
|
}
|
||||||
damagedThisTurn.put(entity, old + amount);
|
damagedThisTurn.put(entity, old + amount);
|
||||||
old = 0;
|
damagedThisGame.add(entity);
|
||||||
if (damagedThisGame.containsKey(entity)) {
|
hasdealtDamagetoAny = true;
|
||||||
old = damagedThisGame.get(entity);
|
|
||||||
}
|
|
||||||
damagedThisGame.put(entity, old + amount);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void newTurn() {
|
||||||
|
damagedThisCombat.clear();
|
||||||
|
damagedThisTurnInCombat.clear();
|
||||||
|
damagedThisTurn.clear();
|
||||||
|
attackedThisTurn.clear();
|
||||||
|
|
||||||
|
// if card already LTB we can safely dereference (allows quite a few objects to be cleaned up earlier for bigger boardstates)
|
||||||
|
CardCollection toRemove = new CardCollection();
|
||||||
|
for (GameEntity e : damagedThisGame) {
|
||||||
|
if (e instanceof Card) {
|
||||||
|
if (((Card) e).getZone().getZoneType() != ZoneType.Battlefield) {
|
||||||
|
toRemove.add((Card)e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
damagedThisGame.removeAll(toRemove);
|
||||||
|
setHasBeenDealtNonCombatDamageThisTurn(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void endCombat() {
|
||||||
|
damagedThisCombat.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1160,7 +1160,7 @@ public class CardProperty {
|
|||||||
} else if (property.startsWith("dealtCombatDamage") || property.startsWith("notDealtCombatDamage")) {
|
} else if (property.startsWith("dealtCombatDamage") || property.startsWith("notDealtCombatDamage")) {
|
||||||
final String[] v = property.split(" ")[1].split(",");
|
final String[] v = property.split(" ")[1].split(",");
|
||||||
final Iterable<GameEntity> list = property.contains("ThisCombat") ?
|
final Iterable<GameEntity> list = property.contains("ThisCombat") ?
|
||||||
card.getDamageHistory().getThisCombatDamaged().keySet() :
|
Lists.newArrayList(card.getDamageHistory().getThisCombatDamaged()) :
|
||||||
card.getDamageHistory().getThisTurnCombatDamaged().keySet();
|
card.getDamageHistory().getThisTurnCombatDamaged().keySet();
|
||||||
boolean found = Iterables.any(list, GameObjectPredicates.restriction(v, sourceController, source, spellAbility));
|
boolean found = Iterables.any(list, GameObjectPredicates.restriction(v, sourceController, source, spellAbility));
|
||||||
if (found == property.startsWith("not")) {
|
if (found == property.startsWith("not")) {
|
||||||
@@ -1182,6 +1182,15 @@ public class CardProperty {
|
|||||||
if (!card.getDamageHistory().hasBeenDealtNonCombatDamageThisTurn()) {
|
if (!card.getDamageHistory().hasBeenDealtNonCombatDamageThisTurn()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
} else if (property.startsWith("wasDealtDamageByThisGame")) {
|
||||||
|
int idx = source.getDamageHistory().getThisGameDamaged().indexOf(card);
|
||||||
|
if (idx == -1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Card c = (Card) source.getDamageHistory().getThisGameDamaged().get(idx);
|
||||||
|
if (!c.equalsWithTimestamp(game.getCardState(card))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
} else if (property.startsWith("dealtDamageThisTurn")) {
|
} else if (property.startsWith("dealtDamageThisTurn")) {
|
||||||
if (card.getTotalDamageDoneBy() == 0) {
|
if (card.getTotalDamageDoneBy() == 0) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ public class PlayerProperty {
|
|||||||
final List<Card> cards = AbilityUtils.getDefinedCards(source, v, spellAbility);
|
final List<Card> cards = AbilityUtils.getDefinedCards(source, v, spellAbility);
|
||||||
int found = 0;
|
int found = 0;
|
||||||
for (final Card card : cards) {
|
for (final Card card : cards) {
|
||||||
if (card.getDamageHistory().getThisCombatDamaged().containsKey(player)) {
|
if (card.getDamageHistory().getThisCombatDamaged().contains(player)) {
|
||||||
found++;
|
found++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -113,7 +113,7 @@ public class PlayerProperty {
|
|||||||
final List<Card> cards = AbilityUtils.getDefinedCards(source, v, spellAbility);
|
final List<Card> cards = AbilityUtils.getDefinedCards(source, v, spellAbility);
|
||||||
int found = 0;
|
int found = 0;
|
||||||
for (final Card card : cards) {
|
for (final Card card : cards) {
|
||||||
if (card.getDamageHistory().getThisGameDamaged().containsKey(player)) {
|
if (card.getDamageHistory().getThisGameDamaged().contains(player)) {
|
||||||
found++;
|
found++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ K:Flying
|
|||||||
T:Mode$ DamageDone | ValidSource$ Card.Self | Execute$ TrigRoll | CombatDamage$ True | ValidTarget$ Player | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME deals combat damage to a player, roll a d20. When you do, put any number of target creature cards with total mana value X or less from graveyards onto the battlefield under your control, where X is the result.
|
T:Mode$ DamageDone | ValidSource$ Card.Self | Execute$ TrigRoll | CombatDamage$ True | ValidTarget$ Player | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME deals combat damage to a player, roll a d20. When you do, put any number of target creature cards with total mana value X or less from graveyards onto the battlefield under your control, where X is the result.
|
||||||
SVar:TrigRoll:DB$ RollDice | ResultSVar$ Result | Sides$ 20 | SubAbility$ DBImmediateTrigger
|
SVar:TrigRoll:DB$ RollDice | ResultSVar$ Result | Sides$ 20 | SubAbility$ DBImmediateTrigger
|
||||||
SVar:DBImmediateTrigger:DB$ ImmediateTrigger | Execute$ TrigChangeZone | RememberSVarAmount$ Result | TriggerDescription$ When you do, put any number of target creature cards with total mana value X or less from graveyards onto the battlefield under your control, where X is the result.
|
SVar:DBImmediateTrigger:DB$ ImmediateTrigger | Execute$ TrigChangeZone | RememberSVarAmount$ Result | TriggerDescription$ When you do, put any number of target creature cards with total mana value X or less from graveyards onto the battlefield under your control, where X is the result.
|
||||||
SVar:TrigChangeZone:DB$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield | TargetMin$ 0 | TargetMax$ Y | ValidTgts$ Creature | TgtPrompt$ Select any number of target creature cards with total mana value X or less from graveyards | WithTotalCMC$ X | GainControl$ True
|
SVar:TrigChangeZone:DB$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield | TargetMin$ 0 | TargetMax$ Y | ValidTgts$ Creature | TgtPrompt$ Select any number of target creature cards with total mana value X or less from graveyards | MaxTotalTargetCMC$ X | GainControl$ True
|
||||||
SVar:X:Count$TriggerRememberAmount
|
SVar:X:Count$TriggerRememberAmount
|
||||||
SVar:Y:Count$TypeInAllYards.Creature
|
SVar:Y:Count$TypeInAllYards.Creature
|
||||||
DeckHas:Ability$Graveyard
|
DeckHas:Ability$Graveyard
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ Name:Bess, Soul Nourisher
|
|||||||
ManaCost:1 G W
|
ManaCost:1 G W
|
||||||
Types:Legendary Creature Human Citizen
|
Types:Legendary Creature Human Citizen
|
||||||
PT:1/1
|
PT:1/1
|
||||||
T:Mode$ ChangesZoneAll | ValidCards$ Creature.basePowerEQ1+baseToughnessEQ1+Other | Destination$ Battlefield | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ Whenever one or more other creatures with base power and toughness 1/1 enter the battlefield under your control, put a +1/+1 counter on CARDNAME.
|
T:Mode$ ChangesZoneAll | ValidCards$ Creature.basePowerEQ1+baseToughnessEQ1+Other+YouCtrl | Destination$ Battlefield | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ Whenever one or more other creatures with base power and toughness 1/1 enter the battlefield under your control, put a +1/+1 counter on CARDNAME.
|
||||||
SVar:TrigPutCounter:DB$ PutCounter | CounterType$ P1P1
|
SVar:TrigPutCounter:DB$ PutCounter | CounterType$ P1P1
|
||||||
T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigPumpAll | TriggerDescription$ Whenever NICKNAME attacks, each other creature you control with base power and toughness 1/1 gets +X/+X until end of turn, where X is the number of +1/+1 counters on NICKNAME.
|
T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigPumpAll | TriggerDescription$ Whenever NICKNAME attacks, each other creature you control with base power and toughness 1/1 gets +X/+X until end of turn, where X is the number of +1/+1 counters on NICKNAME.
|
||||||
SVar:TrigPumpAll:DB$ PumpAll | ValidCards$ Creature.basePowerEQ1+baseToughnessEQ1+Other | NumAtt$ +X | NumDef$ +X
|
SVar:TrigPumpAll:DB$ PumpAll | ValidCards$ Creature.basePowerEQ1+baseToughnessEQ1+Other | NumAtt$ +X | NumDef$ +X
|
||||||
|
|||||||
@@ -3,5 +3,5 @@ ManaCost:1 B B B
|
|||||||
Types:Creature Zombie
|
Types:Creature Zombie
|
||||||
PT:2/3
|
PT:2/3
|
||||||
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | Execute$ TrigDamage | TriggerZones$ Battlefield | TriggerDescription$ At the beginning of your upkeep, CARDNAME deals 1 damage to each opponent and planeswalker it has dealt damage to this game.
|
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | Execute$ TrigDamage | TriggerZones$ Battlefield | TriggerDescription$ At the beginning of your upkeep, CARDNAME deals 1 damage to each opponent and planeswalker it has dealt damage to this game.
|
||||||
SVar:TrigDamage:DB$ DealDamage | Defined$ Player.Opponent+wasDealtDamageThisGameBy Self | NumDmg$ 1
|
SVar:TrigDamage:DB$ DamageAll | ValidPlayers$ Player.Opponent+wasDealtDamageThisGameBy Self | ValidCards$ Planeswalker.wasDealtDamageByThisGame | NumDmg$ 1
|
||||||
Oracle:At the beginning of your upkeep, The Fallen deals 1 damage to each opponent and planeswalker it has dealt damage to this game.
|
Oracle:At the beginning of your upkeep, The Fallen deals 1 damage to each opponent and planeswalker it has dealt damage to this game.
|
||||||
|
|||||||
Reference in New Issue
Block a user