Merge branch 'removeRememberMap' into 'master'

Remove RememberMap, use EnteredSinceYourLastTurn instead

See merge request core-developers/forge!4201
This commit is contained in:
Michael Kamensky
2021-03-15 13:07:58 +00:00
22 changed files with 38 additions and 122 deletions

View File

@@ -153,7 +153,6 @@ public enum SpellApiToAi {
.put(ApiType.SetState, SetStateAi.class)
.put(ApiType.Shuffle, ShuffleAi.class)
.put(ApiType.SkipTurn, SkipTurnAi.class)
.put(ApiType.StoreMap, StoreMapAi.class)
.put(ApiType.StoreSVar, StoreSVarAi.class)
.put(ApiType.Subgame, AlwaysPlayAi.class)
.put(ApiType.Surveil, SurveilAi.class)

View File

@@ -1,21 +0,0 @@
package forge.ai.ability;
import forge.ai.SpellAbilityAi;
import forge.game.player.Player;
import forge.game.spellability.SpellAbility;
public class StoreMapAi extends SpellAbilityAi {
@Override
protected boolean canPlayAI(Player ai, SpellAbility sa) {
return true;
}
@Override
protected boolean doTriggerAINoCost(Player aiPlayer, SpellAbility sa, boolean mandatory) {
return true;
}
}

View File

@@ -155,7 +155,6 @@ public enum ApiType {
Shuffle (ShuffleEffect.class),
SkipTurn (SkipTurnEffect.class),
StoreSVar (StoreSVarEffect.class),
StoreMap (StoreMapEffect.class),
Subgame (SubgameEffect.class),
Surveil (SurveilEffect.class),
SwitchBlock (SwitchBlockEffect.class),

View File

@@ -1,44 +0,0 @@
package forge.game.ability.effects;
import java.util.ArrayList;
import java.util.List;
import forge.game.GameEntity;
import forge.game.ability.AbilityUtils;
import forge.game.ability.SpellAbilityEffect;
import forge.game.card.Card;
import forge.game.spellability.SpellAbility;
public class StoreMapEffect extends SpellAbilityEffect {
@Override
public void resolve(SpellAbility sa) {
final Card source = sa.getHostCard();
List<GameEntity> entity = new ArrayList<>();
List<Object> objects = new ArrayList<>();
if (sa.hasParam("RememberEntity")) {
entity.addAll(AbilityUtils.getDefinedPlayers(source, sa.getParam("RememberEntity"), sa));
entity.addAll(AbilityUtils.getDefinedCards(source, sa.getParam("RememberEntity"), sa));
}
if (sa.hasParam("RememberObjects")) {
String type = sa.hasParam("ObjectType") ? sa.getParam("ObjectType") : "Card";
if (type.equals("Card")) {
objects.addAll(AbilityUtils.getDefinedCards(source, sa.getParam("RememberObjects"), sa));
}
}
for (GameEntity e : entity) {
source.addRememberMap(e, objects);
}
if (sa.hasParam("Clear")) {
for (GameEntity e : entity) {
source.getRememberMap().get(e).clear();
}
}
}
}

View File

@@ -58,8 +58,6 @@ import forge.trackable.Tracker;
import forge.util.*;
import forge.util.collect.FCollection;
import forge.util.collect.FCollectionView;
import forge.util.maps.HashMapOfLists;
import forge.util.maps.MapOfLists;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.mutable.MutableBoolean;
import org.apache.commons.lang3.tuple.Pair;
@@ -144,7 +142,6 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
private Map<String, String> originalSVars = Maps.newHashMap();
private final Set<Object> rememberedObjects = Sets.newLinkedHashSet();
private final MapOfLists<GameEntity, Object> rememberMap = new HashMapOfLists<>(CollectionSuppliers.arrayLists());
private Map<Player, String> flipResult;
private Map<Card, Integer> receivedDamageFromThisTurn = Maps.newHashMap();
@@ -940,13 +937,6 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
convokedCards = null;
}
public MapOfLists<GameEntity, Object> getRememberMap() {
return rememberMap;
}
public final void addRememberMap(final GameEntity e, final List<Object> o) {
rememberMap.addAll(e, o);
}
public final Iterable<Object> getRemembered() {
return rememberedObjects;
}

View File

@@ -1000,11 +1000,20 @@ public class CardProperty {
}
}
return false;
} else if (property.equals("EnteredSinceYourLastTurn")) {
if (card.getTurnInZone() > controller.getLastTurnNr()) {
return false;
}
} else if (property.equals("ThisTurnEntered")) {
// only check if it entered the Zone this turn
if (card.getTurnInZone() != game.getPhaseHandler().getTurn()) {
return false;
}
} else if (property.equals("NotThisTurnEntered")) {
// only check if it entered the Zone this turn
if (card.getTurnInZone() == game.getPhaseHandler().getTurn()) {
return false;
}
} else if (property.startsWith("ThisTurnEnteredFrom")) {
final String restrictions = property.split("ThisTurnEnteredFrom_")[1];
final String[] res = restrictions.split("_");
@@ -1098,14 +1107,6 @@ public class CardProperty {
if (card.getDrawnThisTurn()) {
return false;
}
} else if (property.startsWith("enteredBattlefieldThisTurn")) {
if (!(card.getTurnInZone() == game.getPhaseHandler().getTurn())) {
return false;
}
} else if (property.startsWith("notEnteredBattlefieldThisTurn")) {
if (card.getTurnInZone() == game.getPhaseHandler().getTurn()) {
return false;
}
} else if (property.startsWith("firstTurnControlled")) {
if (!card.isFirstTurnControlled()) {
return false;
@@ -1706,19 +1707,6 @@ public class CardProperty {
if (card.isRenowned()) {
return false;
}
} else if (property.startsWith("RememberMap")) {
System.out.println(source.getRememberMap());
for (SpellAbility sa : source.getSpellAbilities()) {
if (sa.getActivatingPlayer() == null) continue;
for (Player p : AbilityUtils.getDefinedPlayers(source, property.split("RememberMap_")[1], sa)) {
if (source.getRememberMap() != null && source.getRememberMap().get(p) != null) {
if (source.getRememberMap().get(p).contains(card)) {
return true;
}
}
}
}
return false;
} else if (property.equals("IsRemembered")) {
if (!source.isRemembered(card)) {
return false;

View File

@@ -114,6 +114,9 @@ public class Player extends GameEntity implements Comparable<Player> {
private int numTokenCreatedThisTurn = 0;
private int numForetoldThisTurn = 0;
private int numCardsInHandStartedThisTurnWith = 0;
private int lastTurnNr = 0;
private final Map<String, FCollection<String>> notes = Maps.newHashMap();
private boolean revolt = false;
@@ -2539,6 +2542,10 @@ public class Player extends GameEntity implements Comparable<Player> {
return keywords.getAmount(k);
}
public final int getLastTurnNr() {
return this.lastTurnNr;
}
public void onCleanupPhase() {
for (Card c : getCardsIn(ZoneType.Hand)) {
c.setDrawnThisTurn(false);
@@ -2562,6 +2569,11 @@ public class Player extends GameEntity implements Comparable<Player> {
resetAttackersDeclaredThisTurn();
resetAttackedOpponentsThisTurn();
setRevolt(false);
// set last turn nr
if (game.getPhaseHandler().isPlayerTurn(this)) {
this.lastTurnNr = game.getPhaseHandler().getTurn();
}
}
public boolean canCastSorcery() {
@@ -2572,16 +2584,15 @@ public class Player extends GameEntity implements Comparable<Player> {
//NOTE: for conditions the stack must only have the sa being checked
public boolean couldCastSorcery(final SpellAbility sa) {
final Card source = sa.getRootAbility().getHostCard();
boolean onlyThis = true;
for (final Card card : game.getCardsIn(ZoneType.Stack)) {
if (!card.equals(source)) {
onlyThis = false;
return false;
}
}
PhaseHandler now = game.getPhaseHandler();
return onlyThis && now.isPlayerTurn(this) && now.getPhase().isMain();
return now.isPlayerTurn(this) && now.getPhase().isMain();
}
public final PlayerController getController() {

View File

@@ -5,5 +5,5 @@ PT:4/3
K:First Strike
K:Partner
A:AB$ Mana | Cost$ T | Produced$ R | Amount$ X | SpellDescription$ Add an amount of {R} equal to the greatest power among creatures you control that entered the battlefield this turn.
SVar:X:Count$GreatestPower_Creature.YouCtrl+enteredBattlefieldThisTurn
SVar:X:Count$GreatestPower_Creature.YouCtrl+ThisTurnEntered
Oracle:First strike\n{T}: Add an amount of {R} equal to the greatest power among creatures you control that entered the battlefield this turn.\nPartner (You can have two commanders if both have partner.)

View File

@@ -6,6 +6,6 @@ K:First Strike
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ ChangeControl | TriggerDescription$ At the beginning of your upkeep, target opponent gains control of CARDNAME if the number of permanents is even.
SVar:ChangeControl:DB$ GainControl | Defined$ Self | ValidTgts$ Opponent | TgtPrompt$ Select target opponent | ConditionCheckSVar$ X | ConditionSVarCompare$ EQ0
SVar:X:Count$Valid Permanent/Mod.2
S:Mode$ CanAttackIfHaste | ValidCard$ Card.Self+notEnteredBattlefieldThisTurn | Description$ CARDNAME can attack as though it had haste unless it entered the battlefield this turn.
S:Mode$ CanAttackIfHaste | ValidCard$ Card.Self+NotThisTurnEntered | Description$ CARDNAME can attack as though it had haste unless it entered the battlefield this turn.
AI:RemoveDeck:All
Oracle:First strike\nAt the beginning of your upkeep, target opponent gains control of Chaos Lord if the number of permanents is even.\nChaos Lord can attack as though it had haste unless it entered the battlefield this turn.

View File

@@ -1,6 +1,6 @@
Name:Cradle to Grave
ManaCost:1 B
Types:Instant
A:SP$ Destroy | Cost$ 1 B | ValidTgts$ Creature.nonBlack+enteredBattlefieldThisTurn | TgtPrompt$ Select target nonblack creature that entered the battlefield this turn | SpellDescription$ Destroy target nonblack creature that entered the battlefield this turn.
A:SP$ Destroy | Cost$ 1 B | ValidTgts$ Creature.nonBlack+ThisTurnEntered | TgtPrompt$ Select target nonblack creature that entered the battlefield this turn | SpellDescription$ Destroy target nonblack creature that entered the battlefield this turn.
SVar:Picture:http://www.wizards.com/global/images/magic/general/cradle_to_grave.jpg
Oracle:Destroy target nonblack creature that entered the battlefield this turn.

View File

@@ -4,6 +4,6 @@ Types:Creature Eldrazi Crab
PT:5/7
K:Flash
K:Emerge:7 U
S:Mode$ Continuous | Affected$ Card.Self+enteredBattlefieldThisTurn | AddKeyword$ Hexproof | Description$ CARDNAME has hexproof as long as it entered the battlefield this turn.
S:Mode$ Continuous | Affected$ Card.Self+ThisTurnEntered | AddKeyword$ Hexproof | Description$ CARDNAME has hexproof as long as it entered the battlefield this turn.
SVar:Picture:http://www.wizards.com/global/images/magic/general/drownyard_behemoth.jpg
Oracle:Flash (You may cast this spell any time you could cast an instant.)\nEmerge {7}{U} (You may cast this spell by sacrificing a creature and paying the emerge cost reduced by that creature's converted mana cost.)\nDrownyard Behemoth has hexproof as long as it entered the battlefield this turn.

View File

@@ -2,5 +2,5 @@ Name:Force of Despair
ManaCost:1 B B
Types:Instant
SVar:AltCost:Cost$ ExileFromHand<1/Card.Black+Other> | OpponentTurn$ True | Description$ If it's not your turn, you may exile a black card from your hand rather than pay this spell's mana cost.
A:SP$ DestroyAll | Cost$ 1 B B | ValidCards$ Creature.enteredBattlefieldThisTurn | SpellDescription$ Destroy all creatures that entered the battlefield this turn.
A:SP$ DestroyAll | Cost$ 1 B B | ValidCards$ Creature.ThisTurnEntered | SpellDescription$ Destroy all creatures that entered the battlefield this turn.
Oracle:If it's not your turn, you may exile a black card from your hand rather than pay this spell's mana cost.\nDestroy all creatures that entered the battlefield this turn.

View File

@@ -2,7 +2,7 @@ Name:Forge of Heroes
ManaCost:no cost
Types:Land
A:AB$ Mana | Cost$ T | Produced$ C | SpellDescription$ Add {C}.
A:AB$ Pump | Cost$ T | ValidTgts$ Card.IsCommander+enteredBattlefieldThisTurn | TgtPrompt$ Select target commander that entered the battlefield this turn | SubAbility$ DBPutCounter | StackDescription$ Select target commander that entered the battlefield this turn. | SpellDescription$ Choose target commander that entered the battlefield this turn. Put a +1/+1 counter on it if it's a creature and a loyalty counter on it if it's a planeswalker.
A:AB$ Pump | Cost$ T | ValidTgts$ Card.IsCommander+ThisTurnEntered | TgtPrompt$ Select target commander that entered the battlefield this turn | SubAbility$ DBPutCounter | StackDescription$ Select target commander that entered the battlefield this turn. | SpellDescription$ Choose target commander that entered the battlefield this turn. Put a +1/+1 counter on it if it's a creature and a loyalty counter on it if it's a planeswalker.
SVar:DBPutCounter:DB$ PutCounter | Defined$ ParentTarget | CounterType$ P1P1 | CounterNum$ 1 | ConditionDefined$ ParentTarget | ConditionPresent$ Creature | ConditionCompare$ GE1 | SubAbility$ DBPutCounterCommander
SVar:DBPutCounterCommander:DB$ PutCounter | Defined$ ParentTarget | CounterType$ LOYALTY | CounterNum$ 1 | ConditionDefined$ ParentTarget | ConditionPresent$ Planeswalker | ConditionCompare$ GE1
Oracle:{T}: Add {C}.\n{T}: Choose target commander that entered the battlefield this turn. Put a +1/+1 counter on it if it's a creature and a loyalty counter on it if it's a planeswalker.

View File

@@ -2,7 +2,7 @@ Name:Fungus Elemental
ManaCost:3 G
Types:Creature Fungus Elemental
PT:3/3
A:AB$ PutCounter | Cost$ G Sac<1/Forest> | Defined$ Self | CounterType$ P2P2 | CounterNum$ 1 | IsPresent$ Card.Self+enteredBattlefieldThisTurn | SpellDescription$ Put a +2/+2 counter on CARDNAME. Activate this ability only if CARDNAME entered the battlefield this turn.
A:AB$ PutCounter | Cost$ G Sac<1/Forest> | Defined$ Self | CounterType$ P2P2 | CounterNum$ 1 | IsPresent$ Card.Self+ThisTurnEntered | SpellDescription$ Put a +2/+2 counter on CARDNAME. Activate this ability only if CARDNAME entered the battlefield this turn.
AI:RemoveDeck:All
SVar:Picture:http://www.wizards.com/global/images/magic/general/fungus_elemental.jpg
Oracle:{G}, Sacrifice a Forest: Put a +2/+2 counter on Fungus Elemental. Activate this ability only if Fungus Elemental entered the battlefield this turn.

View File

@@ -3,7 +3,7 @@ ManaCost:3 W W
Types:Legendary Creature Human Soldier
PT:4/4
K:Flash
T:Mode$ DamageDone | ValidSource$ Creature | ValidTarget$ You | CombatDamage$ True | IsPresent$ Card.Self+enteredBattlefieldThisTurn | Execute$ TrigExile | TriggerZones$ Battlefield | TriggerDescription$ Whenever a creature deals combat damage to you, if CARDNAME entered the battlefield this turn, exile that creature until CARDNAME leaves the battlefield.
T:Mode$ DamageDone | ValidSource$ Creature | ValidTarget$ You | CombatDamage$ True | IsPresent$ Card.Self+ThisTurnEntered | Execute$ TrigExile | TriggerZones$ Battlefield | TriggerDescription$ Whenever a creature deals combat damage to you, if CARDNAME entered the battlefield this turn, exile that creature until CARDNAME leaves the battlefield.
SVar:TrigExile:DB$ ChangeZone | Origin$ Battlefield | Destination$ Exile | Defined$ TriggeredSourceLKICopy | ConditionPresent$ Card.Self | SubAbility$ DBEffect
SVar:DBEffect:DB$ Effect | Triggers$ ComeBack | RememberObjects$ TriggeredCard | ImprintCards$ Self | ConditionPresent$ Card.Self | Duration$ Permanent | ForgetOnMoved$ Exile
SVar:ComeBack:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Any | ValidCard$ Card.IsImprinted | Execute$ TrigReturn | TriggerZones$ Command | TriggerController$ You | Static$ True | TriggerDescription$ That creature is exiled until EFFECTSOURCE leaves the battlefield

View File

@@ -2,6 +2,6 @@ Name:Novijen, Heart of Progress
ManaCost:no cost
Types:Land
A:AB$ Mana | Cost$ T | Produced$ C | SpellDescription$ Add {C}.
A:AB$ PutCounterAll | Cost$ G U T | CounterType$ P1P1 | CounterNum$ 1 | ValidCards$ Creature.enteredBattlefieldThisTurn | SpellDescription$ Put a +1/+1 counter on each creature that entered the battlefield this turn.
A:AB$ PutCounterAll | Cost$ G U T | CounterType$ P1P1 | CounterNum$ 1 | ValidCards$ Creature.ThisTurnEntered | SpellDescription$ Put a +1/+1 counter on each creature that entered the battlefield this turn.
SVar:Picture:http://www.wizards.com/global/images/magic/general/novijen_heart_of_progress.jpg
Oracle:{T}: Add {C}.\n{G}{U}, {T}: Put a +1/+1 counter on each creature that entered the battlefield this turn.

View File

@@ -3,7 +3,7 @@ ManaCost:no cost
Types:Land
K:CARDNAME enters the battlefield tapped.
A:AB$ Mana | Cost$ T | Produced$ G | SpellDescription$ Add {G}.
A:AB$PutCounterAll | Cost$ T | ValidCards$ Creature.Green+enteredBattlefieldThisTurn | CounterType$ P1P1 | CounterNum$ 1 | SpellDescription$ Put a +1/+1 counter on each green creature that entered the battlefield this turn.
A:AB$PutCounterAll | Cost$ T | ValidCards$ Creature.Green+ThisTurnEntered | CounterType$ P1P1 | CounterNum$ 1 | SpellDescription$ Put a +1/+1 counter on each green creature that entered the battlefield this turn.
DeckHas:Ability$Counters
SVar:Picture:http://www.wizards.com/global/images/magic/general/oran_rief_the_vastwood.jpg
Oracle:Oran-Rief, the Vastwood enters the battlefield tapped.\n{T}: Add {G}.\n{T}: Put a +1/+1 counter on each green creature that entered the battlefield this turn.

View File

@@ -1,10 +1,5 @@
Name:Premature Burial
ManaCost:1 B
Types:Sorcery
A:SP$ Destroy | Cost$ 1 B | ValidTgts$ Creature.RememberMap_You | TgtPrompt$ Select target nonblack creature that entered the battlefield since your last turn ended | SpellDescription$ Destroy target nonblack creature that entered the battlefield since your last turn ended.
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Creature.nonBlack | Static$ True | Execute$ TrigRemember
SVar:TrigRemember:DB$ StoreMap | RememberEntity$ Player | RememberObjects$ TriggeredCard | ObjectType$ Card
T:Mode$ Phase | Phase$ Cleanup | Execute$ TrigCleanup | Static$ True
SVar:TrigCleanup:DB$ StoreMap | RememberEntity$ TriggeredPlayer | Clear$ True
SVar:Picture:http://www.wizards.com/global/images/magic/general/premature_burial.jpg
A:SP$ Destroy | Cost$ 1 B | ValidTgts$ Creature.nonBlack+EnteredSinceYourLastTurn | TgtPrompt$ Select target nonblack creature that entered the battlefield since your last turn ended | SpellDescription$ Destroy target nonblack creature that entered the battlefield since your last turn ended.
Oracle:Destroy target nonblack creature that entered the battlefield since your last turn ended.

View File

@@ -3,7 +3,7 @@ ManaCost:no cost
Types:Land
K:CARDNAME enters the battlefield tapped.
A:AB$ Mana | Cost$ T | Produced$ C | SpellDescription$ Add {C}.
A:AB$ PutCounter | Cost$ T | ValidTgts$ Creature.Colorless+enteredBattlefieldThisTurn | TgtPrompt$ Select target colorless creature that entered the battlefield this turn | CounterType$ P1P1 | CounterNum$ 1 | SpellDescription$ Put a +1/+1 counter on target colorless creature that entered the battlefield this turn.
A:AB$ PutCounter | Cost$ T | ValidTgts$ Creature.Colorless+ThisTurnEntered | TgtPrompt$ Select target colorless creature that entered the battlefield this turn | CounterType$ P1P1 | CounterNum$ 1 | SpellDescription$ Put a +1/+1 counter on target colorless creature that entered the battlefield this turn.
DeckHas:Ability$Mana.Colorless
DeckHints:Color$Colorless & Keyword$Devoid
SVar:Picture:http://www.wizards.com/global/images/magic/general/ruins_of_oran_rief.jpg

View File

@@ -5,5 +5,5 @@ PT:3/1
K:Flash
K:Cascade
K:ETBReplacement:Copy:DBCopy:Optional
SVar:DBCopy:DB$ Clone | Choices$ Permanent.enteredBattlefieldThisTurn+Other | SpellDescription$ You may have CARDNAME enter the battlefield as a copy of any permanent that entered the battlefield this turn.
SVar:DBCopy:DB$ Clone | Choices$ Permanent.ThisTurnEntered+Other | SpellDescription$ You may have CARDNAME enter the battlefield as a copy of any permanent that entered the battlefield this turn.
Oracle:Flash\nCascade (When you cast this spell, exile cards from the top of your library until you exile a nonland card that costs less. You may cast it without paying its mana cost. Put the exiled cards on the bottom of your library in a random order.)\nYou may have Sakashima's Protege enter the battlefield as a copy of any permanent that entered the battlefield this turn.

View File

@@ -6,7 +6,7 @@ K:Flash
K:Cascade
K:Reach
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigPutCounter | TriggerDescription$ When CARDNAME enters the battlefield, put three +1/+1 counters on each of any number of target creatures that entered the battlefield this turn.
SVar:TrigPutCounter:DB$PutCounter | CounterNum$ 3 | CounterType$ P1P1 | TargetMin$ 0 | TargetMax$ X | ValidTgts$ Creature.enteredBattlefieldThisTurn | TgtPrompt$ Select any number of target creatures that entered the battlefield this turn |
SVar:X:Count$Valid Creature.enteredBattlefieldThisTurn
SVar:TrigPutCounter:DB$PutCounter | CounterNum$ 3 | CounterType$ P1P1 | TargetMin$ 0 | TargetMax$ X | ValidTgts$ Creature.ThisTurnEntered | TgtPrompt$ Select any number of target creatures that entered the battlefield this turn |
SVar:X:Count$Valid Creature.ThisTurnEntered
DeckHas:Ability$Counters
Oracle:Flash\nCascade\nReach\nWhen Sweet-Gum Recluse enters the battlefield, put three +1/+1 counters on each of any number of target creatures that entered the battlefield this turn.

View File

@@ -415,7 +415,6 @@ public final class CardScriptParser {
"canProduceSameManaTypeWith", "SecondSpellCastThisTurn",
"ThisTurnCast", "withFlashback", "tapped", "untapped", "faceDown",
"faceUp", "hasLevelUp", "DrawnThisTurn", "notDrawnThisTurn",
"enteredBattlefieldThisTurn", "notEnteredBattlefieldThisTurn",
"firstTurnControlled", "notFirstTurnControlled",
"startedTheTurnUntapped", "attackedOrBlockedSinceYourLastUpkeep",
"blockedOrBeenBlockedSinceYourLastUpkeep",