add incomplete changes

This commit is contained in:
theelk801 2023-10-16 10:07:45 -04:00
parent b3bc6b94aa
commit 99d7b95dac
16 changed files with 196 additions and 136 deletions

View file

@ -4445,8 +4445,8 @@ public class TestPlayer implements Player {
} }
@Override @Override
public PlanarDieRollResult rollPlanarDie(Outcome outcome, Ability source, Game game, int numberChaosSides, int numberPlanarSides) { public PlanarDieRollResult rollPlanarDieResult(Outcome outcome, Ability source, Game game, int numberChaosSides, int numberPlanarSides) {
return computerPlayer.rollPlanarDie(outcome, source, game, numberChaosSides, numberPlanarSides); return computerPlayer.rollPlanarDieResult(outcome, source, game, numberChaosSides, numberPlanarSides);
} }
@Override @Override

View file

@ -986,7 +986,7 @@ public class PlayerStub implements Player {
@Override @Override
public List<Integer> getMultiAmountWithIndividualConstraints(Outcome outcome, List<MultiAmountMessage> messages, public List<Integer> getMultiAmountWithIndividualConstraints(Outcome outcome, List<MultiAmountMessage> messages,
int min, int max, MultiAmountType type, Game game) { int min, int max, MultiAmountType type, Game game) {
return null; return null;
} }
@ -1281,7 +1281,7 @@ public class PlayerStub implements Player {
} }
@Override @Override
public Map<UUID, Map<MageIdentifier,Costs<Cost>>> getCastSourceIdCosts() { public Map<UUID, Map<MageIdentifier, Costs<Cost>>> getCastSourceIdCosts() {
return null; return null;
} }
@ -1386,8 +1386,8 @@ public class PlayerStub implements Player {
} }
@Override @Override
public PlanarDieRollResult rollPlanarDie(Outcome outcome, Ability source, Game game, int numberChaosSides, int numberPlanarSides) { public PlanarDieRollResult rollPlanarDieResult(Outcome outcome, Ability source, Game game, int numberChaosSides, int numberPlanarSides) {
throw new UnsupportedOperationException("Not supported yet."); throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
} }
@Override @Override

View file

