mirror of
https://github.com/magefree/mage.git
synced 2025-12-28 14:32:06 -08:00
refactor: simpler processAction syntax (#12458)
* game.processAction() instead of game.getState().processAction(game) * add simpler method name and docs * find/replace to new method * remove old method * deprecate applyEffects
This commit is contained in:
parent
e2b1d980b6
commit
d61de05eb8
163 changed files with 218 additions and 217 deletions
|
|
@ -248,7 +248,7 @@ public abstract class AbilityImpl implements Ability {
|
|||
* abilities with replacement effects deactivated too late Example:
|
||||
* {@link org.mage.test.cards.replacement.DryadMilitantTest#testDiesByDestroy testDiesByDestroy}
|
||||
*/
|
||||
game.getState().processAction(game);
|
||||
game.processAction();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ class AnimateDeadPutOntoBattlefieldEffect extends OneShotEffect {
|
|||
}
|
||||
// Put card onto the battlefield under your control...
|
||||
player.moveCards(card, Zone.BATTLEFIELD, source, game, tapped, false, false, null);
|
||||
game.getState().processAction(game);
|
||||
game.processAction();
|
||||
|
||||
Permanent creature = game.getPermanent(CardUtil.getDefaultCardSideForBattlefield(game, card).getId());
|
||||
if (creature == null) {
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ public class DevourEffect extends ReplacementEffectImpl {
|
|||
+ filterDevoured.getMessage() + (devouredCreatures > 1 ? "s" : "")
|
||||
);
|
||||
|
||||
game.getState().processAction(game); // need for multistep effects
|
||||
game.processAction(); // need for multistep effects
|
||||
|
||||
int amountCounters;
|
||||
if (devourFactor == Integer.MAX_VALUE) {
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ public class ExileThenReturnTargetEffect extends OneShotEffect {
|
|||
return false;
|
||||
}
|
||||
controller.moveCards(toFlicker, Zone.EXILED, source, game);
|
||||
game.getState().processAction(game);
|
||||
game.processAction();
|
||||
for (Card card : toFlicker) {
|
||||
putCards.moveCard(
|
||||
yourControl ? controller : game.getPlayer(card.getOwnerId()),
|
||||
|
|
|
|||
|
|
@ -47,14 +47,14 @@ public class LivingDeathEffect extends OneShotEffect {
|
|||
}
|
||||
}
|
||||
}
|
||||
game.getState().processAction(game);
|
||||
game.processAction();
|
||||
|
||||
// Sacrifice all creatures
|
||||
for (Permanent permanent : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), game)) {
|
||||
permanent.sacrifice(source, game);
|
||||
}
|
||||
|
||||
game.getState().processAction(game);
|
||||
game.processAction();
|
||||
|
||||
// Exiled cards are put onto the battlefield at the same time under their owner's control
|
||||
Set<Card> cardsToReturnFromExile = new HashSet<>();
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ public class ShuffleHandIntoLibraryDrawThatManySourceEffect extends OneShotEffec
|
|||
if (cardsHand > 0) {
|
||||
controller.moveCards(controller.getHand(), Zone.LIBRARY, source, game);
|
||||
controller.shuffleLibrary(source, game);
|
||||
game.getState().processAction(game); // then
|
||||
game.processAction(); // then
|
||||
controller.drawCards(cardsHand, source, game);
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ public class GainControlAllUntapGainHasteEffect extends OneShotEffect {
|
|||
FilterPermanent affectedFilter = new FilterPermanent();
|
||||
affectedFilter.add(new PermanentReferenceInCollectionPredicate(affectedObjects, game));
|
||||
new GainControlAllEffect(Duration.EndOfTurn, affectedFilter).apply(game, source);
|
||||
game.getState().processAction(game);
|
||||
game.processAction();
|
||||
new UntapAllEffect(affectedFilter).apply(game, source);
|
||||
game.addEffect(new GainAbilityAllEffect(HasteAbility.getInstance(), Duration.EndOfTurn, affectedFilter), source);
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ public class DiscoverEffect extends OneShotEffect {
|
|||
for (Card card : player.getLibrary().getCards(game)) {
|
||||
cards.add(card);
|
||||
player.moveCards(card, Zone.EXILED, source, game);
|
||||
game.getState().processAction(game);
|
||||
game.processAction();
|
||||
if (filter.match(card, game)) {
|
||||
return card;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ public class ExploreSourceEffect extends OneShotEffect {
|
|||
// the exploring creature receives a +1/+1 counter.
|
||||
addCounter(game, permanent, source);
|
||||
}
|
||||
game.getState().processAction(game);
|
||||
game.processAction();
|
||||
// 701.40b A permanent “explores” after the process described in rule 701.40a is complete, even if some or all of
|
||||
// those actions were impossible.
|
||||
game.fireEvent(new ExploredEvent(permanent, source, card));
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ class CascadeEffect extends OneShotEffect {
|
|||
cardsToExile.add(card);
|
||||
// the card move is sequential, not all at once.
|
||||
controller.moveCards(card, Zone.EXILED, source, game);
|
||||
game.getState().processAction(game); // Laelia, the Blade Reforged
|
||||
game.processAction(); // Laelia, the Blade Reforged
|
||||
if (!card.isLand(game)
|
||||
&& card.getManaValue() < sourceCost) {
|
||||
cardToCast = card;
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ class MadnessReplacementEffect extends ReplacementEffectImpl {
|
|||
}
|
||||
|
||||
// needed to add Madness ability to cards (e.g. by Falkenrath Gorger)
|
||||
game.getState().processAction(game);
|
||||
game.processAction();
|
||||
|
||||
GameEvent gameEvent = new MadnessCardExiledEvent(card.getId(), source, controller.getId());
|
||||
game.fireEvent(gameEvent);
|
||||
|
|
|
|||
|
|
@ -610,7 +610,7 @@ public abstract class CardImpl extends MageObjectImpl implements Card {
|
|||
// This is somewhat a band-aid on the special action nature of turning a permanent face up.
|
||||
// 708.8. As a face-down permanent is turned face up, its copiable values revert to its normal copiable values.
|
||||
// Any effects that have been applied to the face-down permanent still apply to the face-up permanent.
|
||||
game.getState().processAction(game);
|
||||
game.processAction();
|
||||
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.TURNED_FACE_UP, getId(), source, playerId));
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -505,14 +505,30 @@ public interface Game extends MageItem, Serializable, Copyable<Game> {
|
|||
UUID fireReflexiveTriggeredAbility(ReflexiveTriggeredAbility reflexiveAbility, Ability source, boolean fireAsSimultaneousEvent);
|
||||
|
||||
/**
|
||||
* Inner game engine call to reset game objects to actual versions
|
||||
* (reset all objects and apply all effects due layer system)
|
||||
* <p>
|
||||
* Warning, if you need to process object moves in the middle of the effect/ability
|
||||
* then call game.getState().processAction(game) instead
|
||||
* Inner engine call to reset all game objects and re-apply all layered continuous effects.
|
||||
* Do NOT use indiscriminately. See processAction() instead.
|
||||
*/
|
||||
@Deprecated
|
||||
void applyEffects();
|
||||
|
||||
/**
|
||||
* Handles simultaneous events for triggers and then re-applies all layered continuous effects.
|
||||
* Must be called between sequential steps of a resolving one-shot effect.
|
||||
* <p>
|
||||
* 608.2e. Some spells and abilities have multiple steps or actions, denoted by separate sentences or clauses,
|
||||
* that involve multiple players. In these cases, the choices for the first action are made in APNAP order,
|
||||
* and then the first action is processed simultaneously. Then the choices for the second action are made in
|
||||
* APNAP order, and then that action is processed simultaneously, and so on. See rule 101.4.
|
||||
* <p>
|
||||
* 608.2f. Some spells and abilities include actions taken on multiple players and/or objects. In most cases,
|
||||
* each such action is processed simultaneously. If the action can't be processed simultaneously, it's instead
|
||||
* processed considering each affected player or object individually. APNAP order is used to make the primary
|
||||
* determination of the order of those actions. Secondarily, if the action is to be taken on both a player
|
||||
* and an object they control or on multiple objects controlled by the same player, the player who controls
|
||||
* the resolving spell or ability chooses the relative order of those actions.
|
||||
*/
|
||||
void processAction();
|
||||
|
||||
@Deprecated // TODO: must research usage and remove it from all non engine code (example: Bestow ability, ProcessActions must be used instead)
|
||||
boolean checkStateAndTriggered();
|
||||
|
||||
|
|
|
|||
|
|
@ -1927,6 +1927,14 @@ public abstract class GameImpl implements Game {
|
|||
state.applyEffects(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processAction() {
|
||||
state.handleSimultaneousEvent(this);
|
||||
resetShortLivingLKI();
|
||||
applyEffects();
|
||||
state.getTriggers().checkStateTriggers(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addEffect(ContinuousEffect continuousEffect, Ability source) {
|
||||
Ability newAbility = source.copy();
|
||||
|
|
@ -2241,20 +2249,17 @@ public abstract class GameImpl implements Game {
|
|||
}
|
||||
|
||||
/**
|
||||
* 116.5. Each time a player would get priority, the game first performs all
|
||||
* 117.5. Each time a player would get priority, the game first performs all
|
||||
* applicable state-based actions as a single event (see rule 704,
|
||||
* “State-Based Actions”), then repeats this process until no state-based
|
||||
* actions are performed. Then triggered abilities are put on the stack (see
|
||||
* rule 603, “Handling Triggered Abilities”). These steps repeat in order
|
||||
* until no further state-based actions are performed and no abilities
|
||||
* trigger. Then the player who would have received priority does so.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public boolean checkStateAndTriggered() {
|
||||
boolean somethingHappened = false;
|
||||
//20091005 - 115.5
|
||||
while (!isPaused() && !checkIfGameIsOver()) {
|
||||
if (!checkStateBasedActions()) {
|
||||
// nothing happened so check triggers
|
||||
|
|
@ -2263,7 +2268,7 @@ public abstract class GameImpl implements Game {
|
|||
break;
|
||||
}
|
||||
}
|
||||
this.getState().processAction(this); // needed e.g if boost effects end and cause creatures to die
|
||||
processAction(); // needed e.g if boost effects end and cause creatures to die
|
||||
somethingHappened = true;
|
||||
}
|
||||
checkConcede();
|
||||
|
|
@ -2273,10 +2278,8 @@ public abstract class GameImpl implements Game {
|
|||
/**
|
||||
* Sets the waiting triggered abilities (if there are any) to the stack in
|
||||
* the chosen order by player
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean checkTriggered() {
|
||||
boolean checkTriggered() {
|
||||
boolean played = false;
|
||||
state.getTriggers().checkStateTriggers(this);
|
||||
for (UUID playerId : state.getPlayerList(state.getActivePlayerId())) {
|
||||
|
|
@ -2314,15 +2317,13 @@ public abstract class GameImpl implements Game {
|
|||
}
|
||||
|
||||
/**
|
||||
* 116.5. Each time a player would get priority, the game first performs all
|
||||
* 117.5. Each time a player would get priority, the game first performs all
|
||||
* applicable state-based actions as a single event (see rule 704,
|
||||
* “State-Based Actions”), then repeats this process until no state-based
|
||||
* actions are performed. Then triggered abilities are put on the stack (see
|
||||
* rule 603, “Handling Triggered Abilities”). These steps repeat in order
|
||||
* until no further state-based actions are performed and no abilities
|
||||
* trigger. Then the player who would have received priority does so.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected boolean checkStateBasedActions() {
|
||||
boolean somethingHappened = false;
|
||||
|
|
|
|||
|
|
@ -666,22 +666,6 @@ public class GameState implements Serializable, Copyable<GameState> {
|
|||
this.gameOver = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Must be called between effects/steps in the ability's resolve
|
||||
* <p>
|
||||
* 608.2e
|
||||
* Some spells and abilities have multiple steps or actions, denoted by separate sentences or clauses,
|
||||
* that involve multiple players. In these cases, the choices for the first action are made in APNAP order,
|
||||
* and then the first action is processed simultaneously. Then the choices for the second action are made in
|
||||
* APNAP order, and then that action is processed simultaneously, and so on. See rule 101.4.
|
||||
*/
|
||||
public void processAction(Game game) {
|
||||
game.getState().handleSimultaneousEvent(game);
|
||||
game.resetShortLivingLKI();
|
||||
game.applyEffects();
|
||||
game.getState().getTriggers().checkStateTriggers(game);
|
||||
}
|
||||
|
||||
void applyEffects(Game game) {
|
||||
applyEffectsCounter++;
|
||||
for (Player player : players.values()) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue