mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 11:18:01 +00:00
Merge branch 'counterGameCheck' into 'master'
Put Counter Effects check Game State Closes #548 See merge request core-developers/forge!568
This commit is contained in:
@@ -543,15 +543,19 @@ public class Game {
|
||||
return found == null;
|
||||
}
|
||||
|
||||
public Card getFound() {
|
||||
return found == null ? old : found;
|
||||
public Card getFound(final Card notFound) {
|
||||
return found == null ? notFound : found;
|
||||
}
|
||||
}
|
||||
|
||||
public Card getCardState(final Card card) {
|
||||
return getCardState(card, card);
|
||||
}
|
||||
|
||||
public Card getCardState(final Card card, final Card notFound) {
|
||||
CardStateVisitor visit = new CardStateVisitor(card);
|
||||
this.forEachCardInGame(visit);
|
||||
return visit.getFound();
|
||||
return visit.getFound(notFound);
|
||||
}
|
||||
|
||||
// Allows visiting cards in game without allocating a temporary list.
|
||||
|
||||
@@ -95,8 +95,8 @@ public class CountersMoveEffect extends SpellAbilityEffect {
|
||||
return;
|
||||
}
|
||||
|
||||
Card cur = game.getCardState(dest);
|
||||
if (cur.getTimestamp() != dest.getTimestamp()) {
|
||||
Card cur = game.getCardState(dest, null);
|
||||
if (cur == null || !cur.equalsWithTimestamp(dest)) {
|
||||
// Test to see if the card we're trying to add is in the expected state
|
||||
return;
|
||||
}
|
||||
@@ -185,8 +185,8 @@ public class CountersMoveEffect extends SpellAbilityEffect {
|
||||
continue;
|
||||
}
|
||||
|
||||
Card cur = game.getCardState(dest);
|
||||
if (cur.getTimestamp() != dest.getTimestamp()) {
|
||||
Card cur = game.getCardState(dest, null);
|
||||
if (cur == null || !cur.equalsWithTimestamp(dest)) {
|
||||
// Test to see if the card we're trying to add is in the expected state
|
||||
continue;
|
||||
}
|
||||
@@ -238,8 +238,8 @@ public class CountersMoveEffect extends SpellAbilityEffect {
|
||||
if (source.equals(dest)) {
|
||||
continue;
|
||||
}
|
||||
Card cur = game.getCardState(dest);
|
||||
if (cur.getTimestamp() != dest.getTimestamp()) {
|
||||
Card cur = game.getCardState(dest, null);
|
||||
if (cur == null || !cur.equalsWithTimestamp(dest)) {
|
||||
// Test to see if the card we're trying to add is in the expected state
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -42,14 +42,21 @@ public class CountersMultiplyEffect extends SpellAbilityEffect {
|
||||
final int n = Integer.valueOf(sa.getParamOrDefault("Multiplier", "2")) - 1;
|
||||
|
||||
for (final Card tgtCard : getTargetCards(sa)) {
|
||||
Card gameCard = game.getCardState(tgtCard, null);
|
||||
// gameCard is LKI in that case, the card is not in game anymore
|
||||
// or the timestamp did change
|
||||
// this should check Self too
|
||||
if (gameCard == null || !tgtCard.equalsWithTimestamp(gameCard)) {
|
||||
continue;
|
||||
}
|
||||
if (counterType != null) {
|
||||
tgtCard.addCounter(counterType, tgtCard.getCounters(counterType) * n, host, true);
|
||||
gameCard.addCounter(counterType, gameCard.getCounters(counterType) * n, host, true);
|
||||
} else {
|
||||
for (Map.Entry<CounterType, Integer> e : tgtCard.getCounters().entrySet()) {
|
||||
tgtCard.addCounter(e.getKey(), e.getValue() * n, host, true);
|
||||
for (Map.Entry<CounterType, Integer> e : gameCard.getCounters().entrySet()) {
|
||||
gameCard.addCounter(e.getKey(), e.getValue() * n, host, true);
|
||||
}
|
||||
}
|
||||
game.updateLastStateForCard(tgtCard);
|
||||
game.updateLastStateForCard(gameCard);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -128,6 +128,18 @@ public class CountersPutEffect extends SpellAbilityEffect {
|
||||
}
|
||||
|
||||
for (final GameObject obj : tgtObjects) {
|
||||
// check if the object is still in game or if it was moved
|
||||
if (obj instanceof Card) {
|
||||
Card tgtCard = (Card) obj;
|
||||
Card gameCard = game.getCardState(tgtCard, null);
|
||||
// gameCard is LKI in that case, the card is not in game anymore
|
||||
// or the timestamp did change
|
||||
// this should check Self too
|
||||
if (gameCard == null || !tgtCard.equalsWithTimestamp(gameCard)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (existingCounter) {
|
||||
final List<CounterType> choices = Lists.newArrayList();
|
||||
if (obj instanceof GameEntity) {
|
||||
@@ -186,11 +198,22 @@ public class CountersPutEffect extends SpellAbilityEffect {
|
||||
// this check needs to check if this card would be on the battlefield
|
||||
noTributeLKI.setLastKnownZone(activator.getZone(ZoneType.Battlefield));
|
||||
|
||||
// double freeze tracker, so it doesn't update view
|
||||
game.getTracker().freeze();
|
||||
|
||||
CardCollection preList = new CardCollection(noTributeLKI);
|
||||
game.getAction().checkStaticAbilities(false, Sets.newHashSet(noTributeLKI), preList);
|
||||
|
||||
boolean abort = !noTributeLKI.canReceiveCounters(counterType);
|
||||
|
||||
game.getAction().checkStaticAbilities(false);
|
||||
// clear delayed changes, this check should not have updated the view
|
||||
game.getTracker().clearDelayed();
|
||||
// need to unfreeze tracker
|
||||
game.getTracker().unfreeze();
|
||||
|
||||
// check if it can recive the Tribute
|
||||
if (!noTributeLKI.canReceiveCounters(counterType)) {
|
||||
if (abort) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -225,9 +248,9 @@ public class CountersPutEffect extends SpellAbilityEffect {
|
||||
}
|
||||
if (sa.hasParam("Monstrosity")) {
|
||||
tgtCard.setMonstrous(true);
|
||||
tgtCard.setMonstrosityNum(counterAmount);
|
||||
final Map<String, Object> runParams = Maps.newHashMap();
|
||||
runParams.put("Card", tgtCard);
|
||||
runParams.put("MonstrosityAmount", counterAmount);
|
||||
game.getTriggerHandler().runTrigger(TriggerType.BecomeMonstrous, runParams, false);
|
||||
}
|
||||
if (sa.hasParam("Renown")) {
|
||||
|
||||
@@ -57,6 +57,13 @@ public class CountersPutOrRemoveEffect extends SpellAbilityEffect {
|
||||
}
|
||||
|
||||
for (final Card tgtCard : getDefinedCardsOrTargeted(sa)) {
|
||||
Card gameCard = game.getCardState(tgtCard, null);
|
||||
// gameCard is LKI in that case, the card is not in game anymore
|
||||
// or the timestamp did change
|
||||
// this should check Self too
|
||||
if (gameCard == null || !tgtCard.equalsWithTimestamp(gameCard)) {
|
||||
continue;
|
||||
}
|
||||
if (!sa.usesTargeting() || tgtCard.canBeTargetedBy(sa)) {
|
||||
if (tgtCard.hasCounters()) {
|
||||
if (sa.hasParam("EachExistingCounter")) {
|
||||
|
||||
@@ -108,8 +108,15 @@ public class CountersRemoveEffect extends SpellAbilityEffect {
|
||||
}
|
||||
|
||||
for (final Card tgtCard : getTargetCards(sa)) {
|
||||
Card gameCard = game.getCardState(tgtCard, null);
|
||||
// gameCard is LKI in that case, the card is not in game anymore
|
||||
// or the timestamp did change
|
||||
// this should check Self too
|
||||
if (gameCard == null || !tgtCard.equalsWithTimestamp(gameCard)) {
|
||||
continue;
|
||||
}
|
||||
if (!sa.usesTargeting() || tgtCard.canBeTargetedBy(sa)) {
|
||||
final Zone zone = game.getZoneOf(tgtCard);
|
||||
final Zone zone = game.getZoneOf(gameCard);
|
||||
if (type.equals("All")) {
|
||||
for (Map.Entry<CounterType, Integer> e : tgtCard.getCounters().entrySet()) {
|
||||
tgtCard.subtractCounter(e.getKey(), e.getValue());
|
||||
|
||||
@@ -154,7 +154,6 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
private boolean unearthed;
|
||||
|
||||
private boolean monstrous = false;
|
||||
private int monstrosityNum = 0;
|
||||
|
||||
private boolean renowned = false;
|
||||
|
||||
@@ -4725,13 +4724,6 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
monstrous = monstrous0;
|
||||
}
|
||||
|
||||
public final int getMonstrosityNum() {
|
||||
return monstrosityNum;
|
||||
}
|
||||
public final void setMonstrosityNum(final int num) {
|
||||
monstrosityNum = num;
|
||||
}
|
||||
|
||||
public final boolean isRenowned() {
|
||||
return renowned;
|
||||
}
|
||||
|
||||
@@ -1017,11 +1017,6 @@ public class CardFactoryUtil {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Count$MonstrosityMagnitude
|
||||
if (sq[0].contains("MonstrosityMagnitude")) {
|
||||
return doXMath(c.getMonstrosityNum(), m, c);
|
||||
}
|
||||
|
||||
// Count$Chroma.<color name>
|
||||
// Count$Devotion.<color name>
|
||||
if (sq[0].contains("Chroma") || sq[0].equals("Devotion")) {
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
*/
|
||||
package forge.game.trigger;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import forge.game.card.Card;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
|
||||
@@ -42,15 +44,15 @@ public class TriggerBecomeMonstrous extends Trigger {
|
||||
* @param intrinsic
|
||||
* the intrinsic
|
||||
*/
|
||||
public TriggerBecomeMonstrous(final java.util.Map<String, String> params, final Card host, final boolean intrinsic) {
|
||||
public TriggerBecomeMonstrous(Map<String, String> params, final Card host, final boolean intrinsic) {
|
||||
super(params, host, intrinsic);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public final boolean performTest(final java.util.Map<String, Object> runParams2) {
|
||||
if (this.mapParams.containsKey("ValidCard")) {
|
||||
if (!matchesValid(runParams2.get("Card"), this.mapParams.get("ValidCard").split(","),
|
||||
public final boolean performTest(Map<String, Object> runParams2) {
|
||||
if (hasParam("ValidCard")) {
|
||||
if (!matchesValid(runParams2.get("Card"), getParam("ValidCard").split(","),
|
||||
this.getHostCard())) {
|
||||
return false;
|
||||
}
|
||||
@@ -62,7 +64,8 @@ public class TriggerBecomeMonstrous extends Trigger {
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public final void setTriggeringObjects(final SpellAbility sa) {
|
||||
sa.setTriggeringObject("Card", this.getRunParams().get("Card"));
|
||||
sa.setTriggeringObject("Card", getRunParams().get("Card"));
|
||||
sa.setTriggeringObject("MonstrosityAmount", getRunParams().get("MonstrosityAmount"));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -52,6 +52,10 @@ public class Tracker {
|
||||
delayedPropChanges.add(new DelayedPropChange(object, prop, value));
|
||||
}
|
||||
|
||||
public void clearDelayed() {
|
||||
delayedPropChanges.clear();
|
||||
}
|
||||
|
||||
private class DelayedPropChange {
|
||||
private final TrackableObject object;
|
||||
private final TrackableProperty prop;
|
||||
|
||||
Reference in New Issue
Block a user