mirror of
https://github.com/magefree/mage.git
synced 2025-12-25 13:02:06 -08:00
Clash adjustments (#10616)
* adjust clash effect * Make clash not a singleton * Add unit test for Clash effect * fix test (skip init shuffling) * Fix CLASHED event flag logic and add to unit test * Additional test and comments * comments in GameEvent * param name typo
This commit is contained in:
parent
0d4c73b385
commit
ee29c38413
15 changed files with 187 additions and 67 deletions
|
|
@ -2,8 +2,6 @@ package mage.abilities.effects.common;
|
|||
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.MageSingleton;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.Cards;
|
||||
|
|
@ -13,11 +11,10 @@ import mage.constants.Zone;
|
|||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.players.Player;
|
||||
import mage.players.PlayerList;
|
||||
import mage.target.Target;
|
||||
import mage.target.common.TargetOpponent;
|
||||
|
||||
import java.io.ObjectStreamException;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* 1. The controller of the spell or ability chooses an opponent. (This doesn't
|
||||
|
|
@ -54,24 +51,14 @@ import java.io.ObjectStreamException;
|
|||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public class ClashEffect extends OneShotEffect implements MageSingleton {
|
||||
public class ClashEffect extends OneShotEffect {
|
||||
|
||||
private static final ClashEffect instance = new ClashEffect();
|
||||
|
||||
private Object readResolve() throws ObjectStreamException {
|
||||
return instance;
|
||||
}
|
||||
|
||||
private ClashEffect() {
|
||||
public ClashEffect() {
|
||||
super(Outcome.Benefit);
|
||||
this.staticText = "Clash with an opponent";
|
||||
}
|
||||
|
||||
public static ClashEffect getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public ClashEffect(final ClashEffect effect) {
|
||||
protected ClashEffect(final ClashEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
|
|
@ -94,7 +81,6 @@ public class ClashEffect extends OneShotEffect implements MageSingleton {
|
|||
// choose opponent
|
||||
Target target = new TargetOpponent(true);
|
||||
target.setTargetName("an opponent to clash with");
|
||||
target.setNotTarget(true);
|
||||
if (!controller.choose(Outcome.Benefit, target, source, game)) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -133,32 +119,26 @@ public class ClashEffect extends OneShotEffect implements MageSingleton {
|
|||
message.append(" no card");
|
||||
}
|
||||
message.append(" - ");
|
||||
if (!game.isSimulation()) {
|
||||
if (cmcController > cmcOpponent) {
|
||||
message.append(controller.getLogName()).append(" won the clash");
|
||||
game.informPlayer(controller, "You won the clash!");
|
||||
} else if (cmcController < cmcOpponent) {
|
||||
message.append(opponent.getLogName()).append(" won the clash");
|
||||
game.informPlayer(controller, opponent.getName() + " won the clash!");
|
||||
} else {
|
||||
message.append(" no winner ");
|
||||
}
|
||||
game.informPlayers(message.toString());
|
||||
if (cmcController > cmcOpponent) {
|
||||
message.append(controller.getLogName()).append(" won the clash");
|
||||
} else if (cmcController < cmcOpponent) {
|
||||
message.append(opponent.getLogName()).append(" won the clash");
|
||||
} else {
|
||||
message.append(" no winner ");
|
||||
}
|
||||
// decide to put the cards on top or on the buttom of library in turn order beginning with the active player in turn order
|
||||
PlayerList playerList = game.getPlayerList().copy();
|
||||
playerList.setCurrent(game.getActivePlayerId());
|
||||
Player nextPlayer;
|
||||
do {
|
||||
Player current = playerList.getCurrent(game);
|
||||
if (cardController != null && current.getId().equals(controller.getId())) {
|
||||
topController = current.chooseUse(Outcome.Detriment, "Put " + cardController.getLogName() + " back on top of your library? (otherwise it goes to bottom)", source, game);
|
||||
game.informPlayers(message.toString());
|
||||
// decide to put the cards on top or on the bottom of library in turn order beginning with the active player in turn order
|
||||
for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) {
|
||||
Player player = game.getPlayer(playerId);
|
||||
if (player == null) {
|
||||
continue;
|
||||
}
|
||||
if (cardOpponent != null && current.getId().equals(opponent.getId())) {
|
||||
topOpponent = current.chooseUse(Outcome.Detriment, "Put " + cardOpponent.getLogName() + " back on top of your library? (otherwise it goes to bottom)", source, game);
|
||||
if (cardController != null && player.getId().equals(controller.getId())) {
|
||||
topController = player.chooseUse(Outcome.Detriment, "Put " + cardController.getLogName() + " back on top of your library? (otherwise it goes to bottom)", source, game);
|
||||
} else if (cardOpponent != null && player.getId().equals(opponent.getId())) {
|
||||
topOpponent = player.chooseUse(Outcome.Detriment, "Put " + cardOpponent.getLogName() + " back on top of your library? (otherwise it goes to bottom)", source, game);
|
||||
}
|
||||
nextPlayer = playerList.getNext(game, false);
|
||||
} while (nextPlayer != null && !nextPlayer.getId().equals(game.getActivePlayerId()));
|
||||
}
|
||||
// put the cards back to library
|
||||
if (cardController != null) {
|
||||
controller.moveCardToLibraryWithInfo(cardController, source, game, Zone.LIBRARY, topController, true);
|
||||
|
|
@ -166,14 +146,14 @@ public class ClashEffect extends OneShotEffect implements MageSingleton {
|
|||
if (cardOpponent != null) {
|
||||
opponent.moveCardToLibraryWithInfo(cardOpponent, source, game, Zone.LIBRARY, topOpponent, true);
|
||||
}
|
||||
// fire CLASHED event with info about who won
|
||||
game.fireEvent(new GameEvent(
|
||||
GameEvent.EventType.CLASHED, controller.getId(), source,
|
||||
opponent.getId(), 0, cmcController > cmcOpponent
|
||||
));
|
||||
// fire CLASHED events with info about winner (flag is true if playerId won; other player is targetId)
|
||||
game.fireEvent(new GameEvent(
|
||||
GameEvent.EventType.CLASHED, opponent.getId(), source,
|
||||
controller.getId(), 0, cmcOpponent > cmcController
|
||||
controller.getId(), 0, cmcController > cmcOpponent
|
||||
));
|
||||
game.fireEvent(new GameEvent(
|
||||
GameEvent.EventType.CLASHED, controller.getId(), source,
|
||||
opponent.getId(), 0, cmcOpponent > cmcController
|
||||
));
|
||||
|
||||
// set opponent to DoIfClashWonEffect
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ public class DoIfClashWonEffect extends OneShotEffect {
|
|||
}
|
||||
|
||||
if (chooseUseText == null || player.chooseUse(executingEffect.getOutcome(), message, source, game)) {
|
||||
if (ClashEffect.getInstance().apply(game, source)) {
|
||||
if (new ClashEffect().apply(game, source)) {
|
||||
if (setTargetPointerToClashedOpponent) {
|
||||
Object opponent = getValue("clashOpponent");
|
||||
if (opponent instanceof Player) {
|
||||
|
|
|
|||
|
|
@ -99,6 +99,11 @@ public class GameEvent implements Serializable {
|
|||
DISCARDED_CARD,
|
||||
DISCARDED_CARDS,
|
||||
CYCLE_CARD, CYCLED_CARD, CYCLE_DRAW,
|
||||
/* CLASHED (one event fired for each player involved)
|
||||
playerId the id of the clashing player
|
||||
flag true = playerId won the clash
|
||||
targetId the id of the other player in the clash
|
||||
*/
|
||||
CLASH, CLASHED,
|
||||
DAMAGE_PLAYER,
|
||||
MILL_CARDS,
|
||||
|
|
@ -107,9 +112,9 @@ public class GameEvent implements Serializable {
|
|||
/* DAMAGED_PLAYER
|
||||
targetId the id of the damaged player
|
||||
sourceId sourceId of the ability which caused the damage
|
||||
playerId the id of the damged player
|
||||
playerId the id of the damaged player
|
||||
amount amount of damage
|
||||
flag true = comabat damage - other damage = false
|
||||
flag true = combat damage - other damage = false
|
||||
*/
|
||||
DAMAGED_PLAYER,
|
||||
|
||||
|
|
@ -121,7 +126,7 @@ public class GameEvent implements Serializable {
|
|||
/* DAMAGE_CAUSES_LIFE_LOSS,
|
||||
targetId the id of the damaged player
|
||||
sourceId sourceId of the ability which caused the damage, can be null for default events like combat
|
||||
playerId the id of the damged player
|
||||
playerId the id of the damaged player
|
||||
amount amount of damage
|
||||
flag is it combat damage
|
||||
*/
|
||||
|
|
@ -134,7 +139,7 @@ public class GameEvent implements Serializable {
|
|||
sourceId sourceId of the ability which caused the lose
|
||||
playerId the id of the player loosing life
|
||||
amount amount of life loss
|
||||
flag true = from comabat damage - other from non combat damage
|
||||
flag true = from combat damage - other from non combat damage
|
||||
*/
|
||||
PLAY_LAND, LAND_PLAYED,
|
||||
CREATURE_CHAMPIONED,
|
||||
|
|
@ -333,7 +338,7 @@ public class GameEvent implements Serializable {
|
|||
TAP,
|
||||
/* TAPPED,
|
||||
targetId tapped permanent
|
||||
sourceId id of the abilitity's source (can be null for standard tap actions like combat)
|
||||
sourceId id of the ability's source (can be null for standard tap actions like combat)
|
||||
playerId controller of the tapped permanent
|
||||
amount not used for this event
|
||||
flag is it tapped for combat
|
||||
|
|
@ -441,7 +446,7 @@ public class GameEvent implements Serializable {
|
|||
/* LOST_CONTROL
|
||||
targetId id of the creature that lost control
|
||||
sourceId null
|
||||
playerId player that controlles the creature before
|
||||
playerId player that controls the creature before
|
||||
amount not used for this event
|
||||
flag not used for this event
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -567,11 +567,11 @@ public interface Player extends MageItem, Copyable<Player> {
|
|||
|
||||
void revealCards(Ability source, Cards cards, Game game);
|
||||
|
||||
void revealCards(String titelSuffix, Cards cards, Game game);
|
||||
void revealCards(String titleSuffix, Cards cards, Game game);
|
||||
|
||||
void revealCards(Ability source, String titelSuffix, Cards cards, Game game);
|
||||
void revealCards(Ability source, String titleSuffix, Cards cards, Game game);
|
||||
|
||||
void revealCards(String titelSuffix, Cards cards, Game game, boolean postToLog);
|
||||
void revealCards(String titleSuffix, Cards cards, Game game, boolean postToLog);
|
||||
|
||||
/**
|
||||
* Adds the cards to the reveal window and adds the source object's id name
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue