From 7603943c38257914c8034cf72efc61eabaa0177d Mon Sep 17 00:00:00 2001 From: Lyu Zong-Hong Date: Fri, 9 Apr 2021 14:06:51 +0900 Subject: [PATCH 1/2] Add Psychic Battle --- .../ability/effects/ChangeTargetsEffect.java | 16 +++++++------- .../SpellAbilityStackInstance.java | 13 +++++++---- .../trigger/TriggerBecomesTargetOnce.java | 3 +++ .../main/java/forge/game/zone/MagicStack.java | 2 ++ .../res/cardsfolder/p/psychic_battle.txt | 22 +++++++++++++++++++ 5 files changed, 44 insertions(+), 12 deletions(-) create mode 100644 forge-gui/res/cardsfolder/p/psychic_battle.txt diff --git a/forge-game/src/main/java/forge/game/ability/effects/ChangeTargetsEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ChangeTargetsEffect.java index 57d4bd08d8a..563498100b8 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ChangeTargetsEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ChangeTargetsEffect.java @@ -35,6 +35,7 @@ public class ChangeTargetsEffect extends SpellAbilityEffect { final List sas = getTargetSpells(sa); final boolean remember = sa.hasParam("RememberTargetedCard"); final Player activator = sa.getActivatingPlayer(); + final Player chooser = sa.hasParam("Chooser") ? getDefinedPlayersOrTargeted(sa, "Chooser").get(0) : sa.getActivatingPlayer(); final MagicStack stack = activator.getGame().getStack(); for (final SpellAbility tgtSA : sas) { @@ -45,7 +46,6 @@ public class ChangeTargetsEffect extends SpellAbilityEffect { } SpellAbilityStackInstance changingTgtSI = si; - Player chooser = sa.getActivatingPlayer(); // 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 @@ -79,7 +79,7 @@ public class ChangeTargetsEffect extends SpellAbilityEffect { // gets the divied value from old target Integer div = oldTargetBlock.getDividedValue(oldTarget); newTargetBlock.remove(oldTarget); - replaceIn.updateTarget(newTargetBlock); + replaceIn.updateTarget(newTargetBlock, sa.getHostCard()); // 3. test if updated choices would be correct. GameObject newTarget = Iterables.getFirst(getDefinedCardsOrTargeted(sa, "DefinedMagnet"), null); @@ -88,10 +88,10 @@ public class ChangeTargetsEffect extends SpellAbilityEffect { if (div != null) { newTargetBlock.addDividedAllocation(newTarget, div); } - replaceIn.updateTarget(newTargetBlock); + replaceIn.updateTarget(newTargetBlock, sa.getHostCard()); } else { - replaceIn.updateTarget(oldTargetBlock); + replaceIn.updateTarget(oldTargetBlock, sa.getHostCard()); } } else { @@ -109,7 +109,7 @@ public class ChangeTargetsEffect extends SpellAbilityEffect { changingTgtSA.addDividedAllocation(choice, div); } - changingTgtSI.updateTarget(changingTgtSA.getTargets()); + changingTgtSI.updateTarget(changingTgtSA.getTargets(), sa.getHostCard()); } else if (sa.hasParam("DefinedMagnet")){ GameObject newTarget = Iterables.getFirst(getDefinedCardsOrTargeted(sa, "DefinedMagnet"), null); @@ -117,7 +117,7 @@ public class ChangeTargetsEffect extends SpellAbilityEffect { int div = changingTgtSA.getTotalDividedValue(); changingTgtSA.resetTargets(); changingTgtSA.getTargets().add(newTarget); - changingTgtSI.updateTarget(changingTgtSA.getTargets()); + changingTgtSI.updateTarget(changingTgtSA.getTargets(), sa.getHostCard()); if (changingTgtSA.isDividedAsYouChoose()) { changingTgtSA.addDividedAllocation(newTarget, div); } @@ -127,9 +127,9 @@ public class ChangeTargetsEffect extends SpellAbilityEffect { // Update targets, with a potential new target Predicate 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 - TargetChoices newTarget = sa.getActivatingPlayer().getController().chooseNewTargetsFor(changingTgtSA, filter, false); + TargetChoices newTarget = chooser.getController().chooseNewTargetsFor(changingTgtSA, filter, false); if (null != newTarget) { - changingTgtSI.updateTarget(newTarget); + changingTgtSI.updateTarget(newTarget, sa.getHostCard()); } } } diff --git a/forge-game/src/main/java/forge/game/spellability/SpellAbilityStackInstance.java b/forge-game/src/main/java/forge/game/spellability/SpellAbilityStackInstance.java index c8c289bbc2c..ca047eadf30 100644 --- a/forge-game/src/main/java/forge/game/spellability/SpellAbilityStackInstance.java +++ b/forge-game/src/main/java/forge/game/spellability/SpellAbilityStackInstance.java @@ -250,7 +250,7 @@ public class SpellAbilityStackInstance implements IIdentifiable, IHasCardView { return playersWithValidTargets; } - public void updateTarget(TargetChoices target) { + public void updateTarget(TargetChoices target, Card cause) { if (target != null) { TargetChoices oldTarget = tc; tc = target; @@ -280,9 +280,14 @@ public class SpellAbilityStackInstance implements IIdentifiable, IHasCardView { runParams.put(AbilityKey.Target, tgt); getSourceCard().getGame().getTriggerHandler().runTrigger(TriggerType.BecomesTarget, runParams, false); } - runParams = AbilityKey.newMap(); - runParams.put(AbilityKey.Targets, distinctObjects); - getSourceCard().getGame().getTriggerHandler().runTrigger(TriggerType.BecomesTargetOnce, runParams, false); + // Only run BecomesTargetOnce when at least one target is changed + if (!distinctObjects.isEmpty()) { + 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); + } } } diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerBecomesTargetOnce.java b/forge-game/src/main/java/forge/game/trigger/TriggerBecomesTargetOnce.java index f1615cd434d..52bdb7d4058 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerBecomesTargetOnce.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerBecomesTargetOnce.java @@ -62,6 +62,9 @@ public class TriggerBecomesTargetOnce extends Trigger { if (!matchesValidParam("ValidTarget", runParams.get(AbilityKey.Targets))) { return false; } + if (!matchesValidParam("ValidCause", runParams.get(AbilityKey.Cause))) { + return false; + } return true; } diff --git a/forge-game/src/main/java/forge/game/zone/MagicStack.java b/forge-game/src/main/java/forge/game/zone/MagicStack.java index 58be16c0c8a..c07f29c7846 100644 --- a/forge-game/src/main/java/forge/game/zone/MagicStack.java +++ b/forge-game/src/main/java/forge/game/zone/MagicStack.java @@ -380,6 +380,7 @@ public class MagicStack /* extends MyObservable */ implements Iterable Date: Fri, 9 Apr 2021 15:12:13 +0900 Subject: [PATCH 2/2] Fix bug that when AI cast divide damage as you choose spells, human can't change targetcorrectly --- forge-gui/src/main/java/forge/player/PlayerControllerHuman.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java b/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java index 6ae278e4374..f36bf4a921d 100644 --- a/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java +++ b/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java @@ -1130,7 +1130,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont } final TargetChoices oldTarget = sa.getTargets(); final TargetSelection select = new TargetSelection(this, sa); - sa.resetTargets(); + sa.clearTargets(); if (select.chooseTargets(oldTarget.size(), Lists.newArrayList(oldTarget.getDividedValues()), filter, optional)) { return sa.getTargets(); } else {