Skip to content

Commit

Permalink
~ update more cards for Triggered LKICopy
Browse files Browse the repository at this point in the history
  • Loading branch information
Hanmac committed Apr 25, 2022
1 parent aa362fb commit 41c9196
Show file tree
Hide file tree
Showing 30 changed files with 86 additions and 77 deletions.
7 changes: 0 additions & 7 deletions forge-ai/src/main/java/forge/ai/ability/ChooseCardAi.java
Original file line number Diff line number Diff line change
Expand Up @@ -190,13 +190,6 @@ public Card chooseSingleCard(final Player ai, final SpellAbility sa, Iterable<Ca
} else if ("RandomNonLand".equals(logic)) {
options = CardLists.getValidCards(options, "Card.nonLand", host.getController(), host, sa);
choice = Aggregates.random(options);
} else if (logic.equals("Untap")) {
final String filter = "Permanent.YouCtrl,Permanent.tapped";
CardCollection newOptions = CardLists.getValidCards(options, filter, ctrl, host, sa);
if (!newOptions.isEmpty()) {
options = newOptions;
}
choice = ComputerUtilCard.getBestAI(options);
} else if (logic.equals("NeedsPrevention")) {
final Game game = ai.getGame();
final Combat combat = game.getCombat();
Expand Down
9 changes: 8 additions & 1 deletion forge-ai/src/main/java/forge/ai/ability/UntapAi.java
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,14 @@ public Card chooseSingleCard(Player ai, SpellAbility sa, Iterable<Card> list, bo
PlayerCollection pl = new PlayerCollection();
pl.add(ai);
pl.addAll(ai.getAllies());
return ComputerUtilCard.getBestAI(CardLists.filterControlledBy(list, pl));
CardCollection filteredList = CardLists.filterControlledBy(list, pl);
if (!filteredList.isEmpty()) {
return ComputerUtilCard.getBestAI(filteredList);
}
if (isOptional) {
return null;
}
return ComputerUtilCard.getWorstAI(list);
}

private static Card detectPriorityUntapTargets(final List<Card> untapList) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ else if (outcome <= chanceToHit) {
protected String getStackDescription(SpellAbility sa) {
final StringBuilder sb = new StringBuilder();
final Card host = sa.getHostCard();
final Player p = sa.getActivatingPlayer();

sb.append("Flip ");
sb.append(host.toString());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ public void resolve(SpellAbility sa) {
game.getTriggerHandler().clearSuppression(TriggerType.ChangesZone);

game.getEndOfTurn().addUntil(new GameCommand() {
private static final long serialVersionUID = 1L;

@Override
public void run() {
game.getAction().exile(eff, null);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package forge.game.ability.effects;

import java.util.List;

import forge.game.Game;
import forge.game.ability.AbilityUtils;
import forge.game.ability.SpellAbilityEffect;
Expand All @@ -18,10 +16,8 @@ public class RemoveFromCombatEffect extends SpellAbilityEffect {
protected String getStackDescription(SpellAbility sa) {
final StringBuilder sb = new StringBuilder();

final List<Card> tgtCards = getTargetCards(sa);

sb.append("Remove ");
sb.append(Lang.joinHomogenous(tgtCards));
sb.append(Lang.joinHomogenous(getTargetCards(sa)));
sb.append(" from combat.");

return sb.toString();
Expand All @@ -38,6 +34,15 @@ public void resolve(SpellAbility sa) {
if (combat == null || !c.isInPlay()) {
continue;
}
// check if the object is still in game or if it was moved
Card gameCard = game.getCardState(c, 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 || !c.equalsWithGameTimestamp(gameCard)) {
continue;
}

// Unblock creatures that were blocked only by this card (e.g. Ydwen Efreet)
if (sa.hasParam("UnblockCreaturesBlockedOnlyBy")) {
CardCollection attackers = AbilityUtils.getDefinedCards(sa.getHostCard(), sa.getParam("UnblockCreaturesBlockedOnlyBy"), sa);
Expand All @@ -58,11 +63,11 @@ public void resolve(SpellAbility sa) {
}
}

game.getCombat().saveLKI(c);
combat.removeFromCombat(c);
game.getCombat().saveLKI(gameCard);
combat.removeFromCombat(gameCard);

if (rem) {
sa.getHostCard().addRemembered(c);
sa.getHostCard().addRemembered(gameCard);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,10 @@ private static void untapChoose(final SpellAbility sa, final boolean mandatory)
}
CardCollectionView list = CardLists.getValidCards(p.getGame().getCardsIn(ZoneType.Battlefield),
valid, sa.getActivatingPlayer(), sa.getHostCard(), sa);
list = CardLists.filter(list, Presets.TAPPED);
// the few mandatory are handled differently
if (!mandatory) {
list = CardLists.filter(list, Presets.TAPPED);
}

final CardCollectionView selected = p.getController().chooseCardsForEffect(list, sa, Localizer.getInstance().getMessage("lblSelectCardToUntap"), mandatory ? num : 0, num, !mandatory, null);
if (selected != null) {
Expand Down
28 changes: 15 additions & 13 deletions forge-game/src/main/java/forge/game/trigger/WrappedAbility.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ public class WrappedAbility extends Ability {
ApiType.RemoveCounter,
ApiType.AddOrRemoveCounter,
ApiType.MoveCounter,
ApiType.Draw,
ApiType.GainLife,
ApiType.LoseLife,
ApiType.Draw, // only player
ApiType.GainLife, // only player
ApiType.LoseLife, // only player
ApiType.ChangeZone,
ApiType.Destroy,
ApiType.Token,
Expand All @@ -59,24 +59,26 @@ public class WrappedAbility extends Ability {

ApiType.Explore,
ApiType.Protection, // should not care about triggered
ApiType.ProtectionAll,
ApiType.ProtectionAll, // No Triggered
ApiType.Proliferate, // only player no triggered interaction
ApiType.CopyPermanent,
ApiType.Debuff, // updated
ApiType.Venture, // only player
ApiType.Manifest, // no triggered
ApiType.Scry, // only player
ApiType.SetInMotion,
ApiType.SetInMotion, // No Triggered
ApiType.Shuffle, // only player
ApiType.Surveil, // only player
ApiType.Tap,
ApiType.TapAll,
ApiType.TapOrUntap,
ApiType.TapOrUntapAll,
ApiType.Untap,
ApiType.UntapAll,
ApiType.Unattach,
ApiType.UnattachAll,
ApiType.Tap, // Done
ApiType.TapAll, // uses filterListByType
ApiType.TapOrUntap, // No TriggeredCard
ApiType.TapOrUntapAll, // No TriggeredCard
ApiType.Untap, // Done
ApiType.UntapAll, // only player
ApiType.Unattach, // No Triggered
ApiType.UnattachAll, // No Triggered

ApiType.RemoveFromCombat, // Done

ApiType.Poison, // only player
ApiType.Vote // only player
Expand Down
2 changes: 1 addition & 1 deletion forge-gui/res/cardsfolder/a/amulet_of_vigor.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ Name:Amulet of Vigor
ManaCost:1
Types:Artifact
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Permanent.tapped+YouCtrl | Execute$ TrigUntap | TriggerZones$ Battlefield | TriggerDescription$ Whenever a permanent enters the battlefield tapped and under your control, untap it.
SVar:TrigUntap:DB$ Untap | Defined$ TriggeredCard
SVar:TrigUntap:DB$ Untap | Defined$ TriggeredCardLKICopy
Oracle:Whenever a permanent enters the battlefield tapped and under your control, untap it.
8 changes: 4 additions & 4 deletions forge-gui/res/cardsfolder/d/dhalsim_pliable_pacifist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ PT:1/3
K:Reach
S:Mode$ Continuous | Affected$ Card.Self | AddKeyword$ Hexproof | IsPresent$ Card.Self+notattacking | Description$ Teleport – CARDNAME has hexproof unless he's attacking.
T:Mode$ Attacks | ValidCard$ Creature.YouCtrl+withReach | TriggerZones$ Battlefield | Execute$ TrigUntap | TriggerDescription$ Whenever a creature you control with reach attacks, untap it and it can't be blocked by creatures with greater power this combat.
SVar:TrigUntap:DB$ Untap | Defined$ TriggeredAttacker | SubAbility$ DBAnimate
SVar:DBAnimate:DB$ Animate | Defined$ TriggeredAttacker | staticAbilities$ CantBeBlockedPow | Duration$ UntilEndOfCombat
SVar:CantBeBlockedPow:Mode$ CantBlockBy | ValidAttacker$ Card.Self | ValidBlocker$ Creature.powerGTX | Description$ CARDNAME can't be blocked by creatures with greater power this combat.
SVar:X:Count$CardPower
SVar:TrigUntap:DB$ Untap | Defined$ TriggeredAttackerLKICopy | SubAbility$ DBEffect
SVar:DBEffect:DB$ Effect | RememberObjects$ TriggeredAttacker | StaticAbilities$ CantBeBlockedPow | ForgetOnMoved$ Battlefield | Duration$ UntilEndOfCombat
SVar:CantBeBlockedPow:Mode$ CantBlockBy | ValidAttacker$ Card.IsRemembered | ValidBlocker$ Creature.powerGTX | Description$ CARDNAME can't be blocked by creatures with greater power this combat.
SVar:X:Remembered$CardPower
T:Mode$ DamageDoneOnce | CombatDamage$ True | ValidSource$ Creature.YouCtrl | TriggerZones$ Battlefield | ValidTarget$ Player | Execute$ TrigDraw | TriggerDescription$ Fierce Punch – Whenever one or more creatures you control deal combat damage to a player, draw a card.
SVar:TrigDraw:DB$ Draw
DeckHints:Keyword$Reach
Expand Down
2 changes: 1 addition & 1 deletion forge-gui/res/cardsfolder/e/enormous_energy_blade.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ ManaCost:2 B
Types:Artifact Equipment
S:Mode$ Continuous | Affected$ Creature.EquippedBy | AddPower$ 4 | Description$ Equipped creature gets +4/+0.
T:Mode$ Attached | ValidSource$ Card.Self | ValidTarget$ Creature | TriggerZones$ Battlefield | Execute$ TrigTap | TriggerDescription$ Whenever CARDNAME becomes attached to a creature, tap that creature.
SVar:TrigTap:DB$ Tap | Defined$ TriggeredTarget
SVar:TrigTap:DB$ Tap | Defined$ TriggeredTargetLKICopy
K:Equip:2
Oracle:Equipped creature gets +4/+0.\nWhenever Enormous Energy Blade becomes attached to a creature, tap that creature.\nEquip {2} ({2}: Attach to target creature you control. Equip only as a sorcery.)
2 changes: 1 addition & 1 deletion forge-gui/res/cardsfolder/f/finest_hour.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ ManaCost:2 G W U
Types:Enchantment
K:Exalted
T:Mode$ Attacks | ValidCard$ Creature.YouCtrl | Alone$ True | TriggerZones$ Battlefield | Execute$ TrigUntap | FirstCombat$ True | TriggerDescription$ Whenever a creature you control attacks alone, if it's the first combat phase of the turn, untap that creature. After this phase, there is an additional combat phase.
SVar:TrigUntap:DB$ Untap | Defined$ TriggeredAttacker | SubAbility$ DBAddCombat
SVar:TrigUntap:DB$ Untap | Defined$ TriggeredAttackerLKICopy | SubAbility$ DBAddCombat
SVar:DBAddCombat:DB$ AddPhase | ExtraPhase$ Combat | AfterPhase$ EndCombat
SVar:PlayMain1:TRUE
Oracle:Exalted (Whenever a creature you control attacks alone, that creature gets +1/+1 until end of turn.)\nWhenever a creature you control attacks alone, if it's the first combat phase of the turn, untap that creature. After this phase, there is an additional combat phase.
4 changes: 2 additions & 2 deletions forge-gui/res/cardsfolder/f/frostwalk_bastion.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Types:Snow Land
A:AB$ Mana | Cost$ T | Produced$ C | SpellDescription$ Add {C}.
A:AB$ Animate | Cost$ 1 S | Defined$ Self | Power$ 2 | Toughness$ 3 | Types$ Creature,Artifact,Construct | SpellDescription$ Until end of turn, CARDNAME becomes a 2/3 Construct artifact creature. It's still a land. ({S} can be paid with one mana from a snow source.)
T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Creature | CombatDamage$ True | TriggerZones$ Battlefield | Execute$ TrigTap | TriggerDescription$ Whenever CARDNAME deals combat damage to a creature, tap that creature and it doesn't untap during its controller's next untap step.
SVar:TrigTap:DB$ Tap | Defined$ TriggeredTarget | SubAbility$ DBPump
SVar:DBPump:DB$ Pump | Defined$ TriggeredTarget | KW$ HIDDEN This card doesn't untap during your next untap step. | Duration$ Permanent | IsCurse$ True
SVar:TrigTap:DB$ Tap | Defined$ TriggeredTargetLKICopy | SubAbility$ DBPump
SVar:DBPump:DB$ Pump | Defined$ TriggeredTargetLKICopy | KW$ HIDDEN This card doesn't untap during your next untap step. | Duration$ Permanent | IsCurse$ True
SVar:HasCombatEffect:TRUE
Oracle:{T}: Add {C}.\n{1}{S}: Until end of turn, Frostwalk Bastion becomes a 2/3 Construct artifact creature. It's still a land. ({S} can be paid with one mana from a snow source.)\nWhenever Frostwalk Bastion deals combat damage to a creature, tap that creature and it doesn't untap during its controller's next untap step.
4 changes: 2 additions & 2 deletions forge-gui/res/cardsfolder/g/gustcloak_savior.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ Types:Creature Bird Soldier
PT:3/4
K:Flying
T:Mode$ AttackerBlocked | ValidCard$ Creature.YouCtrl | Execute$ TrigUntapRemove | TriggerZones$ Battlefield | OptionalDecider$ You | TriggerDescription$ Whenever a creature you control becomes blocked, you may untap that creature and remove it from combat.
SVar:TrigUntapRemove:DB$ Untap | Defined$ TriggeredAttacker | SubAbility$ DBRemoveCombat
SVar:DBRemoveCombat:DB$ RemoveFromCombat | Defined$ TriggeredAttacker
SVar:TrigUntapRemove:DB$ Untap | Defined$ TriggeredAttackerLKICopy | SubAbility$ DBRemoveCombat
SVar:DBRemoveCombat:DB$ RemoveFromCombat | Defined$ TriggeredAttackerLKICopy
Oracle:Flying\nWhenever a creature you control becomes blocked, you may untap that creature and remove it from combat.
2 changes: 1 addition & 1 deletion forge-gui/res/cardsfolder/h/hokori_dust_drinker.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ Types:Legendary Creature Spirit
PT:2/2
S:Mode$ Continuous | Affected$ Land | AddHiddenKeyword$ CARDNAME doesn't untap during your untap step. | Description$ Lands don't untap during their controller's untap steps.
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ Player | TriggerZones$ Battlefield | IsPresent$ Card.Self | Execute$ TrigUntap | TriggerDescription$ At the beginning of each player's upkeep, that player untaps a land they control.
SVar:TrigUntap:DB$ Untap | UntapExactly$ True | UntapType$ Land.ActivePlayerCtrl | Amount$ 1 | Defined$ TriggeredPlayer
SVar:TrigUntap:DB$ Untap | UntapExactly$ True | UntapType$ Land.ActivePlayerCtrl+tapped | Amount$ 1 | Defined$ TriggeredPlayer
AI:RemoveDeck:Random
Oracle:Lands don't untap during their controllers' untap steps.\nAt the beginning of each player's upkeep, that player untaps a land they control.
8 changes: 4 additions & 4 deletions forge-gui/res/cardsfolder/i/imprison.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ T:Mode$ Attacks | ValidCard$ Card.EnchantedBy | TriggerZones$ Battlefield | Exec
T:Mode$ Blocks | ValidCard$ Card.EnchantedBy | TriggerZones$ Battlefield | Execute$ TrigDestroy3 | Secondary$ True | TriggerDescription$ Whenever enchanted creature attacks or blocks, you may pay {1}. If you do, tap the creature, remove it from combat, and creatures it was blocking that had become blocked by only that creature this combat become unblocked. If you don't, destroy CARDNAME.
SVar:TrigDestroy2:DB$ Destroy | Defined$ Self | UnlessCost$ 1 | UnlessPayer$ You | UnlessResolveSubs$ WhenPaid | SubAbility$ DBTapAttacker
SVar:TrigDestroy3:DB$ Destroy | Defined$ Self | UnlessCost$ 1 | UnlessPayer$ You | UnlessResolveSubs$ WhenPaid | SubAbility$ DBTapBlocker
SVar:DBTapAttacker:DB$ Tap | Defined$ TriggeredAttacker | SubAbility$ DBRemoveAttacker
SVar:DBTapBlocker:DB$ Tap | Defined$ TriggeredBlocker | SubAbility$ DBRemoveBlocker
SVar:DBRemoveAttacker:DB$ RemoveFromCombat | Defined$ TriggeredAttacker
SVar:DBRemoveBlocker:DB$ RemoveFromCombat | Defined$ TriggeredBlocker | UnblockCreaturesBlockedOnlyBy$ TriggeredBlocker
SVar:DBTapAttacker:DB$ Tap | Defined$ TriggeredAttackerLKICopy | SubAbility$ DBRemoveAttacker
SVar:DBTapBlocker:DB$ Tap | Defined$ TriggeredBlockerLKICopy | SubAbility$ DBRemoveBlocker
SVar:DBRemoveAttacker:DB$ RemoveFromCombat | Defined$ TriggeredAttackerLKICopy
SVar:DBRemoveBlocker:DB$ RemoveFromCombat | Defined$ TriggeredBlockerLKICopy | UnblockCreaturesBlockedOnlyBy$ TriggeredBlocker
AI:RemoveDeck:All
Oracle:Enchant creature\nWhenever a player activates an ability of enchanted creature with {T} in its activation cost that isn't a mana ability, you may pay {1}. If you do, counter that ability. If you don't, destroy Imprison.\nWhenever enchanted creature attacks or blocks, you may pay {1}. If you do, tap the creature, remove it from combat, and creatures it was blocking that had become blocked by only that creature this combat become unblocked. If you don't, destroy Imprison.
4 changes: 2 additions & 2 deletions forge-gui/res/cardsfolder/k/kashi_tribe_elite.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Types:Creature Snake Warrior
PT:2/3
S:Mode$ Continuous | Affected$ Snake.Legendary+YouCtrl | AddKeyword$ Shroud | Description$ Legendary Snakes you control have shroud. (They can't be the targets of spells or abilities.)
T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Creature | CombatDamage$ True | TriggerZones$ Battlefield | Execute$ TrigTap | TriggerDescription$ Whenever CARDNAME deals combat damage to a creature, tap that creature and it doesn't untap during its controller's next untap step.
SVar:TrigTap:DB$ Tap | Defined$ TriggeredTarget | SubAbility$ DBPump
SVar:DBPump:DB$ Pump | Defined$ TriggeredTarget | KW$ HIDDEN This card doesn't untap during your next untap step. | Duration$ Permanent | IsCurse$ True
SVar:TrigTap:DB$ Tap | Defined$ TriggeredTargetLKICopy | SubAbility$ DBPump
SVar:DBPump:DB$ Pump | Defined$ TriggeredTargetLKICopy | KW$ HIDDEN This card doesn't untap during your next untap step. | Duration$ Permanent | IsCurse$ True
SVar:HasCombatEffect:TRUE
Oracle:Legendary Snakes you control have shroud. (They can't be the targets of spells or abilities.)\nWhenever Kashi-Tribe Elite deals combat damage to a creature, tap that creature and it doesn't untap during its controller's next untap step.
4 changes: 2 additions & 2 deletions forge-gui/res/cardsfolder/k/kashi_tribe_reaver.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ ManaCost:3 G
Types:Creature Snake Warrior
PT:3/2
T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Creature | CombatDamage$ True | TriggerZones$ Battlefield | Execute$ TrigTap | TriggerDescription$ Whenever CARDNAME deals combat damage to a creature, tap that creature and it doesn't untap during its controller's next untap step.
SVar:TrigTap:DB$ Tap | Defined$ TriggeredTarget | SubAbility$ DBPump
SVar:DBPump:DB$ Pump | Defined$ TriggeredTarget | KW$ HIDDEN This card doesn't untap during your next untap step. | Duration$ Permanent | IsCurse$ True
SVar:TrigTap:DB$ Tap | Defined$ TriggeredTargetLKICopy | SubAbility$ DBPump
SVar:DBPump:DB$ Pump | Defined$ TriggeredTargetLKICopy | KW$ HIDDEN This card doesn't untap during your next untap step. | Duration$ Permanent | IsCurse$ True
A:AB$ Regenerate | Cost$ 1 G | SpellDescription$ Regenerate CARDNAME.
SVar:HasCombatEffect:TRUE
Oracle:Whenever Kashi-Tribe Reaver deals combat damage to a creature, tap that creature and it doesn't untap during its controller's next untap step.\n{1}{G}: Regenerate Kashi-Tribe Reaver.
4 changes: 2 additions & 2 deletions forge-gui/res/cardsfolder/k/kashi_tribe_warriors.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ ManaCost:3 G G
Types:Creature Snake Warrior
PT:2/4
T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Creature | CombatDamage$ True | TriggerZones$ Battlefield | Execute$ TrigTap | TriggerDescription$ Whenever CARDNAME deals combat damage to a creature, tap that creature and it doesn't untap during its controller's next untap step.
SVar:TrigTap:DB$ Tap | Defined$ TriggeredTarget | SubAbility$ DBPump
SVar:DBPump:DB$ Pump | Defined$ TriggeredTarget | KW$ HIDDEN This card doesn't untap during your next untap step. | Duration$ Permanent | IsCurse$ True
SVar:TrigTap:DB$ Tap | Defined$ TriggeredTargetLKICopy | SubAbility$ DBPump
SVar:DBPump:DB$ Pump | Defined$ TriggeredTargetLKICopy | KW$ HIDDEN This card doesn't untap during your next untap step. | Duration$ Permanent | IsCurse$ True
SVar:HasCombatEffect:TRUE
Oracle:Whenever Kashi-Tribe Warriors deals combat damage to a creature, tap that creature and it doesn't untap during its controller's next untap step.
Loading

0 comments on commit 41c9196

Please sign in to comment.