mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 03:08:02 +00:00
Merge branch 'psychic_battle' into 'master'
Add Psychic Battle See merge request core-developers/forge!4439
This commit is contained in:
@@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
22
forge-gui/res/cardsfolder/p/psychic_battle.txt
Normal file
22
forge-gui/res/cardsfolder/p/psychic_battle.txt
Normal 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.
|
||||||
@@ -1130,7 +1130,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
|||||||
}
|
}
|
||||||
final TargetChoices oldTarget = sa.getTargets();
|
final TargetChoices oldTarget = sa.getTargets();
|
||||||
final TargetSelection select = new TargetSelection(this, sa);
|
final TargetSelection select = new TargetSelection(this, sa);
|
||||||
sa.resetTargets();
|
sa.clearTargets();
|
||||||
if (select.chooseTargets(oldTarget.size(), Lists.newArrayList(oldTarget.getDividedValues()), filter, optional)) {
|
if (select.chooseTargets(oldTarget.size(), Lists.newArrayList(oldTarget.getDividedValues()), filter, optional)) {
|
||||||
return sa.getTargets();
|
return sa.getTargets();
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user