Add Psychic Battle

This commit is contained in:
Lyu Zong-Hong
2021-04-09 14:06:51 +09:00
parent 52b8c4ae5e
commit 7603943c38
5 changed files with 44 additions and 12 deletions

View File

@@ -35,6 +35,7 @@ public class ChangeTargetsEffect extends SpellAbilityEffect {
final List<SpellAbility> sas = getTargetSpells(sa); final List<SpellAbility> sas = getTargetSpells(sa);
final boolean remember = sa.hasParam("RememberTargetedCard"); final boolean remember = sa.hasParam("RememberTargetedCard");
final Player activator = sa.getActivatingPlayer(); final Player activator = sa.getActivatingPlayer();
final Player chooser = sa.hasParam("Chooser") ? getDefinedPlayersOrTargeted(sa, "Chooser").get(0) : sa.getActivatingPlayer();
final MagicStack stack = activator.getGame().getStack(); final MagicStack stack = activator.getGame().getStack();
for (final SpellAbility tgtSA : sas) { for (final SpellAbility tgtSA : sas) {
@@ -45,7 +46,6 @@ public class ChangeTargetsEffect extends SpellAbilityEffect {
} }
SpellAbilityStackInstance changingTgtSI = si; SpellAbilityStackInstance changingTgtSI = si;
Player chooser = sa.getActivatingPlayer();
// Redirect rules read 'you MAY choose new targets' ... okay! // Redirect rules read 'you MAY choose new targets' ... okay!
// TODO: Don't even ask to change targets, if the SA and subs don't actually have targets // TODO: Don't even ask to change targets, if the SA and subs don't actually have targets
@@ -79,7 +79,7 @@ public class ChangeTargetsEffect extends SpellAbilityEffect {
// gets the divied value from old target // gets the divied value from old target
Integer div = oldTargetBlock.getDividedValue(oldTarget); Integer div = oldTargetBlock.getDividedValue(oldTarget);
newTargetBlock.remove(oldTarget); newTargetBlock.remove(oldTarget);
replaceIn.updateTarget(newTargetBlock); replaceIn.updateTarget(newTargetBlock, sa.getHostCard());
// 3. test if updated choices would be correct. // 3. test if updated choices would be correct.
GameObject newTarget = Iterables.getFirst(getDefinedCardsOrTargeted(sa, "DefinedMagnet"), null); GameObject newTarget = Iterables.getFirst(getDefinedCardsOrTargeted(sa, "DefinedMagnet"), null);
@@ -88,10 +88,10 @@ public class ChangeTargetsEffect extends SpellAbilityEffect {
if (div != null) { if (div != null) {
newTargetBlock.addDividedAllocation(newTarget, div); newTargetBlock.addDividedAllocation(newTarget, div);
} }
replaceIn.updateTarget(newTargetBlock); replaceIn.updateTarget(newTargetBlock, sa.getHostCard());
} }
else { else {
replaceIn.updateTarget(oldTargetBlock); replaceIn.updateTarget(oldTargetBlock, sa.getHostCard());
} }
} }
else { else {
@@ -109,7 +109,7 @@ public class ChangeTargetsEffect extends SpellAbilityEffect {
changingTgtSA.addDividedAllocation(choice, div); changingTgtSA.addDividedAllocation(choice, div);
} }
changingTgtSI.updateTarget(changingTgtSA.getTargets()); changingTgtSI.updateTarget(changingTgtSA.getTargets(), sa.getHostCard());
} }
else if (sa.hasParam("DefinedMagnet")){ else if (sa.hasParam("DefinedMagnet")){
GameObject newTarget = Iterables.getFirst(getDefinedCardsOrTargeted(sa, "DefinedMagnet"), null); GameObject newTarget = Iterables.getFirst(getDefinedCardsOrTargeted(sa, "DefinedMagnet"), null);
@@ -117,7 +117,7 @@ public class ChangeTargetsEffect extends SpellAbilityEffect {
int div = changingTgtSA.getTotalDividedValue(); int div = changingTgtSA.getTotalDividedValue();
changingTgtSA.resetTargets(); changingTgtSA.resetTargets();
changingTgtSA.getTargets().add(newTarget); changingTgtSA.getTargets().add(newTarget);
changingTgtSI.updateTarget(changingTgtSA.getTargets()); changingTgtSI.updateTarget(changingTgtSA.getTargets(), sa.getHostCard());
if (changingTgtSA.isDividedAsYouChoose()) { if (changingTgtSA.isDividedAsYouChoose()) {
changingTgtSA.addDividedAllocation(newTarget, div); changingTgtSA.addDividedAllocation(newTarget, div);
} }
@@ -127,9 +127,9 @@ public class ChangeTargetsEffect extends SpellAbilityEffect {
// Update targets, with a potential new target // Update targets, with a potential new target
Predicate<GameObject> filter = sa.hasParam("TargetRestriction") ? GameObjectPredicates.restriction(sa.getParam("TargetRestriction").split(","), activator, sa.getHostCard(), sa) : null; Predicate<GameObject> filter = sa.hasParam("TargetRestriction") ? GameObjectPredicates.restriction(sa.getParam("TargetRestriction").split(","), activator, sa.getHostCard(), sa) : null;
// TODO Creature.Other might not work yet as it should // TODO Creature.Other might not work yet as it should
TargetChoices newTarget = sa.getActivatingPlayer().getController().chooseNewTargetsFor(changingTgtSA, filter, false); TargetChoices newTarget = chooser.getController().chooseNewTargetsFor(changingTgtSA, filter, false);
if (null != newTarget) { if (null != newTarget) {
changingTgtSI.updateTarget(newTarget); changingTgtSI.updateTarget(newTarget, sa.getHostCard());
} }
} }
} }

