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 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<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
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,11 +280,16 @@ public class SpellAbilityStackInstance implements IIdentifiable, IHasCardView {
|
||||
runParams.put(AbilityKey.Target, tgt);
|
||||
getSourceCard().getGame().getTriggerHandler().runTrigger(TriggerType.BecomesTarget, 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean addTriggeringObject(AbilityKey trigObj, Object value) {
|
||||
if (!triggeringObjects.containsKey(trigObj)) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -380,6 +380,7 @@ public class MagicStack /* extends MyObservable */ implements Iterable<SpellAbil
|
||||
game.getTriggerHandler().runTrigger(TriggerType.BecomesTarget, runParams, false);
|
||||
}
|
||||
runParams.put(AbilityKey.Targets, tc);
|
||||
runParams.put(AbilityKey.Cause, s.getHostCard());
|
||||
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);
|
||||
|
||||
runParams.put(AbilityKey.Targets, Lists.newArrayList(sp.getTargetCard()));
|
||||
runParams.put(AbilityKey.Cause, sp.getHostCard());
|
||||
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 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 {
|
||||
|
||||
Reference in New Issue
Block a user