@ -125,7 +125,7 @@ public class RandomTest {
for (int x = 0; x < weight; x++) { for (int x = 0; x < weight; x++) {
for (int y = 0; y < height; y++) { for (int y = 0; y < height; y++) {
// roll planar dice // roll planar dice
PlanarDieRollResult res = player.rollPlanarDie(Outcome.Neutral, null, game); PlanarDieRollResult res = player.rollPlanarDieResult(Outcome.Neutral, null, game);
image.setRGB(x, y, new Color( image.setRGB(x, y, new Color(
res.equals(PlanarDieRollResult.CHAOS_ROLL) ? 255 : 0, res.equals(PlanarDieRollResult.CHAOS_ROLL) ? 255 : 0,
res.equals(PlanarDieRollResult.PLANAR_ROLL) ? 255 : 0, res.equals(PlanarDieRollResult.PLANAR_ROLL) ? 255 : 0,

View file

@ -14,6 +14,8 @@ import mage.game.permanent.Permanent;
import mage.players.Player; import mage.players.Player;
import mage.util.CardUtil; import mage.util.CardUtil;
import java.util.Objects;
import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
@ -147,8 +149,7 @@ public abstract class ActivatedAbilityImpl extends AbilityImpl implements Activa
if (approvingObjects.isEmpty()) { if (approvingObjects.isEmpty()) {
return ActivationStatus.withoutApprovingObject(true); return ActivationStatus.withoutApprovingObject(true);
} } else {
else {
return new ActivationStatus(approvingObjects); return new ActivationStatus(approvingObjects);
} }
} }
@ -249,6 +250,14 @@ public abstract class ActivatedAbilityImpl extends AbilityImpl implements Activa
return new ActivationInfo(turnNum, activationCount, totalActivations); return new ActivationInfo(turnNum, activationCount, totalActivations);
} }
public int getActivatedThisTurnCount(Game game) {
return Optional
.ofNullable(getActivationInfo(game))
.filter(Objects::nonNull)
.map(a -> a.activationCounter)
.orElse(0);
}
protected void setActivationInfo(ActivationInfo activationInfo, Game game) { protected void setActivationInfo(ActivationInfo activationInfo, Game game) {
game.getState().setValue(CardUtil game.getState().setValue(CardUtil
.getCardZoneString("activationsTurn" + originalId, sourceId, game), activationInfo.turnNum); .getCardZoneString("activationsTurn" + originalId, sourceId, game), activationInfo.turnNum);

View file

@ -0,0 +1,37 @@
package mage.abilities.common;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.Effect;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
/**
* @author TheElk801
*/
public class ChaosEnsuesTriggeredAbility extends TriggeredAbilityImpl {
public ChaosEnsuesTriggeredAbility(Effect effect) {
super(Zone.COMMAND, effect);
this.setTriggerPhrase("Whenever chaos ensues, ");
}
private ChaosEnsuesTriggeredAbility(final ChaosEnsuesTriggeredAbility ability) {
super(ability);
}
@Override
public ChaosEnsuesTriggeredAbility copy() {
return new ChaosEnsuesTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.CHAOS_ENSUES;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return true;
}
}

View file

@ -0,0 +1,70 @@
package mage.abilities.common;
import mage.abilities.Ability;
import mage.abilities.SpecialAction;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.OneShotEffect;
import mage.constants.Outcome;
import mage.game.Game;
import mage.players.Player;
import java.util.UUID;
/**
* @author TheElk801
*/
public class RollPlanarDieSpecialAction extends SpecialAction {
public RollPlanarDieSpecialAction(UUID playerId) {
super();
this.addEffect(new RollPlanarDieSpecialActionEffect());
this.setControllerId(playerId);
this.setCostAdjuster((ability, game) -> {
int count = ((SpecialAction) ability).getActivatedThisTurnCount(game);
ability.getCosts().clear();
if (count > 0) {
ability.addCost(new GenericManaCost(count));
}
});
}
private RollPlanarDieSpecialAction(final RollPlanarDieSpecialAction action) {
super(action);
}
@Override
public RollPlanarDieSpecialAction copy() {
return new RollPlanarDieSpecialAction(this);
}
@Override
public String getRule() {
return "this is the rule";
}
}
class RollPlanarDieSpecialActionEffect extends OneShotEffect {
RollPlanarDieSpecialActionEffect() {
super(Outcome.Benefit);
}
private RollPlanarDieSpecialActionEffect(final RollPlanarDieSpecialActionEffect effect) {
super(effect);
}
@Override
public RollPlanarDieSpecialActionEffect copy() {
return new RollPlanarDieSpecialActionEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player == null) {
return false;
}
player.rollPlanarDieResult(outcome, source, game);
return true;
}
}

View file

@ -61,7 +61,7 @@ public class RollPlanarDieEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
MageObject mageObject = game.getObject(source); MageObject mageObject = game.getObject(source);
if (controller != null && mageObject != null) { if (controller != null && mageObject != null) {
PlanarDieRollResult planarRoll = controller.rollPlanarDie(outcome, source, game); PlanarDieRollResult planarRoll = controller.rollPlanarDieResult(outcome, source, game);
if (planarRoll == PlanarDieRollResult.CHAOS_ROLL && chaosEffects != null && chaosTargets != null) { if (planarRoll == PlanarDieRollResult.CHAOS_ROLL && chaosEffects != null && chaosTargets != null) {
for (int i = 0; i < chaosTargets.size(); i++) { for (int i = 0; i < chaosTargets.size(); i++) {
Target target = chaosTargets.get(i); Target target = chaosTargets.get(i);

View file

@ -6,6 +6,7 @@ import mage.choices.TwoChoiceVote;
import mage.constants.AbilityWord; import mage.constants.AbilityWord;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.game.Game; import mage.game.Game;
import mage.game.events.GameEvent;
/** /**
* @author TheElk801 * @author TheElk801
@ -37,9 +38,15 @@ public class WillOfThePlaneswalkersEffect extends OneShotEffect {
int chaosCount = vote.getVoteCount(false); int chaosCount = vote.getVoteCount(false);
// TODO: Implement when planes have been refactored // TODO: Implement when planes have been refactored
if (planeswalkCount > chaosCount) { if (planeswalkCount > chaosCount) {
// planeswalk to next plane game.fireEvent(GameEvent.getEvent(
GameEvent.EventType.ROLLED_PLANESWALK,
source.getControllerId(), source, source.getControllerId()
));
} else { } else {
// chaos ensues game.fireEvent(GameEvent.getEvent(
GameEvent.EventType.CHAOS_ENSUES,
source.getControllerId(), source, source.getControllerId()
));
} }
return true; return true;
} }

View file

@ -3,10 +3,7 @@ package mage.game;
import mage.MageException; import mage.MageException;
import mage.MageObject; import mage.MageObject;
import mage.abilities.*; import mage.abilities.*;
import mage.abilities.common.AttachableToRestrictedAbility; import mage.abilities.common.*;
import mage.abilities.common.CantHaveMoreThanAmountCountersSourceAbility;
import mage.abilities.common.SagaAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.common.delayed.ReflexiveTriggeredAbility; import mage.abilities.common.delayed.ReflexiveTriggeredAbility;
import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.ContinuousEffects; import mage.abilities.effects.ContinuousEffects;
@ -1331,6 +1328,9 @@ public abstract class GameImpl implements Game {
plane.setControllerId(startingPlayerId); plane.setControllerId(startingPlayerId);
addPlane(plane, startingPlayerId); addPlane(plane, startingPlayerId);
state.setPlaneChase(this, gameOptions.planeChase); state.setPlaneChase(this, gameOptions.planeChase);
for (UUID playerId : state.getPlayerList()) {
state.getSpecialActions().add(new RollPlanarDieSpecialAction(playerId));
}
} }
if (!gameOptions.perPlayerEmblemCards.isEmpty()) { if (!gameOptions.perPlayerEmblemCards.isEmpty()) {

View file

@ -1,18 +1,12 @@
package mage.game.command.planes; package mage.game.command.planes;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.ActivateIfConditionActivatedAbility;
import mage.abilities.common.BeginningOfEndStepTriggeredAbility; import mage.abilities.common.BeginningOfEndStepTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.ChaosEnsuesTriggeredAbility;
import mage.abilities.condition.Condition; import mage.abilities.condition.Condition;
import mage.abilities.condition.common.MainPhaseStackEmptyCondition;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.StaticValue; import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.RollPlanarDieEffect;
import mage.abilities.effects.common.cost.PlanarDieRollCostIncreasingEffect;
import mage.abilities.effects.common.discard.DiscardHandControllerEffect; import mage.abilities.effects.common.discard.DiscardHandControllerEffect;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.constants.Planes; import mage.constants.Planes;
@ -21,12 +15,7 @@ import mage.constants.Zone;
import mage.game.Game; import mage.game.Game;
import mage.game.command.Plane; import mage.game.command.Plane;
import mage.players.Player; import mage.players.Player;
import mage.target.Target;
import mage.util.CardUtil; import mage.util.CardUtil;
import mage.watchers.common.PlanarRollWatcher;
import java.util.ArrayList;
import java.util.List;
/** /**
* @author spjspj * @author spjspj
@ -37,24 +26,13 @@ public class AcademyAtTolariaWestPlane extends Plane {
this.setPlaneType(Planes.PLANE_ACADEMY_AT_TOLARIA_WEST); this.setPlaneType(Planes.PLANE_ACADEMY_AT_TOLARIA_WEST);
// At the beginning of your end step, if you have 0 cards in hand, draw seven cards // At the beginning of your end step, if you have 0 cards in hand, draw seven cards
Ability ability = new BeginningOfEndStepTriggeredAbility(Zone.COMMAND, new DrawCardsActivePlayerEffect(7), TargetController.ANY, HellbentAPCondition.instance, false); this.addAbility(new BeginningOfEndStepTriggeredAbility(
this.getAbilities().add(ability); Zone.COMMAND, new DrawCardsActivePlayerEffect(7),
TargetController.ANY, HellbentAPCondition.instance, false
));
// Active player can roll the planar die: Whenever you roll {CHAOS}, discard your hand // Active player can roll the planar die: Whenever you roll {CHAOS}, discard your hand
Effect chaosEffect = new DiscardHandControllerEffect(); this.addAbility(new ChaosEnsuesTriggeredAbility(new DiscardHandControllerEffect()));
Target chaosTarget = null;
List<Effect> chaosEffects = new ArrayList<Effect>();
chaosEffects.add(chaosEffect);
List<Target> chaosTargets = new ArrayList<Target>();
chaosTargets.add(chaosTarget);
ActivateIfConditionActivatedAbility chaosAbility = new ActivateIfConditionActivatedAbility(Zone.COMMAND, new RollPlanarDieEffect(chaosEffects, chaosTargets), new GenericManaCost(0), MainPhaseStackEmptyCondition.instance);
chaosAbility.addWatcher(new PlanarRollWatcher());
this.getAbilities().add(chaosAbility);
chaosAbility.setMayActivate(TargetController.ANY);
this.getAbilities().add(new SimpleStaticAbility(Zone.ALL, new PlanarDieRollCostIncreasingEffect(chaosAbility.getOriginalId())));
} }
private AcademyAtTolariaWestPlane(final AcademyAtTolariaWestPlane plane) { private AcademyAtTolariaWestPlane(final AcademyAtTolariaWestPlane plane) {

View file

@ -2,19 +2,14 @@ package mage.game.command.planes;
import mage.ObjectColor; import mage.ObjectColor;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.ActivateIfConditionActivatedAbility; import mage.abilities.common.ChaosEnsuesTriggeredAbility;
import mage.abilities.common.DiesCreatureTriggeredAbility; import mage.abilities.common.DiesCreatureTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
import mage.abilities.condition.common.MainPhaseStackEmptyCondition;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.Effect; import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.RestrictionEffect; import mage.abilities.effects.RestrictionEffect;
import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect; import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect;
import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect;
import mage.abilities.effects.common.RollPlanarDieEffect;
import mage.abilities.effects.common.cost.PlanarDieRollCostIncreasingEffect;
import mage.cards.Card; import mage.cards.Card;
import mage.constants.*; import mage.constants.*;
import mage.filter.common.FilterCreaturePermanent; import mage.filter.common.FilterCreaturePermanent;
@ -23,12 +18,8 @@ import mage.filter.predicate.mageobject.ColorPredicate;
import mage.game.Game; import mage.game.Game;
import mage.game.command.Plane; import mage.game.command.Plane;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.target.Target;
import mage.target.targetpointer.FixedTarget; import mage.target.targetpointer.FixedTarget;
import mage.watchers.common.PlanarRollWatcher;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID; import java.util.UUID;
/** /**
@ -48,26 +39,17 @@ public class AgyremPlane extends Plane {
this.setPlaneType(Planes.PLANE_AGYREM); this.setPlaneType(Planes.PLANE_AGYREM);
// Whenever a white creature dies, return it to the battlefield under its owner's control at the beginning of the next end step // Whenever a white creature dies, return it to the battlefield under its owner's control at the beginning of the next end step
DiesCreatureTriggeredAbility ability = new DiesCreatureTriggeredAbility(Zone.COMMAND, new AgyremEffect(), false, filterWhite, true); this.addAbility(new DiesCreatureTriggeredAbility(
this.getAbilities().add(ability); Zone.COMMAND, new AgyremEffect(), false, filterWhite, true
));
// Whenever a nonwhite creature dies, return it to its owner's hand at the beginning of the next end step. // Whenever a nonwhite creature dies, return it to its owner's hand at the beginning of the next end step.
DiesCreatureTriggeredAbility ability2 = new DiesCreatureTriggeredAbility(Zone.COMMAND, new AgyremEffect2(), false, filterNonWhite, true); this.getAbilities().add(new DiesCreatureTriggeredAbility(
this.getAbilities().add(ability2); Zone.COMMAND, new AgyremEffect2(), false, filterNonWhite, true
));
// Active player can roll the planar die: Whenever you roll {CHAOS}, creatures can't attack you until a player planeswalks // Active player can roll the planar die: Whenever you roll {CHAOS}, creatures can't attack you until a player planeswalks
Effect chaosEffect = new AgyremRestrictionEffect(); this.addAbility(new ChaosEnsuesTriggeredAbility(new AgyremRestrictionEffect()));
Target chaosTarget = null;
List<Effect> chaosEffects = new ArrayList<>();
chaosEffects.add(chaosEffect);
List<Target> chaosTargets = new ArrayList<>();
chaosTargets.add(chaosTarget);
ActivateIfConditionActivatedAbility chaosAbility = new ActivateIfConditionActivatedAbility(Zone.COMMAND, new RollPlanarDieEffect(chaosEffects, chaosTargets), new GenericManaCost(0), MainPhaseStackEmptyCondition.instance);
chaosAbility.addWatcher(new PlanarRollWatcher());
this.getAbilities().add(chaosAbility);
chaosAbility.setMayActivate(TargetController.ANY);
this.getAbilities().add(new SimpleStaticAbility(Zone.ALL, new PlanarDieRollCostIncreasingEffect(chaosAbility.getOriginalId())));
} }
private AgyremPlane(final AgyremPlane plane) { private AgyremPlane(final AgyremPlane plane) {

View file

@ -1,26 +1,21 @@
package mage.game.command.planes; package mage.game.command.planes;
import mage.abilities.common.ActivateIfConditionActivatedAbility; import mage.abilities.Ability;
import mage.abilities.common.ChaosEnsuesTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.common.MainPhaseStackEmptyCondition;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.effects.common.DestroyTargetEffect;
import mage.abilities.effects.common.RollPlanarDieEffect;
import mage.abilities.effects.common.continuous.CastAsThoughItHadFlashAllEffect; import mage.abilities.effects.common.continuous.CastAsThoughItHadFlashAllEffect;
import mage.abilities.effects.common.cost.PlanarDieRollCostIncreasingEffect; import mage.constants.CardType;
import mage.constants.*; import mage.constants.Duration;
import mage.constants.Planes;
import mage.constants.Zone;
import mage.filter.FilterCard; import mage.filter.FilterCard;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterCreaturePermanent; import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.Predicates; import mage.filter.predicate.Predicates;
import mage.filter.predicate.permanent.EnchantedPredicate; import mage.filter.predicate.permanent.EnchantedPredicate;
import mage.game.command.Plane; import mage.game.command.Plane;
import mage.target.Target; import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
import mage.watchers.common.PlanarRollWatcher;
import java.util.ArrayList;
import java.util.List;
/** /**
* @author spjspj * @author spjspj
@ -28,7 +23,7 @@ import java.util.List;
public class AkoumPlane extends Plane { public class AkoumPlane extends Plane {
private static final FilterCard filterCard = new FilterCard("enchantment spells"); private static final FilterCard filterCard = new FilterCard("enchantment spells");
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature that isn't enchanted"); private static final FilterPermanent filter = new FilterCreaturePermanent("creature that isn't enchanted");
static { static {
filter.add(Predicates.not(EnchantedPredicate.instance)); filter.add(Predicates.not(EnchantedPredicate.instance));
@ -39,23 +34,14 @@ public class AkoumPlane extends Plane {
this.setPlaneType(Planes.PLANE_AKOUM); this.setPlaneType(Planes.PLANE_AKOUM);
// Players may cast enchantment spells as if they had flash // Players may cast enchantment spells as if they had flash
SimpleStaticAbility ability = new SimpleStaticAbility(Zone.COMMAND, new CastAsThoughItHadFlashAllEffect(Duration.Custom, filterCard, true)); this.addAbility(new SimpleStaticAbility(
this.getAbilities().add(ability); Zone.COMMAND, new CastAsThoughItHadFlashAllEffect(Duration.Custom, filterCard, true)
));
// Active player can roll the planar die: Whenever you roll {CHAOS}, destroy target creature that isn't enchanted // Active player can roll the planar die: Whenever you roll {CHAOS}, destroy target creature that isn't enchanted
Effect chaosEffect = new DestroyTargetEffect("destroy target creature that isn't enchanted"); Ability ability = new ChaosEnsuesTriggeredAbility(new DestroyTargetEffect());
Target chaosTarget = new TargetCreaturePermanent(filter); ability.addTarget(new TargetPermanent(filter));
this.addAbility(ability);
List<Effect> chaosEffects = new ArrayList<Effect>();
chaosEffects.add(chaosEffect);
List<Target> chaosTargets = new ArrayList<Target>();
chaosTargets.add(chaosTarget);
ActivateIfConditionActivatedAbility chaosAbility = new ActivateIfConditionActivatedAbility(Zone.COMMAND, new RollPlanarDieEffect(chaosEffects, chaosTargets), new GenericManaCost(0), MainPhaseStackEmptyCondition.instance);
chaosAbility.addWatcher(new PlanarRollWatcher());
this.getAbilities().add(chaosAbility);
chaosAbility.setMayActivate(TargetController.ANY);
this.getAbilities().add(new SimpleStaticAbility(Zone.ALL, new PlanarDieRollCostIncreasingEffect(chaosAbility.getOriginalId())));
} }
private AkoumPlane(final AkoumPlane plane) { private AkoumPlane(final AkoumPlane plane) {

View file

@ -1,29 +1,18 @@
package mage.game.command.planes; package mage.game.command.planes;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.ActivateIfConditionActivatedAbility; import mage.abilities.common.ChaosEnsuesTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.common.MainPhaseStackEmptyCondition;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.Effect;
import mage.abilities.effects.RestrictionEffect; import mage.abilities.effects.RestrictionEffect;
import mage.abilities.effects.common.DamageAllEffect; import mage.abilities.effects.common.DamageAllEffect;
import mage.abilities.effects.common.RollPlanarDieEffect;
import mage.abilities.effects.common.cost.PlanarDieRollCostIncreasingEffect;
import mage.constants.Duration; import mage.constants.Duration;
import mage.constants.Planes; import mage.constants.Planes;
import mage.constants.TargetController;
import mage.constants.Zone; import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent; import mage.filter.StaticFilters;
import mage.game.Game; import mage.game.Game;
import mage.game.command.Plane; import mage.game.command.Plane;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.target.Target;
import mage.watchers.common.AttackedThisTurnWatcher;
import mage.watchers.common.PlanarRollWatcher;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID; import java.util.UUID;
/** /**
@ -35,27 +24,11 @@ public class AstralArenaPlane extends Plane {
this.setPlaneType(Planes.PLANE_ASTRAL_ARENA); this.setPlaneType(Planes.PLANE_ASTRAL_ARENA);
// No more than one creature can attack each turn. No more than one creature can block each turn. // No more than one creature can attack each turn. No more than one creature can block each turn.
SimpleStaticAbility ability = new SimpleStaticAbility(Zone.COMMAND, new AstralArenaAttackRestrictionEffect()); this.addAbility(new SimpleStaticAbility(Zone.COMMAND, new AstralArenaAttackRestrictionEffect()));
ability.addWatcher(new AttackedThisTurnWatcher()); this.addAbility(new SimpleStaticAbility(Zone.COMMAND, new AstralArenaBlockRestrictionEffect()));
SimpleStaticAbility ability2 = new SimpleStaticAbility(Zone.COMMAND, new AstralArenaBlockRestrictionEffect());
ability2.addWatcher(new AttackedThisTurnWatcher());
this.getAbilities().add(ability);
this.getAbilities().add(ability2);
// Active player can roll the planar die: Whenever you roll {CHAOS}, {this} deals 2 damage to each creature // Active player can roll the planar die: Whenever you roll {CHAOS}, {this} deals 2 damage to each creature
Effect chaosEffect = new DamageAllEffect(2, new FilterCreaturePermanent()); this.addAbility(new ChaosEnsuesTriggeredAbility(new DamageAllEffect(2, StaticFilters.FILTER_PERMANENT_CREATURE)));
Target chaosTarget = null;
List<Effect> chaosEffects = new ArrayList<Effect>();
chaosEffects.add(chaosEffect);
List<Target> chaosTargets = new ArrayList<Target>();
chaosTargets.add(chaosTarget);
ActivateIfConditionActivatedAbility chaosAbility = new ActivateIfConditionActivatedAbility(Zone.COMMAND, new RollPlanarDieEffect(chaosEffects, chaosTargets), new GenericManaCost(0), MainPhaseStackEmptyCondition.instance);
chaosAbility.addWatcher(new PlanarRollWatcher());
this.getAbilities().add(chaosAbility);
chaosAbility.setMayActivate(TargetController.ANY);
this.getAbilities().add(new SimpleStaticAbility(Zone.ALL, new PlanarDieRollCostIncreasingEffect(chaosAbility.getOriginalId())));
} }
private AstralArenaPlane(final AstralArenaPlane plane) { private AstralArenaPlane(final AstralArenaPlane plane) {

View file

@ -329,6 +329,8 @@ public class GameEvent implements Serializable {
REPLACE_ROLLED_DIE, // for Clam-I-Am workaround only REPLACE_ROLLED_DIE, // for Clam-I-Am workaround only
ROLL_DIE, DIE_ROLLED, ROLL_DIE, DIE_ROLLED,
ROLL_DICE, DICE_ROLLED, ROLL_DICE, DICE_ROLLED,
ROLLED_PLANESWALK,CHAOS_ENSUES,
PLANESWALK, PLANESWALKED, PLANESWALK, PLANESWALKED,
PAID_CUMULATIVE_UPKEEP, PAID_CUMULATIVE_UPKEEP,
DIDNT_PAY_CUMULATIVE_UPKEEP, DIDNT_PAY_CUMULATIVE_UPKEEP,

View file

@ -514,11 +514,27 @@ public interface Player extends MageItem, Copyable<Player> {
int rollDieResult(int sides, Game game); int rollDieResult(int sides, Game game);
default PlanarDieRollResult rollPlanarDie(Outcome outcome, Ability source, Game game) { default void rollPlanarDie(Ability source, Game game) {
return rollPlanarDie(outcome, source, game, GameOptions.PLANECHASE_PLANAR_DIE_CHAOS_SIDES, GameOptions.PLANECHASE_PLANAR_DIE_PLANAR_SIDES); switch (rollPlanarDieResult(Outcome.Neutral, source, game)) {
case CHAOS_ROLL:
game.fireEvent(GameEvent.getEvent(
GameEvent.EventType.ROLLED_PLANESWALK,
source.getControllerId(), source, source.getControllerId()
));
return;
case PLANAR_ROLL:
game.fireEvent(GameEvent.getEvent(
GameEvent.EventType.CHAOS_ENSUES,
source.getControllerId(), source, source.getControllerId()
));
}
} }
PlanarDieRollResult rollPlanarDie(Outcome outcome, Ability source, Game game, int numberChaosSides, int numberPlanarSides); default PlanarDieRollResult rollPlanarDieResult(Outcome outcome, Ability source, Game game) {
return rollPlanarDieResult(outcome, source, game, GameOptions.PLANECHASE_PLANAR_DIE_CHAOS_SIDES, GameOptions.PLANECHASE_PLANAR_DIE_PLANAR_SIDES);
}
PlanarDieRollResult rollPlanarDieResult(Outcome outcome, Ability source, Game game, int numberChaosSides, int numberPlanarSides);
Card discardOne(boolean random, boolean payForCost, Ability source, Game game); Card discardOne(boolean random, boolean payForCost, Ability source, Game game);

View file

@ -3298,7 +3298,7 @@ public abstract class PlayerImpl implements Player, Serializable {
* or BlankRoll * or BlankRoll
*/ */
@Override @Override
public PlanarDieRollResult rollPlanarDie(Outcome outcome, Ability source, Game game, int chaosSidesAmount, int planarSidesAmount) { public PlanarDieRollResult rollPlanarDieResult(Outcome outcome, Ability source, Game game, int chaosSidesAmount, int planarSidesAmount) {
return rollDiceInner(outcome, source, game, RollDieType.PLANAR, GameOptions.PLANECHASE_PLANAR_DIE_TOTAL_SIDES, chaosSidesAmount, planarSidesAmount, 1, 0) return rollDiceInner(outcome, source, game, RollDieType.PLANAR, GameOptions.PLANECHASE_PLANAR_DIE_TOTAL_SIDES, chaosSidesAmount, planarSidesAmount, 1, 0)
.stream() .stream()
.map(o -> (PlanarDieRollResult) o) .map(o -> (PlanarDieRollResult) o)