View File

@@ -250,7 +250,7 @@ public class SpellAbilityStackInstance implements IIdentifiable, IHasCardView {
return playersWithValidTargets; return playersWithValidTargets;
} }
public void updateTarget(TargetChoices target) { public void updateTarget(TargetChoices target, Card cause) {
if (target != null) { if (target != null) {
TargetChoices oldTarget = tc; TargetChoices oldTarget = tc;
tc = target; tc = target;
@@ -280,9 +280,14 @@ public class SpellAbilityStackInstance implements IIdentifiable, IHasCardView {
runParams.put(AbilityKey.Target, tgt); runParams.put(AbilityKey.Target, tgt);
getSourceCard().getGame().getTriggerHandler().runTrigger(TriggerType.BecomesTarget, runParams, false); getSourceCard().getGame().getTriggerHandler().runTrigger(TriggerType.BecomesTarget, runParams, false);
} }
runParams = AbilityKey.newMap(); // Only run BecomesTargetOnce when at least one target is changed
runParams.put(AbilityKey.Targets, distinctObjects); if (!distinctObjects.isEmpty()) {
getSourceCard().getGame().getTriggerHandler().runTrigger(TriggerType.BecomesTargetOnce, runParams, false); runParams = AbilityKey.newMap();
runParams.put(AbilityKey.SourceSA, ability);
runParams.put(AbilityKey.Targets, distinctObjects);
runParams.put(AbilityKey.Cause, cause);
getSourceCard().getGame().getTriggerHandler().runTrigger(TriggerType.BecomesTargetOnce, runParams, false);
}
} }
} }

View File

@@ -62,6 +62,9 @@ public class TriggerBecomesTargetOnce extends Trigger {
if (!matchesValidParam("ValidTarget", runParams.get(AbilityKey.Targets))) { if (!matchesValidParam("ValidTarget", runParams.get(AbilityKey.Targets))) {
return false; return false;
} }
if (!matchesValidParam("ValidCause", runParams.get(AbilityKey.Cause))) {
return false;
}
return true; return true;
} }

View File

@@ -380,6 +380,7 @@ public class MagicStack /* extends MyObservable */ implements Iterable<SpellAbil
game.getTriggerHandler().runTrigger(TriggerType.BecomesTarget, runParams, false); game.getTriggerHandler().runTrigger(TriggerType.BecomesTarget, runParams, false);
} }
runParams.put(AbilityKey.Targets, tc); runParams.put(AbilityKey.Targets, tc);
runParams.put(AbilityKey.Cause, s.getHostCard());
game.getTriggerHandler().runTrigger(TriggerType.BecomesTargetOnce, runParams, false); game.getTriggerHandler().runTrigger(TriggerType.BecomesTargetOnce, runParams, false);
} }
} }
@@ -392,6 +393,7 @@ public class MagicStack /* extends MyObservable */ implements Iterable<SpellAbil
game.getTriggerHandler().runTrigger(TriggerType.BecomesTarget, runParams, false); game.getTriggerHandler().runTrigger(TriggerType.BecomesTarget, runParams, false);
runParams.put(AbilityKey.Targets, Lists.newArrayList(sp.getTargetCard())); runParams.put(AbilityKey.Targets, Lists.newArrayList(sp.getTargetCard()));
runParams.put(AbilityKey.Cause, sp.getHostCard());
game.getTriggerHandler().runTrigger(TriggerType.BecomesTargetOnce, runParams, false); game.getTriggerHandler().runTrigger(TriggerType.BecomesTargetOnce, runParams, false);
} }

View File

@@ -0,0 +1,22 @@
Name:Psychic Battle
ManaCost:3 U U
Types:Enchantment
T:Mode$ BecomesTargetOnce | ValidCause$ Card.notnamedPsychic Battle | TriggerZones$ Battlefield | Execute$ TrigReveal | TriggerDescription$ Whenever a player chooses one or more targets, each player reveals the top card of their library. The player who reveals the card with the highest converted mana cost may change the target or targets. If two or more cards are tied for highest cost, the target or targets remain unchanged. Changing targets this way doesn't trigger abilities of permanents named Psychic Battle.
SVar:TrigReveal:DB$ RepeatEach | RepeatPlayers$ Player | RepeatSubAbility$ DBDig | SubAbility$ DBChangeTargets
SVar:DBDig:DB$ Dig | Defined$ Remembered | DigNum$ 1 | Reveal$ True | NoMove$ True | RememberRevealed$ True | SubAbility$ DBCheckLibrary
SVar:DBCheckLibrary:DB$ Branch | BranchConditionSVar$ NumRememberedCard | TrueSubAbility$ DBCheckImprinted
SVar:DBCheckImprinted:DB$ Branch | BranchConditionSVar$ NumImprintedCard | TrueSubAbility$ DBCompareCMC | FalseSubAbility$ DBImprint | SubAbility$ DBCleanupRemembered
SVar:DBCompareCMC:DB$ Branch | BranchConditionSVar$ CMCRememberedCard | BranchConditionSVarCompare$ GTCMCImprintedCard | TrueSubAbility$ DBImprintForget | FalseSubAbility$ DBCompareCMC2
SVar:DBCompareCMC2:DB$ Branch | BranchConditionSVar$ CMCRememberedCard | BranchConditionSVarCompare$ EQCMCImprintedCard | TrueSubAbility$ DBCleanupImprinted
SVar:DBImprintForget:DB$ Cleanup | ClearImprinted$ True | SubAbility$ DBImprint
SVar:DBImprint:DB$ Pump | ImprintCards$ Remembered
SVar:DBChangeTargets:DB$ ChangeTargets | Defined$ TriggeredSourceSA | Chooser$ ImprintedOwner | Optional$ True | ConditionDefined$ Imprinted | ConditionPresent$ Card | ConditionCompare$ GE1 | SubAbility$ DBCleanupImprinted
SVar:DBCleanupRemembered:DB$ Cleanup | ClearRemembered$ True
SVar:DBCleanupImprinted:DB$ Cleanup | ClearImprinted$ True
SVar:NumRememberedCard:Remembered$Valid Card
SVar:NumImprintedCard:Imprinted$Valid Card
SVar:CMCRememberedCard:Remembered$CardManaCost
SVar:CMCImprintedCard:Imprinted$CardManaCost
SVar:NonStackingEffect:True
AI:RemoveDeck:Random
Oracle:Whenever a player chooses one or more targets, each player reveals the top card of their library. The player who reveals the card with the highest converted mana cost may change the target or targets. If two or more cards are tied for highest cost, the target or targets remain unchanged. Changing targets this way doesn't trigger abilities of permanents named Psychic Battle.